Table數組
當咱們須要多個索引的數據結構的時候,一般狀況下,咱們只能用這種醜陋的Map<FirstName, Map<LastName, Person>>來實現。爲此Guava提供了一個新的集合類型-Table集合類型,來支持這種數據結構的使用場景。Table支持「row」和「column」,並且提供多種視圖。 數據結構
@Test public void TableTest(){ Table<String, Integer, String> aTable = HashBasedTable.create(); for (char a = 'A'; a <= 'C'; ++a) { for (Integer b = 1; b <= 3; ++b) { aTable.put(Character.toString(a), b, String.format("%c%d", a, b)); } } System.out.println(aTable.column(2)); System.out.println(aTable.row("B")); System.out.println(aTable.get("B", 2)); System.out.println(aTable.contains("D", 1)); System.out.println(aTable.containsColumn(3)); System.out.println(aTable.containsRow("C")); System.out.println(aTable.columnMap()); System.out.println(aTable.rowMap()); System.out.println(aTable.remove("B", 3)); }
輸出:優化
{A=A2, B=B2, C=C2} {1=B1, 2=B2, 3=B3} B2 false true true {1={A=A1, B=B1, C=C1}, 2={A=A2, B=B2, C=C2}, 3={A=A3, B=B3, C=C3}} {A={1=A1, 2=A2, 3=A3}, B={1=B1, 2=B2, 3=B3}, C={1=C1, 2=C2, 3=C3}} B3
Table視圖:
rowMap()返回一個Map<R, Map<C, V>>的視圖。rowKeySet()相似地返回一個Set<R>。
row(r)返回一個非null的Map<C, V>。修改這個視圖Map也會致使原表格的修改。
和列相關的方法有columnMap(), columnKeySet()和column(c)。(基於列的操做會比基於行的操做效率差些)
cellSet()返回的是以Table.Cell<R, C, V>爲元素的Set。這裏的Cell就相似Map.Entry,可是它是經過行和列來區分的。this
Table有如下實現:
HashBasedTable:基於HashMap<R, HashMap<C, V>>的實現。
TreeBasedTable:基於TreeMap<R, TreeMap<C, V>>的實現。
ImmutableTable:基於ImmutableMap<R, ImmutableMap<C, V>>的實現。(注意,ImmutableTable已對稀疏和密集集合作了優化)
ArrayTable:ArrayTable是一個須要在構建的時候就須要定下行列的表格。這種表格由二維數組實現,這樣能夠在密集數據的表格的場合,提升時間和空間的效率。google
ClassToInstanceMapspa
有的時候,你的map的key並非一種類型,他們是不少類型,你想經過映射他們獲得這種類型,guava提供了ClassToInstanceMap知足了這個目的。
除了繼承自Map接口,ClassToInstaceMap提供了方法 T getInstance(Class<T>) 和 T putInstance(Class<T>, T),消除了強制類型轉換。
該類有一個簡單類型的參數,一般稱爲B,表明了map控制的上層綁定,例如:code
ClassToInstanceMap<Number> numberDefaults = MutableClassToInstanceMap.create(); numberDefaults.putInstance(Integer.class, Integer.valueOf(0));
從技術上來講,ClassToInstanceMap<B> 實現了Map<Class<? extends B>, B>,或者說,這是一個從B的子類到B對象的映射,這可能使得ClassToInstanceMap的泛型輕度混亂,可是隻要記住B老是Map的上層綁定類型,一般來講B只是一個對象。
guava提供了有用的實現, MutableClassToInstanceMap 和 ImmutableClassToInstanceMap.
重點:像其餘的Map<Class,Object>,ClassToInstanceMap 含有的原生類型的項目,一個原生類型和他的相應的包裝類能夠映射到不一樣的值;orm
import org.junit.Test; import com.google.common.collect.ClassToInstanceMap; import com.google.common.collect.HashBasedTable; import com.google.common.collect.MutableClassToInstanceMap;
public class OtherTest { @Test public void ClassToInstanceMapTest() { ClassToInstanceMap<String> classToInstanceMapString =MutableClassToInstanceMap.create(); ClassToInstanceMap<Person> classToInstanceMap =MutableClassToInstanceMap.create(); Person person= new Person("peida",20); System.out.println("person name :"+person.name+" age:"+person.age); classToInstanceMapString.put(String.class, "peida"); System.out.println("string:"+classToInstanceMapString.getInstance(String.class)); classToInstanceMap.putInstance(Person.class,person); Person person1=classToInstanceMap.getInstance(Person.class); System.out.println("person1 name :"+person1.name+" age:"+person1.age); } } class Person { public String name; public int age; Person(String name, int age) { this.name = name; this.age = age; } }
RangeSet對象
RangeSet用來處理一系列不連續,非空的range。當添加一個range到一個RangeSet以後,任何有連續的range將被自動合併,而空的range將被自動去除。例如:blog
@Test public void RangeSetTest(){ RangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); System.out.println("rangeSet:"+rangeSet); rangeSet.add(Range.closedOpen(11, 15)); System.out.println("rangeSet:"+rangeSet); rangeSet.add(Range.open(15, 20)); System.out.println("rangeSet:"+rangeSet); rangeSet.add(Range.openClosed(0, 0)); System.out.println("rangeSet:"+rangeSet); rangeSet.remove(Range.open(5, 10)); System.out.println("rangeSet:"+rangeSet); }
輸出: rangeSet:{[1‥10]} rangeSet:{[1‥10][11‥15)} rangeSet:{[1‥10][11‥15)(15‥20)} rangeSet:{[1‥10][11‥15)(15‥20)} rangeSet:{[1‥5][10‥10][11‥15)(15‥20)}
注意,像合併Range.closed(1, 10)和Range.closedOpen(11, 15)這樣的狀況,咱們必須先用調用Range.canonical(DiscreteDomain)傳入DiscreteDomain.integers()處理一下。
RangeSet的視圖
RangeSet的實現支持了十分豐富的視圖,包括:
complement():是個輔助的RangeSet,它自己就是一個RangeSet,由於它包含了非連續,非空的range。
subRangeSet(Range<C>): 返回的是一個交集的視圖。
asRanges():返回能夠被迭代的Set<Range<C>>的視圖。
asSet(DiscreteDomain<C>) (ImmutableRangeSet only):返回一個ImmutableSortedSet<C>類型的視圖,裏面的元素是range裏面的元素,而不是range自己。(若是DiscreteDomain和RangeSet的上限或下限是無限的話,這個操做就不能支持)
Queries
除了支持各類視圖,RangeSet還支持各類直接的查詢操做,其中最重要的是:
contains(C):這是RangeSet最基本的操做,它能查詢給定的元素是否在RangeSet裏。
rangeContaining(C): 返回包含給定的元素的Range,若是不存在就返回null。
encloses(Range<C>): 用來判斷給定的Range是否包含在RangeSet裏面。
span():返回一個包含在這個RangeSet的全部Range的並集。
RangeMap
RangeMap表明了非連續非空的range對應的集合。不像RangeSet,RangeMap不會合並相鄰的映射,甚至相鄰的range對應的是相同的值。例如:
@Test public void RangeMapTest(){ RangeMap<Integer, String> rangeMap = TreeRangeMap.create(); rangeMap.put(Range.closed(1, 10), "foo"); System.out.println("rangeMap:"+rangeMap); rangeMap.put(Range.open(3, 6), "bar"); System.out.println("rangeMap:"+rangeMap); rangeMap.put(Range.open(10, 20), "foo"); System.out.println("rangeMap:"+rangeMap); rangeMap.remove(Range.closed(5, 11)); System.out.println("rangeMap:"+rangeMap); } 輸出: rangeMap:[[1‥10]=foo] rangeMap:[[1‥3]=foo, (3‥6)=bar, [6‥10]=foo] rangeMap:[[1‥3]=foo, (3‥6)=bar, [6‥10]=foo, (10‥20)=foo] rangeMap:[[1‥3]=foo, (3‥5)=bar, (11‥20)=foo]
RangeMap的視圖 RangeMap提供了兩種視圖: asMapOfRanges():返回Map<Range<K>, V>類型的視圖。這個操做能夠被用做迭代操做。 subRangeMap(Range<K>)提供給定Range的交集。這個操做能夠推廣到傳統的headMap, subMap, 和tailMap。