Key 可重复的 Map -- Multimap

2017-04-07 22:37:24   最后更新: 2017-04-07 22:38:44   访问数量:516




上一篇日志中,我们介绍了 Guava 的可重复 key 的 Set -- Multiset 类型

元素可重复的 Set -- Multiset

本篇日志中,我们就来介绍 Guava 提供的另一个容器,可重复 key 的 Map -- Multimap

 

假设我们需要经营一家超市,超市中有若干库区,我们创建一个水果类,其中有两个字段,分别是水果的名称和所在库区号,那么现在我们需要了解一批水果中,每个库区各有多少水果,分别是什么,那么我们就需要这样的代码:

package com.techlog.test.testspring.service; import java.util.*; /** * Created by techlog on 2017/4/3. */ public class WorkMain { private final static List<Fruit> FRUITS = Arrays.asList(new Fruit("apple", 1), new Fruit("bnana", 1), new Fruit("apple", 2), new Fruit("pear", 3), new Fruit("pear", 1), new Fruit("watermellon", 2), new Fruit("orange", 3), new Fruit("tomato", 2), new Fruit("tomato", 3) ); public static void main(String[] argv) { Map<Long, List<Fruit>> fruitMap = new HashMap<>(); for (Fruit fruit : FRUITS) { List<Fruit> fruits = fruitMap.get(fruit.getWerahouseId()); if (fruits == null) { fruits = new ArrayList<>(); } fruits.add(fruit); fruitMap.put(fruit.getWerahouseId(), fruits); } for (Map.Entry<Long, List<Fruit>> entry : fruitMap.entrySet()) { System.out.println(entry.getKey() + " 号库区有 " + entry.getValue().size() + " 种水果,分别是:"); for (Fruit fruit : entry.getValue()) { System.out.println(fruit.getName()); } System.out.println("~~~~~~~~"); } } } class Fruit { private String name; private long werahouseId; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getWerahouseId() { return werahouseId; } public void setWerahouseId(long werahouseId) { this.werahouseId = werahouseId; } Fruit(String name, long werahouseId) { this.name = name; this.werahouseId = werahouseId; } }

 

 

打印出了:

1 号库区有 3 种水果,分别是:

apple

bnana

pear

~~~~~~~

2 号库区有 3 种水果,分别是:

apple

watermellon

tomato

~~~~~~~

3 号库区有 3 种水果,分别是:

pear

orange

tomato

~~~~~~~

 

注意到了吗?我们使用了 Map<Long, List<Fruit>> 这样的结构,这样的结构看上去非常笨拙,并且不易于理解

Guava 提供的 Multimap 正是用来解决这样的问题的

 

Multimap 是一个接口,提供了以下方法:

Multimap 提供的方法
方法说明
int size();容器中键值对总数
boolean isEmpty()容器是否为空
boolean containsKey(Object var1)传入的 key 是否存在
boolean containsValue(Object var1)传入的 value 是否存在
boolean containsEntry(Object var1, Object var2)传入的键值对是否存在
boolean put(K key, V value)向容器中插入键值对
boolean remove(K key, V value)删除键值对
boolean putAll(K var1, Iterable var2)插入某个 key 对应的一组键值对
boolean putAll(Multimap var1)将另一个 Multimap 中的全部数据插入该 Multimap
Collection replaceValues(K var1, Iterable var2)替换某个 key 的元素为新的一组元素
Collection removeAll(Object var1)删除某个 key 的全部键值对
void clear()清空容器
Collection get(K var1)获取 key 对应的全部值,返回值不可能为 null,但可能为空 List
Set keySet()获取所有 key 组成的 Set
Multiset keys()获取所有 key 组成的 Multiset
Collection values()获取所有 value 组成的集合
Collection> entries()获取所有 Map.Entry 组成的集合,包含重复键
Map> asMap()返回一个对应的 Map> 集合

 

Multimap 的各种实现
实现键类型值类型
ArrayListMultimapHashMapArrayList
HashMultimapHashMapHashSet
LinkedListMultimapLinkedHashMapLinkedList
LinkedHashMultimapLinkedHashMapLinkedHashMap
TreeMultimapTreeMapTreeSet
ImmutableListMultimapImmutableMapImmutableList
ImmutableSetMultimapImmutableMapImmutableSet

 

除了 ImmutableListMultimap 和 ImmutableSetMultimap,其他实现均支持 null 键和 null 值

你也可以通过 Multimaps.newMultimap(Map, Supplier<Collection>) 方法来创建你所需要的 list、set 版本的 Multimap

 

回到我们上文提到的例子,使用 Multimap,看上去就会简洁很多:

package com.techlog.test.testspring.service; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import java.util.*; /** * Created by techlog on 2017/4/3. */ public class WorkMain { private final static List<Fruit> FRUITS = Arrays.asList(new Fruit("apple", 1), new Fruit("bnana", 1), new Fruit("apple", 2), new Fruit("pear", 3), new Fruit("pear", 1), new Fruit("watermellon", 2), new Fruit("orange", 3), new Fruit("tomato", 2), new Fruit("tomato", 3) ); public static void main(String[] argv) { Multimap<Long, Fruit> fruitMultimap = HashMultimap.create(); for (Fruit fruit : FRUITS) { fruitMultimap.put(fruit.getWerahouseId(), fruit); } for (Long key : fruitMultimap.keySet()) { System.out.println(key + " 号库区有 " + fruitMultimap.get(key).size() + " 种水果,分别是:"); for (Fruit fruit : fruitMultimap.get(key)) { System.out.println(fruit.getName()); } System.out.println("~~~~~~~~"); } } } class Fruit { private String name; private long werahouseId; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getWerahouseId() { return werahouseId; } public void setWerahouseId(long werahouseId) { this.werahouseId = werahouseId; } Fruit(String name, long werahouseId) { this.name = name; this.werahouseId = werahouseId; } }

 

 






技术帖      龙潭书斋      容器      list      java      map      guava      multimap     


京ICP备15018585号