真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何進(jìn)行ImmutableList的原理分析

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)如何進(jìn)行Immutable List的原理分析,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、花都ssl等。為上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的花都網(wǎng)站制作公司

Immutable List,顧名思義,就是,啥,不明白 Immutable 是什么意思?一成不變的意思,所以 Immutable List 就是一個不可變的 List 類,這意味著該 List 聲明后,它的內(nèi)容就是固定的,不可增刪改的。

如果對不可變類比較陌生的話,可以先點(diǎn)擊下面的鏈接查看我之前寫的另外一篇文章。

這次要說不明白immutable類,我就怎么地

如果嘗試對 List 中的元素進(jìn)行增加、刪除或者更新,就會拋出 UnsupportedOperationException 異常。

另外,Immutable List 中的元素是非 null 的,如果使用 null 來創(chuàng)建 Immutable List,則會拋出 NullPointerException;如果嘗試在 Immutable List 中添加 null 元素,則會拋出 UnsupportedOperationException。

那 Immutable List 有什么好處呢?

  • 它是線程安全的;

  • 它是高效的;

  • 因?yàn)樗遣豢勺兊?,就可以?String 一樣傳遞給第三方類庫,不會發(fā)生任何安全問題。

那接下來,我們來看一下,如何創(chuàng)建 Immutable List。注意,源碼是基于 JDK14 的。

 

01、借助原生 JDK

Collections 類的 unmodifiableList() 方法可以創(chuàng)建一個類似于 Immutable List 的 UnmodifiableList 或者 UnmodifiableRandomAccessList,都是不可修改的。

public static  List unmodifiableList(List list) {
    return (list instanceof RandomAccess ?
            new Collections.UnmodifiableRandomAccessList<>(list) :
            new Collections.UnmodifiableList<>(list));
}
 

來看一下使用方法:

List list = new ArrayList<>(Arrays.asList("沉默王二", "沉默王三", "沉默王四"));
List unmodifiableList = Collections.unmodifiableList(list);
 

我們嘗試往 unmodifiableList 中添加元素“沉默王五”:

unmodifiableList.add("沉默王五");
 

運(yùn)行后會拋出 UnsupportedOperationException 異常:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.Collections$UnmodifiableCollection.add(Collections.java:1062)
    at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:16)
   

02、借助 Java 9

Java 9 的時候,List 類新增了一個 of() 靜態(tài)工廠方法,可以用來創(chuàng)建不可變的 List。先來看一下源碼:

static  List of(E e1, E e2, E e3) {
    return new ImmutableCollections.ListN<>(e1, e2, e3);
}
 

of() 方法有很多變體,比如說:

static  List of(E e1) {
        return new ImmutableCollections.List12<>(e1);
    }
static  List of(E e1, E e2) {
        return new ImmutableCollections.List12<>(e1, e2);
    }
static  List of(E e1, E e2, E e3, E e4) {
    return new ImmutableCollections.ListN<>(e1, e2, e3, e4);
}
static  List of(E e1, E e2, E e3, E e4, E e5) {
    return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5);
}
static  List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
    return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
            e6, e7, e8, e9, e10);
}
 

該方法的設(shè)計(jì)者也挺有意思的,of() 方法的參數(shù),從 0 到 10 都有一個相同簽名的重載方法。

甚至當(dāng)參數(shù)是可變的時候,使用 switch 語句對參數(shù)的個數(shù)進(jìn)行了判斷,然后調(diào)用不同的重載方法:

static  List of(E... elements) {
    switch (elements.length) { // implicit null check of elements
        case 0:
            @SuppressWarnings("unchecked")
            var list = (List) ImmutableCollections.ListN.EMPTY_LIST;
            return list;
        case 1:
            return new ImmutableCollections.List12<>(elements[0]);
        case 2:
            return new ImmutableCollections.List12<>(elements[0], elements[1]);
        default:
            return new ImmutableCollections.ListN<>(elements);
    }
}
 

不管是 ImmutableCollections.List12 還是 ImmutableCollections.ListN,它們都是 final 的,并且繼承了 AbstractImmutableList,里面的元素也是 final 的。

static final class List12 extends ImmutableCollections.AbstractImmutableList
        implements Serializable {

    @Stable
    private final E e0;

    @Stable
    private final E e1;
}

static final class ListN extends ImmutableCollections.AbstractImmutableList
        implements Serializable {

    // EMPTY_LIST may be initialized from the CDS archive.
    static @Stable List EMPTY_LIST;

    static {
        VM.initializeFromArchive(ImmutableCollections.ListN.class);
        if (EMPTY_LIST == null) {
            EMPTY_LIST = new ImmutableCollections.ListN<>();
        }
    }

    @Stable
    private final E[] elements;
}
 

好了,來看一下使用方法吧:

final List unmodifiableList = List.of("沉默王二", "沉默王三", "沉默王四");
unmodifiableList.add("沉默王五");
 

ImmutableCollections 的內(nèi)部類 ListN 或者 List12 同樣不可修改,使用 add() 方法添加元素同樣會在運(yùn)行時拋出異常:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:73)
    at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:77)
    at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:20)
   

03、借助 Guava

Guava 工程包含了若干被 Google 的 Java 項(xiàng)目廣泛依賴的核心庫,例如:集合 [collections] 、緩存 [caching] 、原生類型支持 [primitives support] 、并發(fā)庫 [concurrency libraries] 、通用注解 [common annotations] 、字符串處理 [string processing] 、I/O 等等。所有這些工具每天都在被 Google 的工程師應(yīng)用在產(chǎn)品服務(wù)中。

在實(shí)際的項(xiàng)目實(shí)戰(zhàn)當(dāng)中,Guava 類庫的使用頻率真的蠻高的,因此我們需要在項(xiàng)目中先引入 Guava 的 Maven 依賴。


    com.google.guava
    guava
    28.1-jre

 

Guava 定了一個 ImmutableList 類,它的聲明方式如下所示:

@GwtCompatible(serializable = true, emulated = true)
@SuppressWarnings("serial") // we're overriding default serialization
public abstract class ImmutableList extends ImmutableCollection
    implements List, RandomAccess {
}
 

它的類結(jié)構(gòu)關(guān)系如下所示:

java.lang.Object
  ? java.util.AbstractCollection
      ? com.google.common.collect.ImmutableCollection
          ? com.google.common.collect.ImmutableList
 

ImmutableList 類的 copyOf() 方法可用于創(chuàng)建一個不可變的 List 對象:

List list = new ArrayList<>(Arrays.asList("沉默王二", "沉默王三", "沉默王四"));
List unmodifiableList = ImmutableList.copyOf(list);
unmodifiableList.add("沉默王五");
 

ImmutableList 同樣不允許添加元素,add() 方法在執(zhí)行的時候會拋出 UnsupportedOperationException 異常:

Exception in thread "main" java.lang.UnsupportedOperationException
    at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:244)
    at com.cmower.mkyong.immutablelist.ImmutableListDemo.main(ImmutableListDemo.java:25)
 

ImmutableList 類的 of() 方法和 Java 9 的 of() 方法類似,同樣有很多相同簽名的重載方法,使用方法也完全類似:

List unmodifiableList = ImmutableList.of("沉默王二", "沉默王三", "沉默王四");
 

ImmutableList 類還提供了 builder 模式,既可以在創(chuàng)建的時候添加元素,也可以基于已有的 List 創(chuàng)建,還可以將兩者混合在一起。

ImmutableList iList = ImmutableList.builder()
        .add("沉默王二", "沉默王三", "沉默王四")
        .build();

List list = List.of("沉默王二", "沉默王三", "沉默王四");
ImmutableList iList = ImmutableList.builder()
        .addAll(list)
        .build();

List list = List.of("沉默王二", "沉默王三", "沉默王四");
ImmutableList iList = ImmutableList.builder()
        .addAll(list)
        .add("沉默王五")
        .build();
   

04、Collections.unmodifiableList() 和 ImmutableList 有什么區(qū)別?

Collections.unmodifiableList() 基于原有的 List 創(chuàng)建了一個不可變的包裝器,該包裝器是不可修改的,但是,我們可以通過對原有的 List 進(jìn)行修改,從而影響到包裝器,來看下面的示例:

List list = new ArrayList<>();
list.add("沉默王二");

List iList = Collections.unmodifiableList(list);

list.add("沉默王三");
list.add("沉默王四");

System.out.println(iList);
 

程序輸出的結(jié)果如下所示:

[沉默王二, 沉默王三, 沉默王四]
 

但如果我們通過 ImmutableList 類創(chuàng)建一個不可變 List,原有 List 的改變并不會影響到 ImmutableList。

List list = new ArrayList<>();
list.add("沉默王二");

ImmutableList iList = ImmutableList.copyOf(list);

list.add("沉默王三");
list.add("沉默王四");

System.out.println(iList);
 

程序輸出的結(jié)果如下所示:

[沉默王二]
 

這是因?yàn)?ImmutableList 是在原有的 List 上進(jìn)行了拷貝。

上述就是小編為大家分享的如何進(jìn)行Immutable List的原理分析了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


名稱欄目:如何進(jìn)行ImmutableList的原理分析
網(wǎng)頁路徑:http://weahome.cn/article/piepis.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部