字符串不可变&练习
- 字符串不可变
- 1. 字符串设置为不可变的原因
- 2. 如何修改字符串内容
- 3 StringBuilder类的具体使用
- 4. 面试题
字符串不可变
1. 字符串设置为不可变的原因
- 方便实现字符串常量池,若String对象可变,常量池中的内容就会随时变化,常量池的实现就会非常麻烦(“写时拷贝”)
- 不可变的对象永远线程安全,不用考虑线程安全问题,效率很高
- 不可变对象可以作为哈希表的key值,高效保存在哈希表中
所谓的字符串不可变指的是字符串对象的内容不能变,而不是字符串引用不能变。这里的不可变是指“hello”,“world”,“helloworld”,这些字符串的对象一旦声明后就无法修改其内容。
不可变的本质原因:
String类的外部无法访问内部的value[]数组,并没有提供对应的getter和setter方法,对外部而言,value无法使用。因此,字符串对象的内容一旦产生无法修改。
由于字符串对象时不可变的,所有字符串的修改方法(subString、replace、toUpperCase)本质上都是产生了新的字符串,不是在原字符串上进行的修改!
2. 如何修改字符串内容
a. 在运行时通过反射破坏对value数组的封装
b. 更换使用StringBuilder或者StringBuffer类
若需要频繁进行字符串的拼接,使用StringBuilder类的append方法。StringBuilder类可以修改对象的内容。
StringBuilder sb=new StringBuilder();
sb.append("hello");
sb.append("world");
sb.append("!!!");
System.out.println(sb);
StringBuffer使用方法和StringBuilder一样,所有的方法名称,具体使用一模一样。
StringBuffer是线程安全,效率较低,性能较差;
StringBuilder线程不安全,效率较高。
不考虑线程安全的情况下,优先使用StringBuilder类。
3 StringBuilder类的具体使用
StringBuilder类和String类是两个独立的类,StringBuilder就是为了解决字符串拼接问题产生的。由于String的对象无法修改内容,为了方便字符串的拼接操作,产生了StringBuilder类,StringBuilder类的对象是可以修改内容的。
StringBuilder和String类的相互转换
(1) 拼接操作 append()方法
String转为StringBuilder
StringBuilder sb=new StringBuilder("hello");
//修改都是在原对象中进行的修改,不会产生新对象
sb.append("123");
(2) 按照String方式返回 toString()
还原为String对象
String str=sb.toString();
(3) 字符串反转操作reverse()
sb.reverse();
(4) 删除指定范围内的数据delete(int start,int end)
sb.delete(5,10);//Java中的区间是左闭右开
(5) 删除指定位置的元素deleteCharAt()
sb.deleteCharAt(5);
(6) 插入操作insert()
insert(int start,各种数据类型);
sb.insert(4,10);
将新元素插入当前sb对象,插入后新数值的起始索引为start
4. 面试题
- 请解释String、StringBuilder、StringBuffer的区别
- String的对象内容无法修改,但是StringBuilder、StringBuffer的对象内容可以修改;
- StringBuffer采用synchroniaed方法处理,是线程安全的操作,性能较差; StringBuilder采用异步处理,是线程不安全,效率较高。
- String对象“+=”其实是编译器会默认优化为StringBuilder的append方法