最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中實現(xiàn)不可變集合的不同方式詳解

 更新時間:2025年06月03日 09:18:54   作者:酷愛碼  
這篇文章主要為大家詳細(xì)介紹了Java中實現(xiàn)不可變集合的不同方式,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、不可變集合的核心價值

不可變集合(Immutable Collections)指一旦創(chuàng)建后,其內(nèi)容就無法被修改的集合對象。這種設(shè)計在Java開發(fā)中具有三大核心優(yōu)勢:

  • 線程安全性:無需同步鎖即可在多線程環(huán)境下共享
  • 防御性編程:防止外部意外修改內(nèi)部數(shù)據(jù)
  • 性能優(yōu)化:哈希值等元數(shù)據(jù)只需計算一次
  • 代碼可預(yù)測性:集合狀態(tài)在生命周期內(nèi)保持恒定

二、傳統(tǒng)實現(xiàn):Collections.unmodifiableXXX

在Java 9之前,我們通過工具類創(chuàng)建不可變視圖:

List<String> mutableList = new ArrayList<>(Arrays.asList("A", "B"));
List<String> unmodifiable = Collections.unmodifiableList(mutableList);

// 嘗試修改將拋出異常
unmodifiable.add("C"); // UnsupportedOperationException

// 但原始集合修改會影響"不可變"視圖
mutableList.add("C"); 
System.out.println(unmodifiable); // 輸出[A, B, C]  ? 實際已改變

致命缺陷:這僅是原集合的視圖包裝器,原集合修改會導(dǎo)致視圖內(nèi)容變化,并非真正不可變。

三、Java 9+ 的工廠方法

Java 9引入全新的不可變集合API,通過of()工廠方法創(chuàng)建真正不可變集合:

List<String> immutableList = List.of("Java", "Kotlin", "Scala");
Set<Integer> immutableSet = Set.of(1, 2, 3);
Map<String, Integer> immutableMap = Map.of("One", 1, "Two", 2);

// 所有修改操作均拋出異常
immutableList.add("Go");  // UnsupportedOperationException
immutableSet.remove(1);   // UnsupportedOperationException

實現(xiàn)特點:

  • 深度不可變:與原集合完全隔離
  • 空間優(yōu)化:根據(jù)元素數(shù)量選擇最優(yōu)內(nèi)部存儲結(jié)構(gòu)
  • 元素限制:禁止null元素(避免NPE歧義)
  • 快速失?。褐貜?fù)元素會立即拋出IllegalArgumentException

四、Guava的不可變集合

Google Guava庫提供了更靈活的創(chuàng)建方式:

// 構(gòu)建器模式
ImmutableList<String> list = ImmutableList.<String>builder()
    .add("Spring")
    .addAll(existingList)
    .build();

// 工廠方法
ImmutableSet<Integer> set = ImmutableSet.copyOf(mutableSet);
ImmutableMap<String, Integer> map = ImmutableMap.of("key1", 1, "key2", 2);

// 拒絕null值
ImmutableList.of(null); // 立即拋出NullPointerException

進階特性:

智能copyOf():若參數(shù)已不可變則直接返回原引用

嚴(yán)格的空值檢查:所有元素在創(chuàng)建時進行非空驗證

有序集合:ImmutableSortedSet自動維護排序

五、實現(xiàn)原理剖析

存儲結(jié)構(gòu):

// Java 10的ImmutableCollections實現(xiàn)
static final class ListN<E> extends AbstractImmutableList<E> {
    private final E[] elements; // 使用final數(shù)組存儲
}

寫操作攔截:

public void add(int index, E element) {
    throw new UnsupportedOperationException();
}

防御性拷貝:

static <E> List<E> listCopy(Collection<? extends E> coll) {
    return coll.isEmpty() ? List.of() 
        : new ImmutableCollections.ListN<>(coll.toArray());
}

六、最佳實踐與注意事項

適用場景:

  • 配置數(shù)據(jù):如國家代碼列表
  • API返回結(jié)果:保證客戶端無法修改
  • 多線程共享數(shù)據(jù):替代同步集合
  • 緩存鍵值:因哈希值穩(wěn)定

性能考量:

  • 創(chuàng)建開銷:初始化時需完整拷貝(Guava的copyOf()有優(yōu)化)
  • 內(nèi)存占用:小集合有存儲結(jié)構(gòu)優(yōu)化
  • 遍歷速度:比同步集合快5-10倍(基準(zhǔn)測試數(shù)據(jù))

重要限制:

// 1. 元素對象本身仍可變
List<Date> dates = List.of(new Date());
dates.get(0).setTime(0); // 成功修改日期對象

// 2. 大集合創(chuàng)建
Set.of(...); // 超過16元素需改用Map.ofEntries()

七、方法補充

1.代碼實現(xiàn)(List)

先創(chuàng)建List集合,此處調(diào)用靜態(tài)方法List.of來創(chuàng)建一個不可變的List集合,以及調(diào)用其常見的遍歷方法進行遍歷:

import java.util.Iterator;
import java.util.List;

public class ImmutableDemo1 {
    public static void main(String[] args) {
        /**
         * 創(chuàng)建不可變的List集合
         * "張三","李四","王五","趙六"
         */

        //一旦創(chuàng)建完畢之后,是無法進行修改的,在下面的代碼中,只能進行查詢操作
        List<String> list = List.of("張三", "李四", "王五", "趙六");

        //用list調(diào)用get方法
        System.out.println(list.get(0));
        System.out.println(list.get(1));
        System.out.println(list.get(2));
        System.out.println(list.get(3));

		//增強for遍歷
        for (String s : list) {
            System.out.println(s);
        }

        //迭代器遍歷
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        //lambda表達(dá)式遍歷
        list.forEach( s -> System.out.println(s));

        //方法引用遍歷
        list.forEach(System.out::println);
        
		
    }
}

代碼運行結(jié)果如下(五種遍歷方式結(jié)果相同):

張三
李四
王五
趙六

此時,我們在上述代碼中添加方法來修改集合中的元素

list.set(0,"aaa");
list.add("zzz");
list.remove("張三");

運行結(jié)果報錯如下:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
    at java.base/java.util.ImmutableCollections$AbstractImmutableList.set(ImmutableCollections.java:260)
    at ImmutableDemo1.main(ImmutableDemo1.java:38)

此處報錯很明顯是因為我們創(chuàng)建的list集合是一個靜態(tài)集合,靜態(tài)集合中的元素是不可以被改變的。

2.代碼實現(xiàn)(Set)

創(chuàng)建方法與上面的List集合大同小異,代碼如下:

import java.util.Iterator;
import java.util.Set;

public class ImmutableDemo2 {
    public static void main(String[] args) {
        /**
         * 創(chuàng)建不可變的Set集合
         * "張三","李四","王五","趙六"
         */

        //一旦創(chuàng)建完畢之后,是無法進行修改的,在下面的代碼中,只能進行查詢操作
        Set<String> set = Set.of("張三","李四","王五","趙六");


        //增強for遍歷
        for (String s : set) {
            System.out.println(s);
        }

        //迭代器遍歷
        Iterator<String> it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        //lambda表達(dá)式遍歷
        set.forEach( s -> System.out.println(s));

        //方法引用遍歷
        set.forEach(System.out::println);
    }
}

代碼運行結(jié)果如下:

趙六
張三
王五
李四

同樣使用remove,add方法:

set.remove("王五");
set.add("aaa");

運行結(jié)果如下:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
    at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.remove(ImmutableCollections.java:150)
    at ImmutableDemo2.main(ImmutableDemo2.java:32)

此處,上述方法同樣不能修改Set集合中的元素。

值得一提的是,Set集合中元素是唯一的,故Set不可變集合中元素不能重復(fù):

Set<String> set = Set.of("張三","李四","王五","趙六","趙六"); 
//此處我們創(chuàng)建了一個帶有重復(fù)元素的Set集合,重復(fù)元素為趙六

代碼運行結(jié)果如下:

Exception in thread "main" java.lang.IllegalArgumentException: duplicate element: 趙六
    at java.base/java.util.ImmutableCollections$SetN.<init>(ImmutableCollections.java:918)
    at java.base/java.util.Set.of(Set.java:544)
    at ImmutableDemo2.main(ImmutableDemo2.java:13)

如上文:因為Set集合中出現(xiàn)了兩個一樣的“趙六”,故報錯,所以當(dāng)我們使用Set不可變集合的時候,我們要確保Set集合中元素的唯一性。

3.代碼實現(xiàn)(Map)

創(chuàng)建方式以及其遍歷方式如下:

import java.util.Map;
import java.util.Set;

public class ImmutableDemo3 {
    public static void main(String[] args) {
        /**
         * 創(chuàng)建不可變的Map集合
         *
         * "張三","南京","李四","北京","王五","上海","趙六","廣州"
         */
        //一旦創(chuàng)建完畢之后,是無法進行修改的,在下面的代碼中,只能進行查詢操作
        Map<String, String> map = Map.of("張三", "南京", "李四", "北京", "王五", "上海", "趙六", "廣州");


        Set<String> keys = map.keySet();

        //增強for遍歷
        for (String key : keys) {
            String value = map.get(key);
            System.out.println(key + "=" + value);
        }

        //entrySet方法遍歷
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "=" + value);
        }
    }
}

運行結(jié)果如下:

李四=北京
趙六=廣州
張三=南京
王五=上海
==========================
李四=北京
趙六=廣州
張三=南京
王五=上海

八、總結(jié)

Java中實現(xiàn)不可變集合的三種核心方式各有適用場景:

實現(xiàn)方式版本要求是否深度不可變空值支持
Collections.unmodifiableJava 1.2?(視圖包裝)允許
List/Set/Map.of()Java 9+?禁止
Guava ImmutableXXXJava 6+?禁止

現(xiàn)代Java開發(fā)建議:

  • 優(yōu)先使用List.of()/Set.of()等內(nèi)置方法
  • 需要復(fù)雜構(gòu)造時選擇Guava構(gòu)建器
  • 涉及遺留代碼時用Collections.unmodifiableXXX+深度拷貝
  • 超大數(shù)據(jù)集考慮ImmutableCollections的子類化擴展

不可變集合通過約束可變性換取安全性與性能,已成為高并發(fā)系統(tǒng)和函數(shù)式編程的基石。合理運用可使系統(tǒng)減少30%以上的同步代碼(實際項目統(tǒng)計),同時顯著降低數(shù)據(jù)異常風(fēng)險。

到此這篇關(guān)于Java中實現(xiàn)不可變集合的不同方式詳解的文章就介紹到這了,更多相關(guān)Java不可變集合內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 運行時常量池和字符串常量池的區(qū)別及說明

    運行時常量池和字符串常量池的區(qū)別及說明

    這篇文章主要介紹了運行時常量池和字符串常量池的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • JAVA8 stream中三個參數(shù)的reduce方法對List進行分組統(tǒng)計操作

    JAVA8 stream中三個參數(shù)的reduce方法對List進行分組統(tǒng)計操作

    這篇文章主要介紹了JAVA8 stream中三個參數(shù)的reduce方法對List進行分組統(tǒng)計操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Java之Set?交集,差集,并集的用法

    Java之Set?交集,差集,并集的用法

    這篇文章主要介紹了Java之Set?交集,差集,并集的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 淺談MyBatis通用Mapper實現(xiàn)原理

    淺談MyBatis通用Mapper實現(xiàn)原理

    這篇文章主要介紹了淺談MyBatis通用Mapper實現(xiàn)原理,本文會先介紹通用 Mapper 的簡單原理,然后使用最簡單的代碼來實現(xiàn)這個過程。感興趣的小伙伴們可以參考一下
    2018-10-10
  • Java利用VLC開發(fā)簡易視屏播放器功能

    Java利用VLC開發(fā)簡易視屏播放器功能

    這篇文章主要介紹了Java利用VLC開發(fā)簡易視屏播放器,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • HarmonyOS實現(xiàn)Java端類似Nine-Patch氣泡聊天框代碼

    HarmonyOS實現(xiàn)Java端類似Nine-Patch氣泡聊天框代碼

    在HarmonyOS Java端實現(xiàn)氣泡聊天框,與Android 上的9圖(Nine-Patch)有相似的實現(xiàn)方式,在HarmonyOS中,可以使用ShapeElement和ElementContainer來創(chuàng)建和管理可伸縮的氣泡背景,下面提供一個簡單的示例代碼,可以在 HarmonyOS 中實現(xiàn)類似于Android的Nine-Patch氣泡聊天框效果
    2024-07-07
  • Java 中的Function.identity()實現(xiàn)原理解析

    Java 中的Function.identity()實現(xiàn)原理解析

    Function.identity()是Java 8 引入的一個靜態(tài)方法,屬于 java.util.function.Function 函數(shù)式接口,這篇文章主要介紹了Java 中的Function.identity()實現(xiàn)原理,需要的朋友可以參考下
    2025-08-08
  • Spring開發(fā)中自定義注解的使用詳解

    Spring開發(fā)中自定義注解的使用詳解

    這篇文章主要介紹了Spring開發(fā)中自定義注解的使用詳解,在Java項目中,可以自定義注解,方便進行某些處理操作,提供開發(fā)效率,需要的朋友可以參考下
    2024-01-01
  • Java中Set集合遍歷的四種方法實現(xiàn)

    Java中Set集合遍歷的四種方法實現(xiàn)

    本文主要介紹了Java中Set集合遍歷的四種方法實現(xiàn),包括迭代器遍歷、增強型for循環(huán)遍歷、Stream API遍歷以及TreeSet的有序遍歷,具有一定的參考價值,感興趣的可以了解一下
    2025-05-05
  • 解決springboot啟動失敗的問題('hibernate.dialect'?not?set)

    解決springboot啟動失敗的問題('hibernate.dialect'?not?set)

    這篇文章主要介紹了解決springboot啟動失敗的問題('hibernate.dialect'?not?set),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論

乐平市| 平罗县| 仙居县| 赤城县| 江阴市| 柘荣县| 邵东县| 合水县| 屯门区| 永和县| 临江市| 太和县| 芜湖县| 兴化市| 乌兰察布市| 北宁市| 河曲县| 白沙| 巩留县| 清徐县| 玛曲县| 金阳县| 宜城市| 临江市| 彰化县| 佛山市| 北安市| 乾安县| 博客| 江川县| 博白县| 潍坊市| 穆棱市| 新宾| 云浮市| 抚松县| 千阳县| 奇台县| 永城市| 荆门市| 应用必备|