文章目录
1 简述
Java字符串用""
引起来表示,主要有三个类String
、StringBuffer
、StringBuilder
.
2 String类
String
类声明为final
,不可被继承。
-
jdk8及以前内部以
final char[] value
存储字符串数据,jdk9之后改为byte[]
. -
字符串数据保存在字符串常量池中,且字符串常量池不会存储重复内容的字符串。
-
创建String对象有两种方式:
String s1 = "abc"; // 字面量定义
String s2 = new String("abc"); // 构造方法定义
2.1 字符串拼接(+)
有两种类型的字符串拼接:
- 常量与常量的拼接,结果直接在常量池中(编译期优化)
String s1 = "Hello" + " man";
final String s2 = "woman";
String s3 = "Hello" + s2;
- 带变量(不包括final变量)的拼接,结果在堆中。
String s2 = "man";
String s3 = "Hello " + s2;
查看字节码:
可见带变量的字符串拼接是通过StringBuilder
对象的append
方法实现的,最后toString
返回String
对象。
注意: toString()
的调用不会再字符串常量池中生成响应的对象。
通过上面分析,对于需要频繁字符串拼接的代码,考虑主动创建StringBuilder
对象进行操作:
StringBuilder sb = new StringBuilder(capacity);
2.2 字符串常量池中的数据
- 字面量定义的字符串会直接存到常量池中
String s1 = new String("hi");
上面代码会创建2个对象:一个是字符串常量池中创建"hi"对象,另一个是堆中new
的String
对象。
- String对象执行
intern()
方法——主动将字符串存入常量池
如果常量池中已经有了该字符串,方法直接返回池中该对象的地址;
否则,jdk6中会将该对象复制一份到常量池中,并返回池中的引用地址,jdk7及之后会将该对象的引用地址(堆上)复制到常量池中,返回的也是堆上的地址。
2.3 String常用方法
- 增:
+
, - 改:
toLowerCase()
、trim()
、replace(char old, char new)
、 - 查:
length()
、charAt(int index)
、equals(Object obj)
、substring(int fromIdx, int toIdx)
、indexOf(String sub, int fromIdx)
注意:String
数据是final修饰的,所以上面的修改都是返回新的String对象,原对象不改变。
-
正则相关方法
String replaceAll(String regex, String replacement)
boolean matches(String regex)
String[] split(String regex)
-
类型转换方法
String.parseInt(String s)
:字符串 --> 数字String.valueOf(int n)
: 数字 --> 字符串char[] toCharArray()
:字符串 --> char[]数组byte[] getBytes()
:字符串 --> byte[]数组
编码:将数据转换为byte类型,byte存储的是[-128, 127]的整数。
解码:将byte数据转化成需要的可展示的格式。
3 StringBuffer、StringBuilder
类的定义:
其父类AbstractStringBuilder
也是StringBuilder
的父类,两者的底层结构都继承自父类:
可见与String
类不用,value数组没有final修饰,是可变的,且通过count计数,实现添加字符串时数组的自动扩容。
StringBuffer
和StringBuilder
的区别主要是StringBuffer
的方法都被synchronized
修饰,也就是说:
StringBuffer是线程安全的,StringBuilder是线程不安全的。
-
常用方法
StringBuffer append(xxx)
: 用于字符串拼接StringBuffer delete(int from, int to)
: 删除指定位置内容StringBuffer replace(int start, int end, String str)
StringBuffer insert(int offset, xxx)
方法返回类型都是StringBuffer
,实际上是方法执行后都返回对象本身(return this),所以这些方法可以链式调用:
sb.append("a").append("b");
除了上面的方法,大部分String
的方法在StringBuffer
中也有实现。
4 String、StringBuffer、StringBuild的区别
String
:不可变的字符序列,底层用final char[]
存储,效率最低。StringBuffer
: 可变的字符序列,线程安全,效率低。StringBuilder
: 可变的字符序列,线程不安全,效率高。