字符串&集合面试题汇总

一、Java 中操作字符串都有哪些类?它们之间有什么区别?

操作字符串的类有:String、StringBuffer、StringBuilder 。
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象。

而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用String

StringBufferStringBuilder 最大的区别在于StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但StringBuilder 的性能却高于 StringBuffer,

所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。

二、String、StringBuffer和StringBuilder区别(类似上一题)

  1. 数据可变和不可变
  • String 底层使用一个不可变的字符数组private final char value[]; 所以它内容不可变。
  • StringBuffer 和 StringBuilder 都继承了AbstractStringBuilder 底层使用的是可变字符数
  1. 线程安全
  • StringBuilder 是线程不安全的,效率较高;而StringBuffer 是线程安全的,效率较低。通过他们的append() 方法来看,StringBuffer 是有同步锁,而StringBuilder 没有:
点击查看代码
@Override
public synchronized StringBuffer append(Object obj){
	toStringCache = null;
	super.append(String.valueOf(obj));
	return this;
}
@Override
public StringBuilder append(String str){
	super.append(str);
	return this;
}
  1. 相同点
    StringBuilder 与 StringBuffer 有公共父类AbstractStringBuilder 。

最后,操作可变字符串速度: StringBuilder > StringBuffer > String,这个答案就显得不足为奇了。

四、String str="i"与 String str=new String("i")一样吗?

不一样,因为内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而String str=new String("i") 则会被分到堆内存中。
代码示例:

点击查看代码
String x = "叶痕秋"; 
String y = "叶痕秋";
String z = new String(" 叶 痕 秋 ");
System.out.println(x == y); // true
System.out.println(x == z); // false
String x = "叶痕秋" 的方式,Java 虚拟机会将其分配到常量池中,而常量池中没有重复的元素,比如当执行“叶痕秋”时,java虚拟机会先在常量池中检索是否已经有“叶痕秋”,如果有那么就将“叶痕秋”的地址赋给变量,如果没有就创建一个,然后在赋给变量;

而 String z = new String(“叶痕秋”) 则会被分到堆内存中,即使内容一样还是会创建新的对象。

五、String 类的常用方法都有那些?

  • indexOf(): 返 回 指 定 字 符 的 索 引 。
  • charAt():返 回 指 定 索 引 处 的 字 符 。
  • replace(): 字 符 串 替 换 。
  • trim(): 去 除 字 符 串 两 端 空 白 。
  • split():分割字符串,返回一个分割后的字符串数组。getBytes():返回字符串的
  • byte 类型数组。
  • length(): 返 回 字 符 串 长 度 。
  • toLowerCase():将字符串转成小写字母。
  • toUpperCase():将字符串转成大写字符。
  • substring():截取字符串。
  • equals():字符串比较。

六、String s = new String("xyz");创建了几个StringObject?是否可以继承String类?

两个或一个都有可能,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。NewString每写一遍,就创建一个新的对象,它使用常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,那么这里就不会创建”xyz”了,直接从缓冲区拿,这时创建了一个StringObject;但如果以前没有用过"xyz",那么此时就会创建一个对象并放入缓冲区,这种情况它创建两个对象。至于String类是否继承,答案是否定的,因为String默认final修饰,是不可继承的。