c++ 字符串拼接_字符串拼接新姿势:StringJoiner
來自:Hollis(微信號:hollischuang)
在為什么阿里巴巴不建議在for循環(huán)中使用”+”進(jìn)行字符串拼接一文中,我們介紹了幾種Java中字符串拼接的方式,以及優(yōu)缺點(diǎn)。其中還有一個(gè)重要的拼接方式我沒有介紹,那就是Java 8中提供的StringJoiner ,本文就來介紹一下這個(gè)字符串拼接的新兵。
如果你想知道一共有多少種方法可以進(jìn)行字符串拼接,教你一個(gè)簡單的辦法,在Intellij IDEA中,定義一個(gè)Java Bean,然后嘗試使用快捷鍵自動生成一個(gè)toString方法,IDEA會提示多種toString生成策略可供選擇。
目前我使用的IDEA的toString生成策略默認(rèn)的是使用JDK 1.8提供的StringJoiner。
1
介紹
StringJoiner是java.util包中的一個(gè)類,用于構(gòu)造一個(gè)由分隔符分隔的字符序列(可選),并且可以從提供的前綴開始并以提供的后綴結(jié)尾。
雖然這也可以在StringBuilder類的幫助下在每個(gè)字符串之后附加分隔符,但StringJoiner提供了簡單的方法來實(shí)現(xiàn),而無需編寫大量代碼。
StringJoiner類共有2個(gè)構(gòu)造函數(shù),5個(gè)公有方法。其中最常用的方法就是add方法和toString方法,類似于StringBuilder中的append方法和toString方法。
2
用法
StringJoiner的用法比較簡單,下面的代碼中,我們使用StringJoiner進(jìn)行了字符串拼接。
public?class?StringJoinerTest?{public?static?void?main(String[]?args)?{
????????StringJoiner?sj?=?new?StringJoiner("Hollis");
????????sj.add("hollischuang");
????????sj.add("Java干貨");
????????System.out.println(sj.toString());
????????StringJoiner?sj1?=?new?StringJoiner(":","[","]");
????????sj1.add("Hollis").add("hollischuang").add("Java干貨");
????????System.out.println(sj1.toString());
????}
}
以上代碼輸出結(jié)果:
hollischuangHollisJava干貨[Hollis:hollischuang:Java干貨]
值得注意的是,當(dāng)我們使用StringJoiner(CharSequence delimiter)初始化一個(gè)StringJoiner的時(shí)候,這個(gè)delimiter其實(shí)是分隔符,并不是可變字符串的初始值。
StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix)的第二個(gè)和第三個(gè)參數(shù)分別是拼接后的字符串的前綴和后綴。
3
原理
介紹了簡單的用法之后,我們再來看看這個(gè)StringJoiner的原理,看看他到底是如何實(shí)現(xiàn)的。主要看一下add方法:
public?StringJoiner?add(CharSequence?newElement)?{
????prepareBuilder().append(newElement);return?this;
}private?StringBuilder?prepareBuilder()?{if?(value?!=?null)?{value.append(delimiter);
????}?else?{value?=?new?StringBuilder().append(prefix);
????}return?value;
}
看到了一個(gè)熟悉的身影——StringBuilder ,沒錯(cuò),StringJoiner其實(shí)就是依賴StringBuilder實(shí)現(xiàn)的,在為什么阿里巴巴不建議在for循環(huán)中使用”+”進(jìn)行字符串拼接中我們介紹過StringBuilder的實(shí)現(xiàn)原理,本文不在贅述。
當(dāng)我們發(fā)現(xiàn)StringJoiner其實(shí)是通過StringBuilder實(shí)現(xiàn)之后,我們大概就可以猜到,StringJoiner性能損耗應(yīng)該和直接使用StringBuilder差不多!
為什么需要StringJoiner
在了解了StringJoiner的用法和原理后,可能很多讀者就會產(chǎn)生一個(gè)疑問,明明已經(jīng)有一個(gè)StringBuilder了,為什么Java 8中還要定義一個(gè)StringJoiner呢?到底有什么好處呢?
如果讀者足夠了解Java 8的話,或許可以猜出個(gè)大概,這肯定和Stream有關(guān)。
作者也在Java doc中找到了答案:
A StringJoiner may be employed to create formatted output from a Stream using Collectors.joining(CharSequence)
試想,在Java中,如果我們有這樣一個(gè)List:
List?list?=?ImmutableList.of("Hollis","hollischuang","Java干貨");
如果我們想要把他拼接成一個(gè)以下形式的字符串:
Hollis,hollischuang,Java干貨
可以通過以下方式:
StringBuilder?builder?=?new?StringBuilder();if?(!list.isEmpty())?{
????builder.append(list.get(0));for?(int?i?=?1,?n?=?list.size();?i?????????builder.append(",").append(list.get(i));
????}
}
builder.toString();
還可以使用:
list.stream().reduce(new?StringBuilder(),?(sb,?s)?->?sb.append(s).append(','),?StringBuilder::append).toString();
但是輸出結(jié)果稍有些不同,需要進(jìn)行二次處理:
Hollis,hollischuang,Java干貨,
還可以使用"+"進(jìn)行拼接:
list.stream().reduce((a,b)->a?+?","?+?b).toString();
以上幾種方式,要么是代碼復(fù)雜,要么是性能不高,或者無法直接得到想要的結(jié)果。
為了滿足類似這樣的需求,Java 8中提供的StringJoiner就派上用場了。以上需求只需要一行代碼:
list.stream().collect(Collectors.joining(":"))
即可。上面用的表達(dá)式中,Collector.joining的源代碼如下:
public?static?Collector?joining(CharSequence?delimiter,CharSequence?prefix,CharSequence?suffix)?{return?new?CollectorImpl<>(
????????????()?->?new?StringJoiner(delimiter,?prefix,?suffix),
????????????StringJoiner::add,?StringJoiner::merge,
????????????StringJoiner::toString,?CH_NOID);
}
Collector.joining的實(shí)現(xiàn)原理就是借助了StringJoiner。
當(dāng)然,或許在Collector中直接使用StringBuilder似乎也可以實(shí)現(xiàn)類似的功能,只不過稍微麻煩一些。所以,Java 8中提供了StringJoiner來豐富Stream的用法。
而且StringJoiner也可以方便的增加前綴和后綴,比如我們希望得到的字符串是"[Hollis,hollischuang,Java干貨]"而不是"Hollis,hollischuang,Java干貨"的話,StringJoiner的優(yōu)勢就更加明顯了。
4
總結(jié)
本文介紹了Java 8中提供的可變字符串類——StringJoiner,可以用于字符串拼接。
StringJoiner其實(shí)是通過StringBuilder實(shí)現(xiàn)的,所以他的性能和StringBuilder差不多,他也是非線程安全的。
如果日常開發(fā)中中,需要進(jìn)行字符串拼接,如何選擇?
1、如果只是簡單的字符串拼接,考慮直接使用"+"即可。
2、如果是在for循環(huán)中進(jìn)行字符串拼接,考慮使用StringBuilder和StringBuffer。
3、如果是通過一個(gè)集合(如List)進(jìn)行字符串拼接,則考慮使用StringJoiner。
4、如果是對一組數(shù)據(jù)進(jìn)行拼接,則可以考慮將其轉(zhuǎn)換成Stream,并使用StringJoiner處理。
●編號917,輸入編號直達(dá)本文
●輸入m獲取文章目錄
推薦↓↓↓程序員求職面試
更多推薦《25個(gè)技術(shù)類公眾微信》
涵蓋:程序人生、算法與數(shù)據(jù)結(jié)構(gòu)、黑客技術(shù)與網(wǎng)絡(luò)安全、大數(shù)據(jù)技術(shù)、前端開發(fā)、Java、Python、Web開發(fā)、安卓開發(fā)、iOS開發(fā)、C/C++、.NET、Linux、數(shù)據(jù)庫、運(yùn)維等。
總結(jié)
以上是生活随笔為你收集整理的c++ 字符串拼接_字符串拼接新姿势:StringJoiner的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黄金基金怎么玩?购买黄金基金的技巧
- 下一篇: 最新,2019年11月LPR利率出来了!