String类,String、StringBuffer、StringBuilder、StringTokenizer
String类
String
字符串:一串连续的字符,也是一串连续的char,Java中将char数组进行封装来表达字符串。
String是不可变性,即对象本身的属性或对象本身的数据不变,重新赋值是变量(存放在堆中)指向堆中新创建的对象;可变的:可以修改对象的属性
查看String源码可以观察到,final修饰的char数组且为私有成员变量(private);
final修饰表示其不能指向新的数组、表示其不能有子类不可被继承从而杜绝了子类覆盖父类行为的可能,不能代表数组本身的数据不会被改变;
String真正不可变的原因是其被final修饰的同时还被private修饰,且String没有暴露和提供任何修改数组的方法。
不可变的优点:
①不可变时字符串常量池(也存放在堆中)才能发挥作用。用自变量创建字符串时,字符串常量池会返回已有对象的引用;若字符串可变引用的值就能随时修改并随时影响其他对象的引用,从而使数据发生各种错误,不能进行常量池的复用。
②其哈希码也不会变,计算哈希码后可缓存不需要再计算,性能更高。
③不可变对象线程是安全的,不用担心当前线程使用的对象会被其他线程修改。
例:用户名和密码通常定义为String类型,接收数据时走到改变数据的方法会被篡改,需要安全性
其他不可变对象:BigDecimal(java.math包中,用来对超过16位有效位的数进行精确的运算)。
StringBuffer
不可变弊端:频繁操作字符串时,会产生许多新对象,从而导致性能低下。——>引出StringBuffer
abstract class AbstractStringBuilder{
char[] value;
}
查看StringBuffer源码,StringBuffer继承的AbstractStringBuilder没有final、private修饰,且StringBuffer有许多方法(例如append()在原字符后面添加字符)供我们修改字符串本身,以方便链式调用。
StringBuilder
StringBuffer可变所以其线程不安全,——>引出StringBuilder
StringBuilder也继承AbstractStringBuilder,每次操作字符串时都会加锁,导致性能低下。
总结
类型 | 特点 | 适用场景 |
---|---|---|
String | 不可变,线程安全 | 少量或不操作数据 |
StringBuffer | 可变,线程不安全 | 大量操作数据且无需考虑线程安全性 |
StringBuilder | 可变,线程安全性能较低 | 大量操作数据且需要考虑线程安全性 |
Test
class StringClass{
public static void testString(){
String s="hello";
String s1="world";
long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
s+=s1;
}
long end=System.currentTimeMillis();
long runTime=(end-start);
System.out.println("String加长所需时间为"+runTime);
}
public static void testStringBuffer(){
StringBuffer s=new StringBuffer("Hello");
String s1="world";
long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
s.append(s1);
}
long end=System.currentTimeMillis();
long runTime=(end-start);
System.out.println("StringBuffer 加长所需时间为"+runTime);
}
public static void testStringBuilder(){
StringBuilder s=new StringBuilder("hello");
String s1="world";
long start=System.currentTimeMillis();
for(int i=0;i<10000;i++){
s.append(s1);
}
long end=System.currentTimeMillis();
long runTime=(end-start);
System.out.println("StringBuilder加长所需时间为"+runTime);
}
public static void main(String[] args){
testString();
testStringBuffer();
testStringBuilder();
}
}
StringTokenizer
StringTokenizer是用来分割字符串的工具
class StringClass{
public static void main(String args[]){
StringTokenizer st=new StringTokenizer("my name is lzm");
while(st.hasMoreTokens()){
System.out.println(st.nextToken());
}
}
}