} } }

    Guava进修笔记:Guava新凑集-Table等

    添加时间:2013-7-11 点击量:

      Table


      须要多个索引的数据布局的时辰,凡是景象下,我们只能用这种丑恶的Map<FirstName, Map<LastName, Person>>来实现。为此Guava供给了一个新的凑集类型-Table凑集类型,来支撑这种数据布局的应用处景。Table支撑“row”和“column”,并且供给多种视图。 



    @Test
    
    public void TableTest(){
    Table
    <String, Integer, String> aTable = HashBasedTable.create();

    forchar 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,然则它是经由过程行和列来区分的。


      Table有以下实现:
      HashBasedTable:基于HashMap<R, HashMap<C, V>>的实现。
      TreeBasedTable:基于TreeMap<R, TreeMap<C, V>>的实现。
      ImmutableTable:基于ImmutableMap<R, ImmutableMap<C, V>>的实现。(重视,ImmutableTable已对稀少和密集凑集做了优化)
      ArrayTable:ArrayTable是一个须要在构建的时辰就须要定下行列的表格。这种表格由二维数组实现,如许可以在密集数据的表格的场合,进步时候和空间的效力。


      ClassToInstanceMap


      有的时辰,你的map的key并不是一种类型,他们是很多类型,你想经由过程映射他们获得这种类型,guava供给了ClassToInstanceMap满足了这个目标。
      除了持续自Map接口,ClassToInstaceMap供给了办法 T getInstance(Class<T>) 和 T putInstance(Class<T>, T),打消了强迫类型转换。
      该类有一个简单类型的参数,凡是称为B,代表了map把握的上层绑定,例如:



    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 含有的原生类型的项目,一个原生类型和他的响应的包装类可以映射到不合的值;



    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将被主动去除。例如:



        @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。

    文艺不是炫耀,不是花哨空洞的文字堆砌,不是一张又一张的逆光照片,不是将旅行的意义转化为名牌包和明信片的物质展示;很多时候它甚至完全不美——它嘶吼、扭曲,它会痛苦地抽搐,它常常无言地沉默。——艾小柯《文艺是一种信仰》
    分享到: