Java菜譜(五)——怎么把字符串列表合并為一個(gè)字符串抑月?

今天的菜品是這樣的:

怎樣把許多小字符串合并成一個(gè)大的字符串。

太長(zhǎng)不看版

  • 可以用String.join()方法將字符串的List或數(shù)組拼接成一個(gè)大字符串舆蝴,并指定分隔符谦絮。
  • 也可以手動(dòng)創(chuàng)建StringJoiner對(duì)象,指定分隔符洁仗、前綴和后綴层皱。
  • 如果需要先對(duì)字符串進(jìn)行處理,可以將List或數(shù)組轉(zhuǎn)成Stream赠潦,處理后再利用Collectors.joining()方法進(jìn)行合并叫胖。
  • 避免在循環(huán)中使用+操作符進(jìn)行字符串拼接

String.join()方法

如果想要合并的字符串在一個(gè)列表、數(shù)組或其他可迭代對(duì)象中她奥,那么合并它們最快的方法就是使用String.join()靜態(tài)方法瓮增。這一個(gè)API可以說(shuō)是千呼萬(wàn)喚才在jdk8中“始出來(lái)”,因?yàn)槠渌Z(yǔ)言很早就支持這一方便的特性哩俭。示例如下:

    List<String> list = List.of("Java", "is", "very", "cool"); // 注意這個(gè)api是jdk9之后引入的
    final String join = String.join(",", list);
    System.out.println(join); // Java,is,very,cool

String.join()方法的第一個(gè)參數(shù)是分隔符绷跑,即字符串拼接時(shí)連接各個(gè)小字符串的字符,第二個(gè)參數(shù)是可迭代對(duì)象或者不定長(zhǎng)參數(shù)携茂。因此該API支持?jǐn)?shù)組以及List、Set等各種可迭代對(duì)象诅岩,也可以按不定長(zhǎng)的方式使用:

    final String join = String.join(",", "Java", "is", "very", "cool");
    System.out.println(join); // Java,is,very,cool

StringJoiner

/* String.join()源碼 */

public static String join(CharSequence delimiter, CharSequence... elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
        joiner.add(cs);
    }
    return joiner.toString();
}
public static String join(CharSequence delimiter,
        Iterable<? extends CharSequence> elements) {
    Objects.requireNonNull(delimiter);
    Objects.requireNonNull(elements);
    StringJoiner joiner = new StringJoiner(delimiter);
    for (CharSequence cs: elements) {
        joiner.add(cs);
    }
    return joiner.toString();
}

通過(guò)String.join()兩個(gè)重載方法的源碼我們發(fā)現(xiàn)讳苦,String.join()方法是通過(guò)創(chuàng)建StringJoiner對(duì)象實(shí)現(xiàn)的带膜,該類同樣也是在jdk8版本引入的。

有時(shí)候我們也可以主動(dòng)創(chuàng)建StringJoiner類來(lái)實(shí)現(xiàn)字符串的合并鸳谜,如在合并結(jié)果需要前后綴的情況下:

    StringJoiner joiner = new StringJoiner("-", "(", ")");
    List<String> list = List.of("Java", "is", "very", "cool");
    list.forEach(joiner::add);
    System.out.println(joiner.toString());

Stream收集器的Collectors.joining()

有時(shí)候我們需要對(duì)原字符串列表進(jìn)行一定處理后再進(jìn)行拼接膝藕,這時(shí)我們就可以用Stream的collect方法直接對(duì)處理后的字符串進(jìn)行拼接,示例如下:

    List<String> list = List.of("Java", "is", "very", "cool");
    final String result = list.stream().map(s -> s + "abc").collect(Collectors.joining("-"));
    System.out.println(result); // Javaabc-isabc-veryabc-coolabc

+號(hào)與StringBuilder

如果只是要簡(jiǎn)單連接一些字符串咐扭,一般直接使用+操作符就足夠完成任務(wù)了芭挽。但是我們需要意識(shí)到,在使用+操作符對(duì)大量字符串進(jìn)行拼接的時(shí)候蝗肪,這種連接的效率是很低的袜爪。

因?yàn)槭褂?操作符拼接字符串是Java內(nèi)置的一種操作符重載的行為,在編譯階段薛闪,非字面量字符串進(jìn)行拼接時(shí)辛馆,會(huì)被編譯器改寫為通過(guò)StringBuilder的append方法進(jìn)行拼接。如果在循環(huán)結(jié)構(gòu)中使用+進(jìn)行字符串拼接豁延,則會(huì)產(chǎn)生大量的StringBuilder對(duì)象昙篙,降低整個(gè)程序運(yùn)行效率。因此我們應(yīng)該避免在循環(huán)結(jié)構(gòu)中使用加號(hào)進(jìn)行字符串拼接诱咏,改用String.join方法或者手動(dòng)在循環(huán)外創(chuàng)建StringBuilder對(duì)象苔可。

    String str = "";
    // 錯(cuò)誤!4焚辅!不能在循環(huán)中使用+或+=進(jìn)行字符串拼接!!!
    //for (s: list) {
    //    str += s;
    //}

    // 方法1,推薦
    str = String.join("", str);

    // 方法2硕并,相對(duì)麻煩
    StringBuilder sb = new StringBuilder();
    list.forEach(sb::append);
    str = sb.toString();

    // 方法3法焰,相對(duì)麻煩
    StringJoiner sj = new StringJoiner("");
    list.forEach(sj::add);
    str = sj.toString();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市倔毙,隨后出現(xiàn)的幾起案子埃仪,更是在濱河造成了極大的恐慌,老刑警劉巖陕赃,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卵蛉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡么库,警方通過(guò)查閱死者的電腦和手機(jī)傻丝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)诉儒,“玉大人葡缰,你說(shuō)我怎么就攤上這事。” “怎么了泛释?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵滤愕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我怜校,道長(zhǎng)间影,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任茄茁,我火速辦了婚禮魂贬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘裙顽。我一直安慰自己付燥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布锦庸。 她就那樣靜靜地躺著机蔗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪甘萧。 梳的紋絲不亂的頭發(fā)上萝嘁,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音扬卷,去河邊找鬼牙言。 笑死,一個(gè)胖子當(dāng)著我的面吹牛怪得,可吹牛的內(nèi)容都是我干的咱枉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼徒恋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蚕断!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起入挣,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤亿乳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后径筏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葛假,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年滋恬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了聊训。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡恢氯,死狀恐怖带斑,靈堂內(nèi)的尸體忽然破棺而出鼓寺,到底是詐尸還是另有隱情,我是刑警寧澤勋磕,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布侄刽,位于F島的核電站,受9級(jí)特大地震影響朋凉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜醋安,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一杂彭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吓揪,春花似錦亲怠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至叭首,卻和暖如春习勤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背焙格。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工图毕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人眷唉。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓予颤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親冬阳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蛤虐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容