guava之multimap
上一篇講到Multiset它可以對存入相同元素做一個計數的功能,那multimap呢?
一、概述
1、基本介紹和案例說明
multimap和MultiSet的繼承結果很相似,只不過在上層的接口是Multimap不是Multiset。
Multimap的特點其實就是可以包含有幾個重復Key的value,你可以put進入多個不同value但是相同的key,但是又不是讓后面覆蓋前面的內容。
它的業務場景:當你需要構造像Map<K, List<V>>或者Map<K, Set<V>>這樣比較復雜的集合類型的數據結構,來做相應的業務邏輯處理。那Multimap在合適不過。
舉例
@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>進行去重,所以會有這種情況。
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 } ]
傳統做法:
//Item就是封裝的對象 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<String,Item> multiMap = ArrayListMultimap.create(); for (Item item : list){ multiMap.put(item.getName(),item); }
代碼量直接減少了一半,這就是實際開發中它發揮的作用。
(2)再舉一例子了解常用方法:
public class MultimapTest { 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); } } /**輸出結果: *輸出key為lower的list集合========= * [a, b, c] * [a, b, c, f] * 把Multimap轉為一個map============ * lower:[a, b, c, f] * upper:[A, B] * 獲得所有Multimap的key值========== * lower * upper * 輸出Multimap所有的value值======== * [a, b, c, f, A, B] */
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維持插入的順序,以及鍵的插入順序。
參考
想太多,做太少,中間的落差就是煩惱。想沒有煩惱,要么別想,要么多做。中校【15】