99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Java 8新增的 StringJoiner用法

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-11 15:40 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

概述

StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix.

Prior to adding something to the StringJoiner, its sj.toString() method will, by default, return prefix + suffix. However, if the setEmptyValue method is called, the emptyValue supplied will be returned instead. This can be used, for example, when creating a string using set notation to indicate an empty set, i.e. "{}", where the prefix is "{", the suffix is "}" and nothing has been added to the StringJoiner.

StringJoiner 源碼的定義可以看出,它是 java.util 包中的一個(gè)類,被用來構(gòu)造一個(gè)由分隔符分隔的字符串,并且可以從提供的前綴字符串開頭,以提供的后綴字符串結(jié)尾。

通常我們拼接字符串都是使用 StringBuilder 或者 StringBuffer 來實(shí)現(xiàn)的。這個(gè)時(shí)候,我們可能就會(huì)有一個(gè)疑問了, StringJoiner 的價(jià)值是什么?到底為什么要到這個(gè)時(shí)候創(chuàng)造它。

源碼解析

好,我們先看一下 StringJoiner 的構(gòu)造函數(shù), StringJoiner 一共有 2 個(gè)構(gòu)造函數(shù)。構(gòu)造函數(shù)很簡(jiǎn)單,沒有什么可以多講的,就是對(duì) 分隔符、前綴和后綴字符串的初始化。

public StringJoiner(CharSequence delimiter) {
        this(delimiter, "", "");
    }
    public StringJoiner(CharSequence delimiter,
                        CharSequence prefix,
                        CharSequence suffix) {
        Objects.requireNonNull(prefix, "The prefix must not be null");
        Objects.requireNonNull(delimiter, "The delimiter must not be null");
        Objects.requireNonNull(suffix, "The suffix must not be null");
        // make defensive copies of arguments
        this.prefix = prefix.toString();
        this.delimiter = delimiter.toString();
        this.suffix = suffix.toString();
    }

另外 StringJoiner 有 5 個(gè)公有方法,其中比較常用的就是 addtoString 。我們也來看看這兩個(gè)常用方法。

public final class StringJoiner {
    private String[] elts;
    
    @Override
    public String toString() {
        final String[] elts = this.elts;
        if (elts == null && emptyValue != null) {
            return emptyValue;
        }
        final int size = this.size;
        final int addLen = prefix.length() + suffix.length();
        if (addLen == 0) {
            compactElts();
            return size == 0 ? "" : elts[0];
        }
        final String delimiter = this.delimiter;
        final char[] chars = new char[len + addLen];
        int k = getChars(prefix, chars, 0);
        if (size > 0) {
            k += getChars(elts[0], chars, k);
            for (int i = 1; i < size; i++) {
                k += getChars(delimiter, chars, k);
                k += getChars(elts[i], chars, k);
            }
        }
        k += getChars(suffix, chars, k);
        return new String(chars);
    }
    public StringJoiner add(CharSequence newElement) {
        final String elt = String.valueOf(newElement);
        if (elts == null) {
            elts = new String[8];
        } else {
            if (size == elts.length)
                elts = Arrays.copyOf(elts, 2 * size);
            len += delimiter.length();
        }
        len += elt.length();
        elts[size++] = elt;
        return this;
    }
}

我們來看下 add 方法的實(shí)現(xiàn),看起來也挺簡(jiǎn)單的,就是把待拼接的字符串,放到一個(gè)字符串?dāng)?shù)組里面。toString() 方法的時(shí)候,才是真正做字符串拼接的過程。我例子中的代碼是 JDK 11, 相比 JDK 8 中,StringJoiner 是通過 StringBuilder 來實(shí)現(xiàn)的。

既然 JDK 8 的時(shí)候,已經(jīng)使用了StringBuilder 來實(shí)現(xiàn),那么為什么還要改成 String[] 來緩存所有的待拼接的字符串。這個(gè)就要涉及到JVM底層的優(yōu)化,我們這里暫時(shí)不展開講這個(gè)問題了。

前面已經(jīng)提過既然已經(jīng)有了 StringBuilder,為什么還要造一個(gè)StringJoiner,它的優(yōu)勢(shì)到底在哪里,我們接著來找找原因。很快我們?cè)诖a類的注釋中找到了貓膩,在注釋中標(biāo)記了Collectors#joining 。

A StringJoiner may be employed to create formatted output from a java.util.stream.Stream using java.util.stream.Collectors.joining(CharSequence).

* @see java.util.stream.Collectors#joining(CharSequence)
 * @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence)

那我們就順藤摸瓜,看看 Collectors#joining 有什么跟 StringJoiner 有關(guān)聯(lián)的呢?

public static Collector< CharSequence, ?, String > joining() {
        return new CollectorImpl< CharSequence, StringBuilder, String >(
                StringBuilder::new, StringBuilder::append,
                (r1, r2) - > { r1.append(r2); return r1; },
                StringBuilder::toString, CH_NOID);
    }
    public static Collector< CharSequence, ?, String > joining(CharSequence delimiter) {
        return joining(delimiter, "", "");
    }
    public static Collector< CharSequence, ?, String > joining(CharSequence delimiter,
                                                             CharSequence prefix,
                                                             CharSequence suffix) {
        return new CollectorImpl<  >(
                () - > new StringJoiner(delimiter, prefix, suffix),
                StringJoiner::add, StringJoiner::merge,
                StringJoiner::toString, CH_NOID);
    }

原來啊,Java 8Stream 是借助了 StringJoiner 來實(shí)現(xiàn)的。這個(gè)時(shí)候,我們可能會(huì)想,為什么不使用 StringBuilder 來實(shí)現(xiàn)呢?我們可以從上面的代碼里看出,如果 使用 StringBuilder 來構(gòu)造拼接的話,在沒有前后綴的情況下,應(yīng)該還是簡(jiǎn)單的,事實(shí)上JDK 官方組織也選擇了 StringBuilder 。但是一旦涉及到拼接之類的操作,那如果還是使用 StringBuilder 的話,那就真的是太復(fù)雜了。

所以 StringJoinerJava 8 的地位是 StringBuilder 所不能代替的。

總結(jié)

本文介紹了 Java 8 開始提供的字符串拼接類 StringJoiner。JDK 8StringJoiner 是通過 StringBuilder 實(shí)現(xiàn)的, 所以它的性能和 StringBuilder 差不多,它也是非線程安全的。JDK 11 中已經(jīng)對(duì)其進(jìn)行了優(yōu)化,通過 String[] 來代理 StringBuilder 。

在日常的開發(fā)過程中,我們?cè)趺催x擇字符串拼接類呢?

  1. 簡(jiǎn)單的字符串拼接,直接使用 + 即可。
  2. 在 for 循環(huán)之類的場(chǎng)景下需要字符串拼接,可以優(yōu)先考慮使用 StringBuilder 。
  3. 在使用 Java Stream 的場(chǎng)景下需要字符串拼接,可以優(yōu)先考慮使用 StringJoiner。
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2989

    瀏覽量

    109605
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    590

    瀏覽量

    22263
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4380

    瀏覽量

    64850
  • string
    +關(guān)注

    關(guān)注

    0

    文章

    40

    瀏覽量

    4910
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Java多線程的用法

    本文將介紹一下Java多線程的用法。 基礎(chǔ)介紹 什么是多線程 指的是在一個(gè)進(jìn)程中同時(shí)運(yùn)行多個(gè)線程,每個(gè)線程都可以獨(dú)立執(zhí)行不同的任務(wù)或操作。 與單線程相比,多線程可以提高程序的并發(fā)性和響應(yīng)
    的頭像 發(fā)表于 09-30 17:07 ?1228次閱讀

    新增16條設(shè)計(jì)規(guī)約!阿里巴巴Java開發(fā)手冊(cè)(詳盡版)開放下載!

    摘要:2018年6月,《阿里巴巴Java開發(fā)手冊(cè)》再次刷新代碼規(guī)范認(rèn)知,我們新增了16條設(shè)計(jì)規(guī)約!現(xiàn)免費(fèi)開放下載,不可錯(cuò)過!《阿里巴巴Java開發(fā)手冊(cè)》是阿里內(nèi)部Java工程師所遵循的
    發(fā)表于 06-06 17:24

    java并發(fā)編程實(shí)戰(zhàn)之輔助類用法

    二.CyclicBarrier用法 三.Semaphore用法 若有不正之處請(qǐng)多多諒解,并歡迎批評(píng)指正。 一.CountDownLatch用法 CountDownLatch類位于java
    發(fā)表于 09-27 16:50 ?0次下載

    java8新特性

    java8為接口聲明添加非抽象方法的實(shí)現(xiàn),也成為拓展方法。
    發(fā)表于 11-27 15:54 ?1827次閱讀

    java final關(guān)鍵字用法技巧匯總解析

    談到final關(guān)鍵字,想必很多人都不陌生,在使用匿名內(nèi)部類的時(shí)候可能會(huì)經(jīng)常用到final關(guān)鍵字。另外,Java中的String類就是一個(gè)final類,那么今天我們就來了解final這個(gè)關(guān)鍵字的用法
    發(fā)表于 12-01 11:02 ?1239次閱讀
    <b class='flag-5'>java</b> final關(guān)鍵字<b class='flag-5'>用法</b>技巧匯總解析

    Java數(shù)組的常用方法_Java:數(shù)組工具類Arrays類的常用方法的用法及代碼

    本文主要詳細(xì)介紹了Java數(shù)組的常用方法以及數(shù)組工具類Arrays類的常用方法的用法及代碼。
    發(fā)表于 01-29 10:25 ?3056次閱讀

    Java 10 發(fā)布之后,大多數(shù)受訪者仍在使用 Java 8(82%)

    300 條的反饋,并對(duì)數(shù)據(jù)進(jìn)行的整理。整理的數(shù)據(jù)結(jié)果顯示,大多數(shù)受訪者仍在使用 Java 8(82%)。 8% 的用戶仍在使用 Java 9,而使用
    的頭像 發(fā)表于 06-13 11:43 ?3486次閱讀
    <b class='flag-5'>Java</b> 10 發(fā)布之后,大多數(shù)受訪者仍在使用 <b class='flag-5'>Java</b> <b class='flag-5'>8</b>(82%)

    Java11GC 性能基準(zhǔn)測(cè)試報(bào)告 Java8Java11對(duì)比測(cè)試

    當(dāng)前使用量最大的 Java 版本是 8,所以測(cè)試者用 Java 8Java 11 進(jìn)行對(duì)比測(cè)試。GC 是影響
    發(fā)表于 02-01 01:46 ?3867次閱讀

    SpringBoot正式棄用Java8 Java17將成為未來主流版本

    Java基線從 Java 8 提升到了 Java 17 從Java EE APIs 到 Jakarta EE 這個(gè)支持被移除 依賴升級(jí) 未來
    的頭像 發(fā)表于 10-09 18:03 ?3901次閱讀

    如何正確區(qū)分Java中super函數(shù)用法

    Java中super函數(shù)有很多方法,在使用的時(shí)候我們應(yīng)該如何正確區(qū)分? 2 方法 三種用法: 訪問父類的方法。 調(diào)用父類構(gòu)造方法。 訪問父類中的隱藏成員變量。
    的頭像 發(fā)表于 02-21 15:08 ?797次閱讀

    Java枚舉的特點(diǎn)及用法

    Java 枚舉出現(xiàn)之前,通常會(huì)使用常量類來表示一組固定的常量值,直到Java 1.5之后推出了枚舉,那么枚舉類型有哪些特點(diǎn),它比常量類又好在哪里呢。 本文將分析一下枚舉的特點(diǎn)及用法。 1.
    的頭像 發(fā)表于 09-30 10:02 ?1996次閱讀

    Java時(shí)間類轉(zhuǎn)換方案

    LocalDate 的過程中,我們使用 Date 類中在 Java 8 新增的 toInstant() 方法進(jìn)行轉(zhuǎn)換。 當(dāng)我們轉(zhuǎn)換一個(gè) Instant 對(duì)象時(shí),需要使用 ZoneId,因?yàn)?Instant 對(duì)象是不分時(shí)區(qū)的--
    的頭像 發(fā)表于 10-09 15:48 ?734次閱讀

    java 8的日期用法

    java 已經(jīng)出到 17 了,而小編還在用 8 的版本,在 8 中已經(jīng)推出了新的日期 API,不在使用 。java.time 包下提供了用于日期、時(shí)間、實(shí)例和周期的主要 API。 獲取
    的頭像 發(fā)表于 10-09 15:50 ?638次閱讀

    this關(guān)鍵字在Java中的用法

    this 關(guān)鍵字只能在方法內(nèi)部使用,表示對(duì)“調(diào)用方法的那個(gè)對(duì)象”的引用。 其實(shí)簡(jiǎn)單來說 this 關(guān)鍵字就是表示當(dāng)前對(duì)象,下面我們來具體介紹 this 關(guān)鍵字在Java中的用法。 1、調(diào)用成員變量
    的頭像 發(fā)表于 10-10 16:49 ?972次閱讀
    this關(guān)鍵字在<b class='flag-5'>Java</b>中的<b class='flag-5'>用法</b>

    java中obj類型的實(shí)戰(zhàn)用法

    類型具有許多實(shí)戰(zhàn)用法,下面將詳細(xì)介紹一些常見的使用場(chǎng)景。 作為方法參數(shù)和返回值的類型 在Java中,可以使用obj類型作為方法的參數(shù)或返回值類型。這種用法可以使方法具有更廣泛的適用性,因?yàn)閛bj類型可以接受任何對(duì)象作為參數(shù)或返回
    的頭像 發(fā)表于 11-21 10:27 ?1119次閱讀