StringBuilder、StringBuffer和StringJoiner
StringBuilder是可变对象,用来高效拼接字符串;
StringBuilder可以支持链式操作,实现链式操作的关键是返回实例本身;
StringBuffer是StringBuilder的线程安全版本,现在很少使用。它是Java早期的一个StringBuilder的线程安全版本,它通过同步来保证多个线程操作StringBuffer也是安全的,但是同步会带来执行速度的下降。StringBuilder和StringBuffer接口完全相同,现在完全没有必要使用StringBuffer。
关于字符的处理
Java编译器对String做了特殊处理,使得我们可以直接用+拼接字符串。
考察下面的循环代码:
String s = "";
for (int i = 0; i < 1000; i++) {
s = s + "," + i;
}
虽然可以直接拼接字符串,但是,在循环中,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。
为了能高效拼接字符串,Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象:
StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
sb.append(',');
sb.append(i);
}
String s = sb.toString();
StringBuilder还可以进行链式操作:
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(1024);
sb.append("Mr ")
.append("Bob")
.append("!")
.insert(0, "Hello, ");
System.out.println(sb.toString());
}
}
如果我们查看StringBuilder的源码,可以发现,进行链式操作的关键是,定义的append()方法会返回this,这样,就可以不断调用自身的其他方法。
仿照StringBuilder,我们也可以设计支持链式操作的类。例如,一个可以不断增加的计数器:
public class Main {
public static void main(String[] args) {
Adder adder = new Adder();
adder.add(3)
.add(5)
.inc()
.add(10);
System.out.println(adder.value());
}
}
class Adder {
private int sum = 0;
public Adder add(int n) {
sum += n;
return this;
}
public Adder inc() {
sum ++;
return this;
}
public int value() {
return sum;
}
}
StringBuilder 和 StringJoiner
要高效拼接字符串,应该使用StringBuilder。
很多时候,我们拼接的字符串像这样:
public class Main {
public static void main(String[] args) {
String[] names = {"Bob", "Alice", "Grace"};
StringBuilder sb = new StringBuilder();
sb.append("Hello ");
for (String name : names) {
sb.append(name).append(", ");
}
// 注意去掉最后的", ":
sb.delete(sb.length() - 2, sb.length());
sb.append("!");
System.out.println(sb.toString());
}
}
输出结果:
Hello Bob, Alice, Grace!
类似用分隔符拼接数组的需求很常见,所以Java标准库还提供了一个StringJoiner来干这个事:
public class Main {
public static void main(String[] args) {
String[] names = {"Bob", "Alice", "Grace"};
StringJoiner sj = new StringJoiner(", ");
for (String name : names) {
sj.add(name);
}
System.out.println(sj.toString());
}
}
输出结果:
Bob, Alice, Grace //注意,和join方法一样,没有前后缀
但是用StringJoiner的结果少了前面的"Hello"和结尾的"!",遇到这种情况,需要给StringJoiner指定“开头”和“结尾”:
public class Main {
public static void main(String[] args) {
String[] names = {"Bob", "Alice", "Grace"};
//第一个为分隔符,第二个参数为字符串前缀,第三个参数为字符串后缀,注意空格
StringJoiner sj = new StringJoiner(", ", "Hello ", "!");
for (String name : names) {
sj.add(name);
}
System.out.println(sj.toString());
}
}
输出结果:
Hello Bob, Alice, Grace!
那么StringJoiner内部是如何拼接字符串的呢?如果查看源码,可以发现,StringJoiner内部实际上就是使用了StringBuilder,所以拼接效率和StringBuilder几乎是一模一样的。
String.join()
String还提供了一个静态方法join(),这个方法在内部使用了StringJoiner来拼接字符串,在不需要指定“开头”和“结尾”的时候,用String.join()更方便:
String[] names = {"Bob", "Alice", "Grace"};
String s = String.join(", ", names);
StringBuilder、StringBuffer和StringJoiner的更多相关文章
- 你只会用 StringBuilder?试试 StringJoiner,真香!
你只会用 StringBuilder/ StringBuffer 拼接字符串? 那你就 OUT 了!! 如果需要拼接分隔符的字符串,建议使用 Java 8 中的这款拼接神器:StringJoiner, ...
- string,stringbuilder,stringbuffer用法
总结:1.如果要操作少量的数据用 = String ==================================>字符串常量2.单线程操作字符串缓冲区 下操作大量数据 = Strin ...
- [java] StringBuilder / StringBuffer / String 建立字符串
1.三者在建立新字符串速度方面的比较: StringBuilder > StringBuffer > String 2.线程安全性: StringBuilder:线程非安全的 Str ...
- JAVA StringBuilder StringBuffer String比较
字符串连接时的效率: StringBuilder>StringBuffer>String 区别: StringBuilder效率最高,但是不是线程安全的,适用于单线程.多线程用String ...
- java中string stringbuilder stringbuffer 的区别
1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a&qu ...
- Java中string拼接,StringBuilder,StringBuffer和+
Java中string拼接,StringBuilder,StringBuffer和+,到底哪个更合适? StringBuilder线程不安全,效率较线程安全的StringBuffer高.jdk1.5之 ...
- String,StringBuilder,StringBuffer
(转:http://blog.csdn.net/rmn190/article/details/1492013) String 字符串常量StringBuffer 字符串变量(线程安全)String ...
- String Stringbuilder Stringbuffer的区别
String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...
- 深入源码剖析String,StringBuilder,StringBuffer
[String,StringBuffer,StringBulider] 深入源码剖析String,StringBuilder,StringBuffer [作者:高瑞林] [博客地址]http://ww ...
- String, StringBuilder, StringBuffer问题
1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...
随机推荐
- Linux系统时间\硬件时间(date、tzselect、clock、hwclock、ntpdate)
1.系统时间和硬件时间 在Linux中有硬件时钟与系统时钟两种时钟.硬件时钟是指主机板上的时钟设备,也就是通常可在BIOS画面设定的时钟.系统时钟则是指kernel中的时钟.所有Linux相关指令与函 ...
- Win10专业版和企业版的区别
微软最新的Windows 10版本诸多,包括精简版(S).家庭版(Home).专业版(Pro).企业版(Enterprise),而论功能体验,Win10专业版和企业版无疑是最完善的.那么,Win10专 ...
- eNSP仿真软件之利用单臂路由实现VLAN间路由
1. 实验原理 以太网中,通常会使用VLAN技术隔离二层广播域来减少广播的影响,并增强网络的安全性和可管理性.其缺点是同时也严格地隔离了不同VLAN之间的任何二层流量,使分属于不同VLAN的用户不能直 ...
- oracle中两个服务器连接中sys密码修改问题
问题描述:orcl服务器要连接orclstd 想要sqlplus sys/410526@orclstd as sysdba 连接orclstd数据库,但是发现啥意思密码不对,就对sys密码进行重新设置 ...
- RxJS入门
一.RxJS是什么? 官方文档使用了一句话总结RxJS: Think of RxJS as Lodash for events.那么Lodash主要解决了什么问题?Lodash主要集成了一系列关于数组 ...
- day 40 文本属性 常用css属性 定位
一. 浮动的特性 1.浮动的元素脱标 2.浮动的元素互相贴靠 3.浮动的元素由"字围"效果 4.收缩的效果 前提是标准文档流,margin的垂直方向会出现塌陷问题. 如果盒子居中: ...
- python常见字符串操作
附: python2.x和python3.x中raw_input( )和input( )区别: 备注:1.在python2.x中raw_input( )和input( ),两个函数都存在,其中区别为r ...
- vue下谷歌浏览器的扩展程序(vue-devtools-master)
1,在百度网盘中下载压缩包,网盘地址:https://pan.baidu.com/s/1BnwWHANHNyJzG3Krpy7S8A ,密码:xm6s 2,将压缩包解压到F盘,F:\chromeVue ...
- python名称空间和作用域
python名称空间和作用域 名称空间 名称空间:例如a=1000,python解释器会开辟一块新的内存来存贮1000这个变量值,然后会有一个a指向这个1000,那么a存在哪里?其实他和变量值差不多, ...
- 线程锁&信号量&gil
线程锁 线程锁的主要目的是防止多个线程之间出现同时抢同一个数据,这会造成数据的流失.线程锁的作用类似于进程锁,都是为了数据的安全性 下面,我将用代码来体现进程锁的作用: from threading ...