Guava提供了不少新的集合類型(這部分也是目前使用最廣的)html
1.Multisetjava
The traditional Java idiom for e.g. counting how many times a word occurs in a document is something like:git
Map<String,Integer> counts =newHashMap<String,Integer>(); for(String word : words){ Integer count = counts.get(word); if(count ==null){ counts.put(word,1); }else{ counts.put(word, count +1); } }
在JDK中,List和Set有一個基本的區別,就是List能夠包含多個相同對象,且是有順序的,而Set不能有重複,且不保證順序(有些實現有順序,例如LinkedHashSet和SortedSet等)
因此Multiset佔據了List和Set之間的一個灰色地帶:容許重複,可是不保證順序。
注意:這種集合在apache commons collections中也被稱做「Bag」. apache
Guava provides many implementations of Multiset, which roughly correspond to JDK map implementations.編程
Map | Corresponding Multiset | Supports null elements |
HashMap | HashMultiset | Yes |
TreeMap | TreeMultiset | Yes (if the comparator does) |
LinkedHashMap | LinkedHashMultiset | Yes |
ConcurrentHashMap | ConcurrentHashMultiset | No |
ImmutableMap | ImmutableMultiset | No |
因而咱們使用Multiset就能很好的簡化上面的代碼app
package com.jake.guava.collections; import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; import org.junit.Test; import java.util.List; import java.util.Map; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; /** * User: jake * Date: 13-10-11 * Time: 上午11:27 */ public class MultiSetTest { @Test public void countWorldByMultiSetTest() { List<String> words = newArrayList("a", "b", "b", "b", "b", "b", "fdsf", "fdsf", "fdsf"); Map<String, Integer> counts = newHashMap(); Multiset wordSet = HashMultiset.create(); for (String word : words) { wordSet.add(word); } System.out.println(wordSet.size()); System.out.println(wordSet.elementSet().size()); } @Test public void countWorldCommonTest() { List<String> words = newArrayList("a", "b", "b", "b", "b", "b", "fdsf", "fdsf", "fdsf"); Map<String, Integer> counts = newHashMap(); for (String word : words) { Integer count = counts.get(word); if (count == null) { counts.put(word, 1); } else { counts.put(word, count + 1); } } } }
總結:JDK中沒出現的集合類型,實際中用到的地方仍是不少的ide
實用性:高 ui
2.Multimap(ListMultimap or SetMultimap)this
和MultiSet一樣有個Multi ,官網上也說明 Guava's Multimapframework makes it easy to handle a mapping from keys to multiple valuesgoogle
說明了,Multimap是用來處理一個key對應多個值,也就是 Map<K, List<V>> or Map<K, Set<V>> 這兩種狀況。(不包含 Map<K,Map<K,V>這種狀況)
通常咱們處理Map<K, List<V>> or Map<K, Set<V>> 這種稍顯複雜的結構,以下:
應用場景仍是比較多的,例如:
學校每一個班的學生總數,Map<class,List<Student>>
醫院每一個病房的病人信息,Map<room,List<Patient>>
咱們拿醫院來舉例,例如如今303病房要添加一個病人,
代碼會是如此
@Test public void multiMapCommonTest(){ List<Patient> pList = newArrayList(new Patient(1,"lucy",303),new Patient(2,"lily",303)); Map<Integer,List<Patient>> patientList = newHashMap(); patientList.put(303, pList); //此時要入住一個病人到303 Patient p = new Patient(3,"jake",303); List<Patient> patients = patientList.get(303); if (patients != null) { patients.add(p); } else { patients = newArrayList(); patients.add(p); } } @Test public void multiMapGuavaTest() { //這裏要改變一個思路,之前用 Map<K,List<V>> 來存儲 //如今用 Multimap<K,V> 來存儲 Multimap<Integer, Patient> patients = ArrayListMultimap.create(); patients.put(303,new Patient(1,"lucy",303)); patients.put(303,new Patient(1,"lily",303)); //此時要入住一個病人到303 Patient p = new Patient(3,"jake",303); Patient pAnother = new Patient(4,"jone",304); patients.put(303, p); patients.put(304, pAnother); for (Patient patient :patients.get(303) ) { System.out.println(patient); } }
//Multimap 也能夠經過asMap 轉爲 Map<K,Collection<V>>形式 Map<Integer,Collection<Patient>> patientmap = patients.asMap();
官方提供了不少View,如下這些那就都屬於java基礎數據的處理了,和Guava沒什麼關係
Multimap also supports a number of powerful views.
Multimap provides a wide variety of implementations. You can use it in most places you would have used a Map<K, Collection<V>>.
Implementation Keys behave like... Values behave like..
ArrayListMultimap HashMap ArrayList
HashMultimap HashMap HashSet
LinkedListMultimap* LinkedHashMap* LinkedList*
LinkedHashMultimap** LinkedHashMap LinkedHashSet
TreeMultimap TreeMap TreeSet
ImmutableListMultimap ImmutableMap ImmutableList
ImmutableSetMultimap ImmutableMap ImmutableSet
也就是說會有不少種形式,
Multimap<String, Object> multimap_1 = ArrayListMultimap.create(); Multimap<String, Object> multimap_2 = HashMultimap.create(); Multimap<String, Object> multimap_3 = LinkedListMultimap.create();
依然沒有 Map<K,Map<K,V>>的形式!
Each of these implementations, except the immutable ones, support null keys and values.
總結:可以幫助自動分類,和以前的編程習慣有些不一樣,須要些時間來適應,推薦
實用性:高
BiMap雙向或者叫作反向映射,就是經過value找key,普通思路就是維護着兩個同步的Map , keyMap 和valueMap,可是這樣作容易出錯!
Guava提供BiMap的inverse()方法來實現,
@Test public void biMapTest(){ ImmutableMap<Integer,String> map = ImmutableMap.of(1,"303",2,"304"); BiMap<Integer, String> biMap = HashBiMap.create(map); System.out.println(biMap.inverse().get("304")); }
Key-Value Map Impl | Value-Key Map Impl | Corresponding BiMap |
HashMap | HashMap | HashBiMap |
ImmutableMap | ImmutableMap | ImmutableBiMap |
EnumMap | EnumMap | EnumBiMap |
EnumMap | HashMap | EnumHashBiMap |
總結:使用簡單
實用性:中
table是一種新的集合,提供了一種二重定位,能夠認爲是 行 加 列 定位一個值
Table接口提供瞭如下幾種實現方式。使用上很簡單
@Test public void tableTest() { Table<Integer,Integer,String> table = HashBasedTable.create(); table.put(1, 1, "first row first column"); table.put(1, 2, "first row second column"); table.put(2,1,"second row first column"); System.out.println(table.get(1,2)); Table<Book, Integer, String> test = HashBasedTable.create(); }
可使用Integer定位,也可使用Book等對象定位。
總結:簡單易懂,
實用性:中
普通Map是K ,V 鍵值對,ClassToInstanceMap是 class ,V的鍵值對形式(加泛型後就沒意義了,只能存放一種對象,或者這種對象的子類對象)
示例代碼:
@Test public void classToInstanceMapTest(){ ClassToInstanceMap classToInstanceMapString =MutableClassToInstanceMap.create(); classToInstanceMapString.put(String.class, ""); classToInstanceMapString.put(Integer.class, 1); Book book = new Book(1,"ST10001","三國志"); classToInstanceMapString.put(Book.class, book); }
總結:簡單易懂,
實用性:中偏低
剩下的RangeSet和RangeMap等Range那一章一塊兒介紹
寫的很差,歡迎指正,有時間會進一步完善