StringBuilder / StringBuffer
–1,概述
专门优化字符串拼接
–2,创建对象
StringBuilder()
构造一个不带任何字符的字符串生成器,其初始容量为 16 个字符。
–3,常用方法
StringBuilder append(String str)
将指定的字符串追加到此字符序列。
–4,测试
package cn.tedu.api;
//测试 字符串拼接
//1,工具类的使用场景:当有大量的字符串拼接需求时
//2,使用步骤: 先创建对象 ,然后调用append()追加
//3,性能: 工具类拼接 > +号拼接
//4,为什么+拼接字符串慢?–因为字符串是一个常量,一旦创建不能改变
public class Test4_StringBuilder {
public static void main(String[] args) {
// method();//+拼接
method2();//StringBuilder拼接
}
public static void method2() {
//把指定的字符串拼接10000次
String s = “abcdefghijklmnopqrstuvwxyz” ;
// StringBuilder sb = new StringBuilder();
StringBuffer sb = new StringBuffer();
long start = System.currentTimeMillis();//计时开始
for (int i = 0; i < 10000; i++) {
sb.append(s) ;//工具拼接
}
long end = System.currentTimeMillis();//计时结束
System.out.println(end-start);//1ms
}
//+拼接
public static void method() {
//把指定的字符串拼接10000次
String s = "abcdefghijklmnopqrstuvwxyz" ;
String res = "" ;//定义变量,记录结果
long start = System.currentTimeMillis();//计时开始
for (int i = 0; i < 10000; i++) {
res = res + s ;//+拼接慢
}
long end = System.currentTimeMillis();//计时结束
System.out.println(end-start);//1372ms
}
}
区别1:线程安全
StringBuffer:线程安全,StringBuilder:线程不安全。因为 StringBuffer 的所有公开方法都是 synchronized 修饰的,而 StringBuilder 并没有 StringBuilder 修饰。
StringBuffer 代码片段:
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
区别2:缓冲区
StringBuffer 代码片段:
private transient char[] toStringCache;
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
StringBuilder 代码片段:
@Override
public String toString() {
// Create a copy, don’t share the array
return new String(value, 0, count);
}
可以看出,StringBuffer 每次获取 toString 都会直接使用缓存区的 toStringCache 值来构造一个字符串。
而 StringBuilder 则每次都需要复制一次字符数组,再构造一个字符串。
所以,缓存冲这也是对 StringBuffer 的一个优化吧,不过 StringBuffer 的这个toString 方法仍然是同步的。
区别3:性能
既然 StringBuffer 是线程安全的,它的所有公开方法都是同步的,StringBuilder 是没有对方法加锁同步的,所以毫无疑问,StringBuilder 的性能要远大于 StringBuffer。
总结
所以,StringBuffer 适用于用在多线程操作同一个 StringBuffer 的场景,如果是单线程场合 StringBuilder 更适合。
三,String
–1,概述
String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。
–2,特点
–源码摘抄:
–public final class String --不能被继承
–private final char value[];–字符串是常量
–3,创建对象
String(char[] value)
–4,常用方法
char charAt(int index)
返回指定索引处的 char 值。
String concat(String str)
将指定字符串连接到此字符串的结尾。
boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束。
boolean equals(Object anObject)
将此字符串与指定的对象比较。
byte[] getBytes()
int hashCode()
返回此字符串的哈希码。
int indexOf(String str)
返回指定子字符串在此字符串中第一次出现处的索引
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引。
boolean isEmpty()
当且仅当 length() 为 0 时返回 true。
int length()
返回此字符串的长度。
String replace(char oldChar, char newChar)
返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串。
boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始。
String substring(int beginIndex)
返回一个新的字符串,它是此字符串的一个子字符串。
String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的一个子字符串。
char[] toCharArray()
将此字符串转换为一个新的字符数组。
String toLowerCase()
String toUpperCase()
String trim()
返回字符串的副本,忽略前导空白和尾部空白。
static String valueOf(int i)
返回 int 参数的字符串表示形式。
–5,测试
package cn.tedu.api;
import java.util.Arrays;
//测试 String工具类
public class Test3_String {
public static void main(String[] args) {
//1,创建String对象
char[] cs = {'a','b','c','a'};
String str = new String(cs);//触发String(char[] value)
String str2 = "abcdefabc" ;//相当于简写形式
//2,调用方法
System.out.println( str.charAt(2) );//根据下标2,获取对应的字符
System.out.println( str.concat("xyz") );//拼接字符串
System.out.println( str.endsWith("abc"));//判断是否以指定数据结尾
System.out.println( str.equals("abca"));//判断两个字符串的内容是否相同
System.out.println("--------------");
System.out.println( str.hashCode() );//计算哈希码值
System.out.println( str.indexOf("a") );//获取第一次出现的索引值
System.out.println( str.lastIndexOf("a") );//获取最后一次出现的索引值
System.out.println( str.isEmpty() );//判断字符串是否为空
System.out.println( str.length() );//获取字符串的长度
System.out.println("--------------");
System.out.println( str.replace('a','x') );//把旧字符换成新字符
System.out.println( str.startsWith("ab") );//判断是否以指定内容开始
//截取字符串,从指定位置开始到末尾处
System.out.println( str.substring(2) );
//截取字符串,从1开始,到3结束,含头不含尾[1,3)
System.out.println( str.substring(1,3) );
System.out.println( str.toLowerCase() );//全转小写
System.out.println( str.toUpperCase() );//全转大写
str = " abc 1 23 " ;
System.out.println( str.trim() );//去除前导和后导多余的空格
System.out.println("--------------");
String s = String.valueOf(10);//把指定的数字10转成字符串
System.out.println(s+1);//101,字符串拼接
char[] css = str.toCharArray();//把字符串的数据存入char[]
System.out.println(css);
byte[] bs = str.getBytes() ;//把字符串的数据,转成整数并存入byte[]
System.out.println( Arrays.toString(bs) );
// String[] split(String regex)
str = "a1b1c1d1" ;
String[] ss = str.split("1") ;//按照指定的字符串切割字符串
System.out.println( Arrays.toString(ss) );//[a, b, c, d]
//TODO 打印字符串里的每个字符-----------------
char[] a = str.toCharArray() ;
for (int i = 0; i < a.length; i++) {//遍历char[]数组
System.out.println(a[i]);//根据下标获取数据
}
for(int i = 0; i < str.length() ;i++) {//遍历字符串
char c = str.charAt(i);//根据下标获取字符
System.out.println(c);
}
}
}