Guava - Collections - New collection types

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

 

Implementations

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 SetMultimapthis

和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沒什麼關係

Views

Multimap also supports a number of powerful views.

  • asMap views any Multimap<K, V> as a Map<K, Collection<V>>. The returned map supports remove, and changes to the returned collections write through, but the map does not support put or putAll. Critically, you can use asMap().get(key) when you want null on absent keys rather than a fresh, writable empty collection. (You can and should cast asMap.get(key) to the appropriate collection type -- aSet for a SetMultimap, a List for a ListMultimap -- but the type system does not allow ListMultimap to return Map<K, List<V>> here.)
  • entries views the Collection<Map.Entry<K, V>> of all entries in the Multimap. (For a SetMultimap, this is a Set.)
  • keySet views the distinct keys in the Multimap as a Set.
  • keys views the keys of the Multimap as a Multiset, with multiplicity equal to the number of values associated to that key. Elements can be removed from the Multiset, but not added; changes will write through.
  • values() views the all the values in the Multimap as a "flattened" Collection<V>, all as one collection. This is similar toIterables.concat(multimap.asMap().values()), but returns a full Collection instead.

  

Implementations

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.

 

總結:可以幫助自動分類,和以前的編程習慣有些不一樣,須要些時間來適應,推薦

實用性:高

 

3.BiMap

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"));
}

Implementations 

Key-Value Map Impl Value-Key Map Impl Corresponding BiMap
HashMap HashMap HashBiMap
ImmutableMap ImmutableMap ImmutableBiMap
EnumMap EnumMap EnumBiMap
EnumMap HashMap EnumHashBiMap

 

總結:使用簡單

實用性:中

 

4.Table

table是一種新的集合,提供了一種二重定位,能夠認爲是 行 加 列 定位一個值

 Table接口提供瞭如下幾種實現方式。使用上很簡單

  • HashBasedTable, which is essentially backed by a HashMap<R, HashMap<C, V>>.
  • TreeBasedTable, which is essentially backed by a TreeMap<R, TreeMap<C, V>>.
  • ImmutableTable, which is essentially backed by an ImmutableMap<R, ImmutableMap<C, V>>. (Note: ImmutableTable has optimized implementations for sparser and denser data sets.)
  • ArrayTable, which requires that the complete universe of rows and columns be specified at construction time, but is backed by a two-dimensional array to improve speed and memory efficiency when the table is dense. ArrayTable works somewhat differently from other implementations; consult the Javadoc for details.

 

    @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等對象定位。

總結:簡單易懂,

實用性:中

5.ClassToInstanceMap

普通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那一章一塊兒介紹

 

寫的很差,歡迎指正,有時間會進一步完善

相關文章
相關標籤/搜索