guava之multimap
上一篇说的是Multiset它可以对存入的相同元素做一个计数的功能,那multimap呢?
一、概述 |
1、基本介绍和案例说明
multimap和Multiset的继承结果很相似,只不过在上层的接口是Multimap不是Multiset
Multimap的特点其实就是可以包含有几个重复key的value值,你可以put进多个不同的value,但是key相同,但是又不是让后面的覆盖前面的内容
它的业务场景:当你需要构造像Map<K,List<V>> 或者Map(K,Set<V>)这样比较复杂的集合类型的数据结构,来做相应的业务逻辑处理,那Multimap在合适不过
举例
public class MultimapTest { @Test public void testMultimap(){ HashMultimap<Integer, Integer> map = HashMultimap.create(); map.put(1, 2); map.put(1, 3); map.put(1, 2); map.put(2, 3); map.put(4, 2); map.put(4, 3); map.put(4, 2); map.put(4, 3); System.out.println(map.toString()); } }
/*输出结果: *{1=[2, 3], 2=[3], 4=[2, 3]} */
其实它会把相同的key和value的值会覆盖起来,但是相同的key又可以保留不同的value,因为它的entry的实现是一个Set,Set会对相同的Entry<K,V>进行曲重,所以会有这种情况
那map和multimap又有什么区别呢?
Map是不能有重复的键值,就像在我们国家一个男人只能有一个老婆,男人就是KEY,老婆就是VALUE.
Multimap是可以有重复的键值,就像一个男人可以有多个情人。
2、实际开发场景及常用方法
(1)根据业务需要对下面的list数据根据name字段进行分组
[ { "date":"2018-01-31", "name":"wuzhong", "socre":0.8 }, { "date":"2018-01-30", "name":"wuzhong", "socre":0.9 }, { "date":"2018-01-31", "name":"wuzhong2", "socre":0.8 } ]
传统做法:
Map<String,List<Item>> map = new HashMap<>(); for (Item item : list){ List<Item> tmp = map.get(item.getName()); if (null == tmp){ tmp = new ArrayList<>(); map.put(item.getName(),tmp); } tmp.add(item); }
很简单,但是代码量有点多,特别是需要判断List为null并初始化
再用guava实现上述的功能
//使用Multimap做法 Multimap<String,Item> multiMap = ArrayListMultimap.create(); for (Item item : list){ multiMap.put(item.getName(),item); }
代码量直接减少一半,这样实际开发中才能发挥作用
(2)再举一例子了解常用方法
public class MultimapTest01 { public static void main(String args[]){ Multimap<String,String> multimap = ArrayListMultimap.create(); multimap.put("lower", "a"); multimap.put("lower", "b"); multimap.put("lower", "c"); multimap.put("upper", "A"); multimap.put("upper", "B"); List<String> lowerList = (List<String>)multimap.get("lower"); //输出key为lower的list集合 System.out.println("输出key为lower的list集合========="); System.out.println(lowerList.toString()); lowerList.add("f"); System.out.println(lowerList.toString()); Map<String, Collection<String>> map = multimap.asMap(); System.out.println("把Multimap转为一个map============"); for (Map.Entry<String, Collection<String>> entry : map.entrySet()) { String key = entry.getKey(); Collection<String> value = multimap.get(key); System.out.println(key + ":" + value); } System.out.println("获得所有Multimap的key值=========="); Set<String> keys = multimap.keySet(); for(String key:keys){ System.out.println(key); } System.out.println("输出Multimap所有的value值========"); Collection<String> values = multimap.values(); System.out.println(values); }
输出结果:
4、Multimap的实现类
Multimap提供了丰富的实现,所以你可以用它来替代程序里的Map<K, Collection<V>>,具体的实现如下:
Implementation Keys 的行为类似 Values的行为类似ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap LinkedHashMap* LinkedList*
LinkedHashMultimap LinkedHashMap LinkedHashSet
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet
以上这些实现,除了immutable的实现都支持null的键和值。
1、LinkedListMultimap.entries()能维持迭代时的顺序。
2、LinkedHashMultimap维持插入的顺序,以及键的插入顺序。