欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?Multimap實(shí)現(xiàn)類與操作的具體示例

 更新時(shí)間:2025年06月09日 11:17:24   作者:A-angular  
Multimap出現(xiàn)在Google的Guava庫(kù)中,它為Java提供了更加靈活的集合操作,這篇文章主要介紹了Java?Multimap實(shí)現(xiàn)類與操作的具體示例,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、Multimap 概述

Multimap 是 Google Guava 庫(kù)中提供的一種集合類型,它擴(kuò)展了傳統(tǒng)的 Map 概念,允許一個(gè)鍵對(duì)應(yīng)多個(gè)值。與標(biāo)準(zhǔn)的 Map<K, List<V>> 或 Map<K, Set<V>> 相比,Multimap 提供了更簡(jiǎn)潔的 API 和更強(qiáng)大的功能。

Multimap 主要特點(diǎn):

  • 一個(gè)鍵可以映射到多個(gè)值
  • 避免了手動(dòng)管理值集合的麻煩
  • 提供了豐富的視圖集合
  • 支持不可變實(shí)現(xiàn)

二、Multimap 實(shí)現(xiàn)類

Guava 提供了多種 Multimap 實(shí)現(xiàn),每種實(shí)現(xiàn)都有不同的特性和使用場(chǎng)景。

1. ListMultimap 系列

特點(diǎn):值以 List 形式存儲(chǔ),允許重復(fù)值,保留插入順序

實(shí)現(xiàn)類描述是否線程安全
ArrayListMultimap使用 ArrayList 作為值集合
LinkedListMultimap使用 LinkedList 作為值集合
ImmutableListMultimap不可變實(shí)現(xiàn)

2. SetMultimap 系列

特點(diǎn):值以 Set 形式存儲(chǔ),不允許重復(fù)值

實(shí)現(xiàn)類描述是否線程安全
HashMultimap使用 HashSet 作為值集合
LinkedHashMultimap使用 LinkedHashSet 作為值集合,保留插入順序
TreeMultimap使用 TreeSet 作為值集合,按鍵和值排序
ImmutableSetMultimap不可變實(shí)現(xiàn)

3. 其他實(shí)現(xiàn)

實(shí)現(xiàn)類描述是否線程安全
Multimaps.synchronizedMultimap同步包裝器,使任何 Multimap 線程安全
Multimaps.unmodifiableMultimap不可修改視圖

三、Multimap 基本操作示例

1. 創(chuàng)建 Multimap

// 創(chuàng)建ArrayListMultimap
ListMultimap<String, String> listMultimap = ArrayListMultimap.create();

// 創(chuàng)建HashMultimap
SetMultimap<String, Integer> setMultimap = HashMultimap.create();

// 創(chuàng)建不可變Multimap
ImmutableListMultimap<String, String> immutableMultimap = ImmutableListMultimap.of(
    "key1", "value1",
    "key1", "value2",
    "key2", "value3"
);

2. 添加元素

ListMultimap<String, String> multimap = ArrayListMultimap.create();

// 添加單個(gè)元素
multimap.put("fruit", "apple");
multimap.put("fruit", "banana");
multimap.put("fruit", "orange");
multimap.put("vegetable", "carrot");

// 添加多個(gè)元素
multimap.putAll("fruit", Arrays.asList("pear", "grape"));
multimap.putAll("vegetable", Arrays.asList("potato", "tomato"));

3. 獲取元素

// 獲取某個(gè)鍵的所有值
List<String> fruits = multimap.get("fruit"); // [apple, banana, orange, pear, grape]

// 獲取第一個(gè)值
String firstFruit = multimap.get("fruit").get(0); // apple

// 檢查鍵是否存在
boolean hasFruit = multimap.containsKey("fruit"); // true

// 檢查鍵值對(duì)是否存在
boolean hasApple = multimap.containsEntry("fruit", "apple"); // true

4. 刪除元素

// 刪除鍵的所有值
multimap.removeAll("fruit"); // 返回被刪除的值列表

// 刪除特定鍵值對(duì)
multimap.remove("vegetable", "tomato"); // 返回boolean表示是否刪除成功

// 清空所有元素
multimap.clear();

5. 視圖操作

// 獲取所有鍵的集合(去重)
Set<String> keys = multimap.keySet();

// 獲取所有值的集合(不去重)
Collection<String> values = multimap.values();

// 獲取鍵值對(duì)集合
Collection<Map.Entry<String, String>> entries = multimap.entries();

// 將Multimap轉(zhuǎn)換為Map<K, Collection<V>>
Map<String, Collection<String>> mapView = multimap.asMap();

四、不同實(shí)現(xiàn)類的具體示例

1. ArrayListMultimap 示例

// 創(chuàng)建ArrayListMultimap
ListMultimap<String, Integer> scores = ArrayListMultimap.create();

// 添加元素
scores.put("Alice", 90);
scores.put("Alice", 85);
scores.put("Bob", 75);
scores.put("Bob", 80);
scores.put("Bob", 82);

// 獲取元素
List<Integer> aliceScores = scores.get("Alice"); // [90, 85]
List<Integer> bobScores = scores.get("Bob"); // [75, 80, 82]

// 允許重復(fù)值
scores.put("Alice", 90);
List<Integer> newAliceScores = scores.get("Alice"); // [90, 85, 90]

2. HashMultimap 示例

// 創(chuàng)建HashMultimap
SetMultimap<String, String> tags = HashMultimap.create();

// 添加元素
tags.put("article1", "tech");
tags.put("article1", "java");
tags.put("article1", "programming");
tags.put("article2", "design");
tags.put("article2", "ui");

// 嘗試添加重復(fù)值
tags.put("article1", "java"); // 不會(huì)有任何效果

// 獲取元素
Set<String> article1Tags = tags.get("article1"); // [tech, java, programming]
Set<String> article2Tags = tags.get("article2"); // [design, ui]

3. TreeMultimap 示例

// 創(chuàng)建TreeMultimap(按鍵和值排序)
TreeMultimap<String, Integer> sortedScores = TreeMultimap.create();

// 添加元素(亂序)
sortedScores.put("Bob", 80);
sortedScores.put("Alice", 90);
sortedScores.put("Bob", 75);
sortedScores.put("Alice", 85);

// 獲取元素(自動(dòng)排序)
SortedSet<Integer> aliceSortedScores = sortedScores.get("Alice"); // [85, 90]
SortedSet<Integer> bobSortedScores = sortedScores.get("Bob"); // [75, 80]

// 整個(gè)Multimap也是按鍵排序的
System.out.println(sortedScores); // {Alice=[85, 90], Bob=[75, 80]}

4. ImmutableListMultimap 示例

// 創(chuàng)建不可變Multimap
ImmutableListMultimap<String, String> immutableMap = ImmutableListMultimap.<String, String>builder()
    .put("colors", "red")
    .put("colors", "green")
    .put("colors", "blue")
    .put("shapes", "circle")
    .put("shapes", "square")
    .build();

// 嘗試修改會(huì)拋出UnsupportedOperationException
// immutableMap.put("colors", "yellow"); // 錯(cuò)誤!

// 安全地獲取數(shù)據(jù)
List<String> colors = immutableMap.get("colors"); // [red, green, blue]

五、高級(jí)操作與工具方法

1. 使用 Multimaps 工具類

// 從Map<K, Collection<V>>創(chuàng)建Multimap
Map<String, List<Integer>> map = new HashMap<>();
map.put("a", Arrays.asList(1, 2, 3));
map.put("b", Arrays.asList(4, 5));
ListMultimap<String, Integer> multimap = Multimaps.forMap(map);

// 轉(zhuǎn)換Multimap的值類型
ListMultimap<String, String> stringMultimap = ArrayListMultimap.create();
stringMultimap.put("key", "1");
stringMultimap.put("key", "2");
ListMultimap<String, Integer> intMultimap = Multimaps.transformValues(stringMultimap, Integer::valueOf);

// 反轉(zhuǎn)Multimap(鍵值互換)
SetMultimap<Integer, String> inverted = Multimaps.invertFrom(stringMultimap, HashMultimap.create());

2. 過(guò)濾操作

ListMultimap<String, Integer> scores = ArrayListMultimap.create();
scores.put("Alice", 90);
scores.put("Alice", 85);
scores.put("Bob", 75);
scores.put("Bob", 80);

// 過(guò)濾出分?jǐn)?shù)大于80的條目
Multimap<String, Integer> highScores = Multimaps.filterEntries(scores, 
    entry -> entry.getValue() > 80);

System.out.println(highScores); // {Alice=[90, 85]}

3. 同步包裝

ListMultimap<String, String> unsafeMultimap = ArrayListMultimap.create();

// 創(chuàng)建線程安全版本
ListMultimap<String, String> safeMultimap = Multimaps.synchronizedListMultimap(unsafeMultimap);

// 現(xiàn)在可以安全地在多線程環(huán)境中使用
safeMultimap.put("key", "value");

六、性能比較與選擇指南

實(shí)現(xiàn)類鍵存儲(chǔ)值存儲(chǔ)允許重復(fù)值順序保證典型用途
ArrayListMultimapHashMapArrayList插入順序需要保留插入順序且允許重復(fù)值的場(chǎng)景
LinkedListMultimapLinkedHashMapLinkedList插入順序需要頻繁在中間插入/刪除的場(chǎng)景
HashMultimapHashMapHashSet無(wú)需要快速查找且不需要重復(fù)值的場(chǎng)景
LinkedHashMultimapLinkedHashMapLinkedHashSet插入順序需要保留插入順序且不允許重復(fù)值的場(chǎng)景
TreeMultimapTreeMapTreeSet排序順序需要按鍵和值排序的場(chǎng)景
ImmutableListMultimap不可變不可變構(gòu)造順序需要不可變集合的場(chǎng)景
ImmutableSetMultimap不可變不可變構(gòu)造順序需要不可變集合且不允許重復(fù)值的場(chǎng)景

選擇建議

  • 如果需要允許重復(fù)值 - 選擇 ListMultimap 實(shí)現(xiàn)
  • 如果需要快速查找且不允許重復(fù)值 - 選擇 SetMultimap 實(shí)現(xiàn)
  • 如果需要排序功能 - 選擇 TreeMultimap
  • 如果需要線程安全 - 使用不可變實(shí)現(xiàn)或同步包裝器
  • 如果數(shù)據(jù)不常變化 - 優(yōu)先考慮不可變實(shí)現(xiàn)

七、常見問(wèn)題解答

Q1: Multimap 和 Map<K, List> 有什么區(qū)別?

A1: 主要區(qū)別在于:

  • Multimap 提供了更簡(jiǎn)潔的 API,不需要手動(dòng)管理值集合
  • Multimap 提供了豐富的視圖方法(如 entries(), keys(), values())
  • Multimap 隱藏了實(shí)現(xiàn)細(xì)節(jié),可以更靈活地切換底層實(shí)現(xiàn)
  • Multimap 的方法更直觀,如 put() 直接添加元素而不需要先檢查是否存在集合

Q2: 如何將 Multimap 轉(zhuǎn)換為傳統(tǒng)的 Map?

A2: 可以使用 asMap() 方法:

ListMultimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("key", "value1");
multimap.put("key", "value2");

Map<String, Collection<String>> map = multimap.asMap();

Q3: Multimap 是線程安全的嗎?

A3: 大多數(shù) Multimap 實(shí)現(xiàn)不是線程安全的,除了:

  • 不可變實(shí)現(xiàn)(ImmutableListMultimap, ImmutableSetMultimap)
  • 使用 Multimaps.synchronizedMultimap() 包裝的 Multimap

Q4: 如何統(tǒng)計(jì) Multimap 中每個(gè)鍵對(duì)應(yīng)的值數(shù)量?

A4: 可以使用 Multimap 的 keys() 方法結(jié)合 Multisets:

ListMultimap<String, String> multimap = ArrayListMultimap.create();
// 添加元素...

Multiset<String> counts = HashMultiset.create(multimap.keys());
System.out.println(counts); // 顯示每個(gè)鍵的出現(xiàn)次數(shù)

八、總結(jié)

Guava 的 Multimap 提供了一種優(yōu)雅的方式來(lái)處理鍵到多個(gè)值的映射關(guān)系,比傳統(tǒng)的 Map<K, Collection<V>> 更加方便和強(qiáng)大。通過(guò)選擇合適的實(shí)現(xiàn)類,可以滿足各種不同的業(yè)務(wù)需求,包括是否需要允許重復(fù)值、是否需要保持順序、是否需要排序等功能。

在實(shí)際開發(fā)中,Multimap 特別適用于以下場(chǎng)景:

  • 標(biāo)簽系統(tǒng)(一個(gè)項(xiàng)目有多個(gè)標(biāo)簽)
  • 學(xué)生成績(jī)記錄(一個(gè)學(xué)生有多門成績(jī))
  • 反向索引(一個(gè)單詞出現(xiàn)在多個(gè)文檔中)
  • 分組統(tǒng)計(jì)(按類別分組記錄)

掌握 Multimap 的使用可以顯著簡(jiǎn)化代碼,提高開發(fā)效率,是 Java 開發(fā)者工具箱中不可或缺的工具之一。

到此這篇關(guān)于Java Multimap實(shí)現(xiàn)類與操作具體示例的文章就介紹到這了,更多相關(guān)Java Multimap類操作示例內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java序列化和反序列化示例介紹

    Java序列化和反序列化示例介紹

    大家好,本篇文章主要講的是Java序列化和反序列化示例介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • Java中的鎖分類的詳細(xì)介紹

    Java中的鎖分類的詳細(xì)介紹

    這篇文章主要介紹了Java中的鎖分類的詳細(xì)介紹,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解

    Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解

    這篇文章主要介紹了Spring核心容器之ApplicationContext上下文啟動(dòng)準(zhǔn)備詳解,ApplicationContext 繼承自 BeanFactory ,其不僅包含 BeanFactory 所有功能,還擴(kuò)展了容器功能,需要的朋友可以參考下
    2023-11-11
  • Java 8對(duì)LinkedHashSet元素進(jìn)行排序的操作方法

    Java 8對(duì)LinkedHashSet元素進(jìn)行排序的操作方法

    LinkedHashSet 是 Java 集合框架中的一個(gè)類,它繼承自 HashSet,并實(shí)現(xiàn)了 Set 接口,然而,LinkedHashSet 不支持元素的排序,它僅僅保持插入順序,所以本文給大家介紹了Java 8 如何對(duì) LinkedHashSet 元素進(jìn)行排序,需要的朋友可以參考下
    2024-11-11
  • IDEA?2022?中的Lombok?使用基礎(chǔ)教程

    IDEA?2022?中的Lombok?使用基礎(chǔ)教程

    ? Lombok是使用java編寫的一款開源類庫(kù)。其主作用是使用注解來(lái)代替一些具有格式固定,沒(méi)有過(guò)多技術(shù)含量的編碼工作,這篇文章主要介紹了IDEA?2022?中的Lombok?使用基礎(chǔ)教程,需要的朋友可以參考下
    2022-12-12
  • IDEA實(shí)現(xiàn)遠(yuǎn)程調(diào)試步驟詳解

    IDEA實(shí)現(xiàn)遠(yuǎn)程調(diào)試步驟詳解

    這篇文章主要介紹了IDEA實(shí)現(xiàn)遠(yuǎn)程調(diào)試步驟詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • hystrix配置中Apollo與Archaius對(duì)比分析

    hystrix配置中Apollo與Archaius對(duì)比分析

    這篇文章主要為大家介紹了hystrix的配置中Apollo與Archaius對(duì)比分析,并為大家解答在hystrix的配置中有了Apollo是否還需要Archaius這一問(wèn)題詳解
    2022-02-02
  • 使用okhttp替換Feign默認(rèn)Client的操作

    使用okhttp替換Feign默認(rèn)Client的操作

    這篇文章主要介紹了使用okhttp替換Feign默認(rèn)Client的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • java中的equals()和toString()方法實(shí)例詳解

    java中的equals()和toString()方法實(shí)例詳解

    這篇文章主要介紹了java中的equals()和toString()方法實(shí)例詳解的相關(guān)資料,這里舉例說(shuō)明,并附實(shí)例代碼,和實(shí)現(xiàn)效果圖,需要的朋友可以參考下
    2016-11-11
  • SpringBoot整合JPA 基礎(chǔ)使用示例教程

    SpringBoot整合JPA 基礎(chǔ)使用示例教程

    JPA(Java Persistence API)是Java提供的一套數(shù)據(jù)持久化標(biāo)準(zhǔn),通過(guò)對(duì)象-關(guān)系映射(ORM)技術(shù)實(shí)現(xiàn)Java對(duì)象與數(shù)據(jù)庫(kù)表之間的映射,它提供了一系列注解和接口,簡(jiǎn)化了數(shù)據(jù)庫(kù)操作,使得開發(fā)者可以通過(guò)操作對(duì)象來(lái)進(jìn)行數(shù)據(jù)庫(kù)交互,而無(wú)需編寫復(fù)雜的SQL語(yǔ)句
    2024-10-10

最新評(píng)論