【Java基础】String & StringBuffer & StringBuilder

String

String 对象是不可变的。String 类中每一个看起来会修改 String 值的方法,实际上都是创建了一个全新的 String 对象,以包含修改后的字符串内容。而最初的 String 对象则丝毫未动。

String 真正不可变原因:

  • 保存字符串的数组被 final 修饰且为私有的,并且String 类没有提供/暴露修改这个字符串的方法。
  • String 类被 final 修饰导致其不能被继承,进而避免了子类破坏 String 不可变。
// strings/Immutable.java
public class Immutable { 
    public static String upcase(String s) { 
        return s.toUpperCase(); 
    } 
    public static void main(String[] args) { 
        String q = "howdy";
        System.out.println(q); // howdy 
        String qq = upcase(q); 
        System.out.println(qq); // HOWDY 
        System.out.println(q); // howdy 
    } 
} 
/* Output: 
howdy
HOWDY 
howdy
*/ 

当把 q 传递给 upcase() 方法时,实际传递的是引用的一个拷贝。其实,每当把 String 对象作为方法的参数时,都会复制一份引用,而该引用所指向的对象其实一直待在单一的物理位置上,从未动过。

回到 upcase() 的定义,传入其中的引用有了名字 s,只有 upcase() 运行的时候,局部引用 s 才存在。一旦 upcase() 运行结束,s 就消失了。当然了,upcase() 的返回值,其实是最终结果的引用。这足以说明,upcase() 返回的引用已经指向了一个新的对象,而 q 仍然在原来的位置。

StringBuilder与StringBuffer

StringBuilderStringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,不过没有使用 finalprivate 关键字修饰, AbstractStringBuilder 类还提供了很多修改字符串的方法比如 append 方法。

StringBuilder 提供了丰富而全面的方法,包括 insert()replace()substring(),甚至还有reverse(),但是最常用的还是 append()toString()

StringBuilder 是 Java SE5 引入的,在这之前用的是 StringBuffer。后者是线程安全的(参见并发编程),因此开销也会大些。使用 StringBuilder 进行字符串操作更快一点。

+与StringBuilder

Java 语言本身并不支持运算符重载,“+”和“+=”是专门为 String 类重载过的运算符,也是 Java 中仅有的两个重载过的运算符。

// strings/Concatenation.java

public class Concatenation {
    public static void main(String[] args) { 
        String mango = "mango"; 
        String s = "abc" + mango + "def" + 47; 
        System.out.println(s);
    } 
}
/* Output:
abcmangodef47 
*/

在这里,编译器创建了一个 StringBuilder 对象,用于构建最终的 String,并对每个字符串调用了一次 append() 方法,最后调用 toString() 生成结果。

在循环内使用“+”进行字符串的拼接的话,存在比较明显的缺陷:编译器不会创建单个 StringBuilder 以复用,会导致创建过多的 StringBuilder 对象

对于三者使用的总结:

  1. 操作少量的数据: 适用 String
  2. 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
  3. 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer

字符串操作

以下是 String 对象具备的一些基本方法。重载的方法归纳在同一行中:

方法参数,重载版本作用
构造方法默认版本,StringStringBuilderStringBufferchar数组,byte数组创建String对象
length()String中字符的个数
charAt()int索引获取String中索引位置上的char
getChars()getBytes()待复制部分的开始和结束索引,复制的目标数组,目标数组的开始索引复制charbyte到一个目标数组中
toCharArray()生成一个char[],包含String中的所有字符
equals()equalsIgnoreCase()与之进行比较的String比较两个String的内容是否相同。如果相同,结果为true
compareTo()compareToIgnoreCase()与之进行比较的String按词典顺序比较String的内容,比较结果为负数、零或正数。注意,大小写不等价
contains()要搜索的CharSequence如果该String对象包含参数的内容,则返回true
contentEquals()与之进行比较的CharSequenceStringBuffer如果该String对象与参数的内容完全一致,则返回true
isEmpty()返回boolean结果,以表明String对象的长度是否为0
regionMatches()String的索引偏移量,另一个String及其索引偏移量,要比较的长度。重载版本增加了“忽略大小写”功能返回boolean结果,以表明所比较区域是否相等
startsWith()可能的起始String。重载版本在参数中增加了偏移量返回boolean结果,以表明该String是否以传入参数开始
endsWith()String可能的后缀String返回boolean结果,以表明此参数是否是该字符串的后缀
indexOf()lastIndexOf()重载版本包括:charchar与起始索引,StringString与起始索引如果该String并不包含此参数,就返回-1;否则返回此参数在String中的起始索引。lastIndexOf()是从后往前搜索
matches()一个正则表达式返回boolean结果,以表明该String和给出的正则表达式是否匹配
split()一个正则表达式。可选参数为需要拆分的最大数量按照正则表达式拆分String,返回一个结果数组
join()(Java8引入的)分隔符,待拼字符序列。用分隔符将字符序列拼接成一个新的String用分隔符拼接字符片段,产生一个新的String
substring()(即subSequence()重载版本:起始索引;起始索引+终止索引返回一个新的String对象,以包含参数指定的子串
concat()要连接的String返回一个新的String对象,内容为原始String连接上参数String
replace()要替换的字符,用来进行替换的新字符。也可以用一个CharSequence替换另一个CharSequence返回替换字符后的新String对象。如果没有替换发生,则返回原始的String对象
replaceFirst()要替换的正则表达式,用来进行替换的String返回替换首个目标字符串后的String对象
replaceAll()要替换的正则表达式,用来进行替换的String返回替换所有目标字符串后的String对象
toLowerCase()toUpperCase()将字符的大小写改变后,返回一个新的String对象。如果没有任何改变,则返回原始的String对象
trim()String两端的空白符删除后,返回一个新的String对象。如果没有任何改变,则返回原始的String对象
valueOf()static重载版本:Objectchar[]char[],偏移量,与字符个数;booleancharintlongfloatdouble返回一个表示参数内容的String
intern()为每个唯一的字符序列生成一个且仅生成一个String引用
format()要格式化的字符串,要替换到格式化字符串的参数返回格式化结果String

参考资料

深入探究可参考如下内容

onJava8

JavaGuide string

深入解析string

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值