目录
String 、StringBuilder、StringBuffer的区别
String类
String类型它是一个引用数据类型。String型并不是基本类型,是Java.lang包中的类。
在源码中String类是一个被final修饰的不可变类。
字符串存储形式
String 的底层是以char类型的数组的形式存储,String类内部就是一个char[] 数组。
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
String类相关功能
2.与String类相关功能有:静态方法,比如:
static String valueOf(char b) //返回char类型b的字符串表示形式
static String valueOf(int a) //返回int参数a的字符串表示形式
static String valueOf(double c) // 返回double 参数c的字符串表示形式
实例方法,如下:
String concat(String str) //将字符串str拼接到字符串的末尾
int indexOf(int ch) //返回字符ch在字符串中第一次出现处的索引
String subString(int beginIndex,int endIndex) //截取子串,从索引beginIndex到endIndex的子字符串
String replace(char oldChar,char newChar) //返回所有oldChar替换为newChar后所创建的新的字符串
字符串拼接操作
1. 字符串常量“拼接”字符串常量 -> 在编译期优化,直接优化成一个helloworld。
String str="hello"+"world";
System.out.println(str); // 结果为helloworld
2. 变量+字符串常量 (在某种情况下,String类的“+”,拼接操作会被JVM解释为StringBuilder类下的拼接操作)
String的值是不可变的,使用String效率低下,且浪费大量的内存。而StringBuilder则是可变类,速度更快。
- String类是不可变类,一旦一个String类对象被创建后,它包含的字符串序列是不可变的,直到其被销毁 。每次给String类进行赋值就相当于在生成一个新的String类对象,然后指针指向新的对象,效率低下且十分浪费空间。如下:再次给str进行赋值时,并不是在原来堆上生成的实例对象进行赋值,而是在堆上重新开辟空间,重新生成一个实例对象并且指向“456”这个字符串,并将str指向新生成的实例对象,原来的实例对象仍然存在。若原来的实例对象不再被引用,则进行垃圾回收。
- StringBuilder类:在对字符串对象经常改变的情况下,使用StringBuilder类和StringBuffer类较好。StringBuilder类和StringBuffer(线程安全)类对象可以被修改并且不生成新的对象。StringBuilder相较于StringBuffer有速度优势(效率高),通常情况下,在没有线程安全的要求下,建议使用StringBuilder类。
如上所说,在某种情况下,String类的“+”,即拼接操作会被JVM解释为StringBuilder类下的拼接操作。先new一个StringBuilder类对象(StringBuilder类对象是一个空的对象)。append()方法是将字符添加在末端。insert()方法则是将字符添加在指定位置。最后通过 toString()方法将其转化为String类。
字符串比较操作
比较相等:字符串比较使用equals,该方法比较的是两个字符串的值,str1.equals(str2);而str 1==str2比较的是两者的地址。
以下为String类中的equals()方法的源码。
比较大小:引用数据类型使用Comparable接口的comparaTor()方法进行比较。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {}
在源码中,String类已经实现了Comparable<String>接口,所以compareTo方法可以直接使用。
String 、StringBuilder、StringBuffer的区别
首先:基于单线程环境(不考虑线程安全的情况下),建议使用String类和StringBuilder类;基于多线程环境下,使用StringBuffer。
其次:若要实现的是字符串常量+字符串常量,则优先使用String类;若要实现的是变量+字符串常量,则优先使用StringBuilder类。如果变量+字符串常量这个操作的使用次数较少,则可以使用String类,但如果使用次数多,例如在循环中使用,则使用StringBulider类。
StringBuilder和StringBuffer之间最大的区别是:前者的方法不是线程安全的(不能同步访问)。StringBuffer中的方法大多采用了synchronized 关键字修饰,所以是线程安全的。
StringBuilder和StringBuffer的源码分析
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
}
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{}
两者都继承自AbstractStringBuilder类,只不过StringBuffer在方法重写的时候使用了synchronized关键字修饰。