Skip to content

String的存储结构

659字约2分钟

java

2024-10-24

String的存储结构

private final char[] value;
private int hash;

image-20210925170932940

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;
}

image-20210925171129543

image-20210925171205933

实现了Appendable接口

image-20210925171318785

image-20210925171335804

保存的char数组可变

1.数组的初始状态

value数组默认长度为16,可以根据参数进行初始化

public StringBuffer() {
        super(16);
}

public StringBuffer(int capacity) {
        super(capacity);
}

image-20210925171632836

2.扩容

原来的数组长度的两倍+2(默认)

image-20210925172049695

3.内容会被缓存

每次操作内容会缓存

image-20210925172414139

4.equals方法

StringBuffer、StringBuilder没有重写equals方法

比较内容使用toString转换

String与StringBuffer使用时机

一次写入多次读取使用String,最好使用final修饰(安全、效率高)

优先考虑使用StringBuilder代替StringBuffer,除在线程安全

StringBuilder使用场景:

循环中的字符串的改变必须使用StringBuilder

Tip:

获取子字符串出现的次数使用split(子字符串)切割,获取字符数组的长度。出现次数为数组长度-1。