精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Java 8新增的 StringJoiner用法

科技綠洲 ? 來源:Java技術指北 ? 作者:Java技術指北 ? 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 包中的一個類,被用來構造一個由分隔符分隔的字符串,并且可以從提供的前綴字符串開頭,以提供的后綴字符串結尾。

通常我們拼接字符串都是使用 StringBuilder 或者 StringBuffer 來實現的。這個時候,我們可能就會有一個疑問了, StringJoiner 的價值是什么?到底為什么要到這個時候創造它。

源碼解析

好,我們先看一下 StringJoiner 的構造函數, StringJoiner 一共有 2 個構造函數。構造函數很簡單,沒有什么可以多講的,就是對 分隔符、前綴和后綴字符串的初始化。

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 個公有方法,其中比較常用的就是 addtoString 。我們也來看看這兩個常用方法。

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 方法的實現,看起來也挺簡單的,就是把待拼接的字符串,放到一個字符串數組里面。toString() 方法的時候,才是真正做字符串拼接的過程。我例子中的代碼是 JDK 11, 相比 JDK 8 中,StringJoiner 是通過 StringBuilder 來實現的。

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

前面已經提過既然已經有了 StringBuilder,為什么還要造一個StringJoiner,它的優勢到底在哪里,我們接著來找找原因。很快我們在代碼類的注釋中找到了貓膩,在注釋中標記了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 有關聯的呢?

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 來實現的。這個時候,我們可能會想,為什么不使用 StringBuilder 來實現呢?我們可以從上面的代碼里看出,如果 使用 StringBuilder 來構造拼接的話,在沒有前后綴的情況下,應該還是簡單的,事實上JDK 官方組織也選擇了 StringBuilder 。但是一旦涉及到拼接之類的操作,那如果還是使用 StringBuilder 的話,那就真的是太復雜了。

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

總結

本文介紹了 Java 8 開始提供的字符串拼接類 StringJoinerJDK 8StringJoiner 是通過 StringBuilder 實現的, 所以它的性能和 StringBuilder 差不多,它也是非線程安全的。JDK 11 中已經對其進行了優化,通過 String[] 來代理 StringBuilder

在日常的開發過程中,我們怎么選擇字符串拼接類呢?

  1. 簡單的字符串拼接,直接使用 + 即可。
  2. 在 for 循環之類的場景下需要字符串拼接,可以優先考慮使用 StringBuilder 。
  3. 在使用 Java Stream 的場景下需要字符串拼接,可以優先考慮使用 StringJoiner。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2959

    瀏覽量

    104553
  • 字符串
    +關注

    關注

    1

    文章

    577

    瀏覽量

    20485
  • 函數
    +關注

    關注

    3

    文章

    4307

    瀏覽量

    62433
  • string
    +關注

    關注

    0

    文章

    40

    瀏覽量

    4719
收藏 人收藏

    評論

    相關推薦

    Java多線程的用法

    本文將介紹一下Java多線程的用法。 基礎介紹 什么是多線程 指的是在一個進程中同時運行多個線程,每個線程都可以獨立執行不同的任務或操作。 與單線程相比,多線程可以提高程序的并發性和響應
    的頭像 發表于 09-30 17:07 ?926次閱讀

    新增16條設計規約!阿里巴巴Java開發手冊(詳盡版)開放下載!

    摘要:2018年6月,《阿里巴巴Java開發手冊》再次刷新代碼規范認知,我們新增了16條設計規約!現免費開放下載,不可錯過!《阿里巴巴Java開發手冊》是阿里內部Java工程師所遵循的
    發表于 06-06 17:24

    java并發編程實戰之輔助類用法

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

    java8新特性

    java8為接口聲明添加非抽象方法的實現,也成為拓展方法。
    發表于 11-27 15:54 ?1733次閱讀

    java final關鍵字用法技巧匯總解析

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

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

    本文主要詳細介紹了Java數組的常用方法以及數組工具類Arrays類的常用方法的用法及代碼。
    發表于 01-29 10:25 ?2910次閱讀

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

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

    Java11GC 性能基準測試報告 Java8Java11對比測試

    當前使用量最大的 Java 版本是 8,所以測試者用 Java 8Java 11 進行對比測試。GC 是影響
    發表于 02-01 01:46 ?3610次閱讀

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

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

    如何正確區分Java中super函數用法

    Java中super函數有很多方法,在使用的時候我們應該如何正確區分? 2 方法 三種用法: 訪問父類的方法。 調用父類構造方法。 訪問父類中的隱藏成員變量。
    的頭像 發表于 02-21 15:08 ?547次閱讀

    Java枚舉的特點及用法

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

    Java時間類轉換方案

    LocalDate 的過程中,我們使用 Date 類中在 Java 8 新增的 toInstant() 方法進行轉換。 當我們轉換一個 Instant 對象時,需要使用 ZoneId,因為 Instant 對象是不分時區的--
    的頭像 發表于 10-09 15:48 ?469次閱讀

    java 8的日期用法

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

    this關鍵字在Java中的用法

    this 關鍵字只能在方法內部使用,表示對“調用方法的那個對象”的引用。 其實簡單來說 this 關鍵字就是表示當前對象,下面我們來具體介紹 this 關鍵字在Java中的用法。 1、調用成員變量
    的頭像 發表于 10-10 16:49 ?548次閱讀
    this關鍵字在<b class='flag-5'>Java</b>中的<b class='flag-5'>用法</b>

    java中obj類型的實戰用法

    類型具有許多實戰用法,下面將詳細介紹一些常見的使用場景。 作為方法參數和返回值的類型 在Java中,可以使用obj類型作為方法的參數或返回值類型。這種用法可以使方法具有更廣泛的適用性,因為obj類型可以接受任何對象作為參數或返回
    的頭像 發表于 11-21 10:27 ?729次閱讀