外观
String的存储结构
String的存储结构
private final char[] value;
private int hash;
String s3 = "Hello";
String s4 = s3 + " World";
// 实质是先转为一个StringBuilder对象在进行append(" World")操作
String s1 = "Hello Wold";
String s2 = "Hello" + " World";
System.out.println(s1 == s2);// true
// 实质是他们都指向了常量池中的"Hello World"常量
常量存在于常量池当中
池结构
缓存,以某种对象建立的数据结构
缓存
一定是需要重复利用的对象
这些对象不是复用频率就是创建或销毁时开销很大,这些对象都可以利用缓存技术进行池化
1.使用哪些数据结构
2.缓存替换算法
先进先出(FIFO)、后进先出(FILO)、最近最少未使用(LRU)
缓存后的对象一经创建,就不轻易销毁,使用完毕只是将它归还到缓存池
3.缓存对象的生命周期
由缓存管理软件控制
String的intern方法
返回常量池中的字符串常量(String对象的常量缓存)
缓存技术、内存结构
元空间(常量池)
StringBuffer类
线程安全:会不会引起读写冲突
StringBuffer是线程安全的,方法有synchronized修饰,多个线程并发读写不会引起冲突(在JDK1.0就有)
StringBulider是线程不安全的,方法没有synchronized修饰,多个线程并发读写会引起冲突(JDK1.5中才有)
因为效率和性能问题,StringBulider取消了线程同步机制,它有其他的线程安全解决方案
StringBuffer
private char[] value;
private int count;
public int capacity(){
return value.length;
}
实现了Appendable接口
保存的char数组可变
1.数组的初始状态
value数组默认长度为16,可以根据参数进行初始化
public StringBuffer() {
super(16);
}
public StringBuffer(int capacity) {
super(capacity);
}
2.扩容
原来的数组长度的两倍+2(默认)
3.内容会被缓存
每次操作内容会缓存
4.equals方法
StringBuffer、StringBuilder没有重写equals方法
比较内容使用toString转换
String与StringBuffer使用时机
一次写入多次读取使用String,最好使用final修饰(安全、效率高)
优先考虑使用StringBuilder代替StringBuffer,除在线程安全
StringBuilder使用场景:
循环中的字符串的改变必须使用StringBuilder
Tip:
获取子字符串出现的次数使用split(子字符串)切割,获取字符数组的长度。出现次数为数组长度-1。