当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map<FirstName, Map<LastName, Person>>来实现。为此Guava提供了一个新的集合类型-Table集合类型,来支持这种数据结构的使用场景。Table支持“row”和“column”,而且提供多种视图。 

  1. @Test
  2. public void TableTest(){
  3. Table<String, Integer, String> aTable = HashBasedTable.create();
  4.  
  5. for (char a = 'A'; a <= 'C'; ++a) {
  6. for (Integer b = 1; b <= 3; ++b) {
  7. aTable.put(Character.toString(a), b, String.format("%c%d", a, b));
  8. }
  9. }
  10.  
  11. System.out.println(aTable.column(2));
  12. System.out.println(aTable.row("B"));
  13. System.out.println(aTable.get("B", 2));
  14.  
  15. System.out.println(aTable.contains("D", 1));
  16. System.out.println(aTable.containsColumn(3));
  17. System.out.println(aTable.containsRow("C"));
  18. System.out.println(aTable.columnMap());
  19. System.out.println(aTable.rowMap());
  20.  
  21. System.out.println(aTable.remove("B", 3));
  22. }

  输出:

  1. {A=A2, B=B2, C=C2}
  2. {1=B1, 2=B2, 3=B3}
  3. B2
  4. false
  5. true
  6. true
  7. {1={A=A1, B=B1, C=C1}, 2={A=A2, B=B2, C=C2}, 3={A=A3, B=B3, C=C3}}
  8. {A={1=A1, 2=A2, 3=A3}, B={1=B1, 2=B2, 3=B3}, C={1=C1, 2=C2, 3=C3}}
  9. 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控制的上层绑定,例如:

  1. ClassToInstanceMap<Number> numberDefaults = MutableClassToInstanceMap.create();
  2. 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 含有的原生类型的项目,一个原生类型和他的相应的包装类可以映射到不同的值;

  1. import org.junit.Test;
  2.  
  3. import com.google.common.collect.ClassToInstanceMap;
  4. import com.google.common.collect.HashBasedTable;
  5. import com.google.common.collect.MutableClassToInstanceMap;

  6. public class OtherTest {
  7.  
  8. @Test
  9. public void ClassToInstanceMapTest() {
  10. ClassToInstanceMap<String> classToInstanceMapString =MutableClassToInstanceMap.create();
  11. ClassToInstanceMap<Person> classToInstanceMap =MutableClassToInstanceMap.create();
  12. Person person= new Person("peida",20);
  13. System.out.println("person name :"+person.name+" age:"+person.age);
  14. classToInstanceMapString.put(String.class, "peida");
  15. System.out.println("string:"+classToInstanceMapString.getInstance(String.class));
  16.  
  17. classToInstanceMap.putInstance(Person.class,person);
  18. Person person1=classToInstanceMap.getInstance(Person.class);
  19. System.out.println("person1 name :"+person1.name+" age:"+person1.age);
  20. }
  21. }
  22.  
  23. class Person {
  24. public String name;
  25. public int age;
  26.  
  27. Person(String name, int age) {
  28. this.name = name;
  29. this.age = age;
  30. }
  31. } 

  RangeSet

  RangeSet用来处理一系列不连续,非空的range。当添加一个range到一个RangeSet之后,任何有连续的range将被自动合并,而空的range将被自动去除。例如:

  1. @Test
  2. public void RangeSetTest(){
  3. RangeSet<Integer> rangeSet = TreeRangeSet.create();
  4. rangeSet.add(Range.closed(1, 10));
  5. System.out.println("rangeSet:"+rangeSet);
  6. rangeSet.add(Range.closedOpen(11, 15));
  7. System.out.println("rangeSet:"+rangeSet);
  8. rangeSet.add(Range.open(15, 20));
  9. System.out.println("rangeSet:"+rangeSet);
  10. rangeSet.add(Range.openClosed(0, 0));
  11. System.out.println("rangeSet:"+rangeSet);
  12. rangeSet.remove(Range.open(5, 10));
  13. System.out.println("rangeSet:"+rangeSet);
  14. }
  1. 输出:
  2. rangeSet:{[110]}
  3. rangeSet:{[110][1115)}
  4. rangeSet:{[110][1115)(1520)}
  5. rangeSet:{[110][1115)(1520)}
  6. rangeSet:{[15][1010][1115)(1520)}

  注意,像合并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对应的是相同的值。例如:

  1. @Test
  2. public void RangeMapTest(){
  3. RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
  4. rangeMap.put(Range.closed(1, 10), "foo");
  5. System.out.println("rangeMap:"+rangeMap);
  6. rangeMap.put(Range.open(3, 6), "bar");
  7. System.out.println("rangeMap:"+rangeMap);
  8. rangeMap.put(Range.open(10, 20), "foo");
  9. System.out.println("rangeMap:"+rangeMap);
  10. rangeMap.remove(Range.closed(5, 11));
  11. System.out.println("rangeMap:"+rangeMap);
  12. }
  13.  
  14. 输出:
  15. rangeMap:[[110]=foo]
  16. rangeMap:[[13]=foo, (36)=bar, [610]=foo]
  17. rangeMap:[[13]=foo, (36)=bar, [610]=foo, (1020)=foo]
  18. rangeMap:[[13]=foo, (35)=bar, (1120)=foo]

  RangeMap的视图
  RangeMap提供了两种视图:
  asMapOfRanges():返回Map<Range<K>, V>类型的视图。这个操作可以被用作迭代操作。
  subRangeMap(Range<K>)提供给定Range的交集。这个操作可以推广到传统的headMap, subMap, 和tailMap

集合-Table的更多相关文章

  1. Guava学习笔记:Guava新集合-Table等

    Table 当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map<FirstName, Map<LastName, Person>>来实现.为此Guava ...

  2. Mongodb命令集合

    一.数据库常用命令 1.Help查看命令提示 复制代码代码如下: help db.help(); db.yourColl.help(); db.youColl.find().help(); rs.he ...

  3. MongoDB创建数据库和集合命令db.createCollection详解(转)

    切换/创建数据库 use yourDB;  当创建一个集合(table)的时候会自动创建当前数据库 完整的命令如下:db.createCollection(name, {capped: <Boo ...

  4. Oracle_PL/SQL(7) 集合

    pl/sql集合处理单行单列数据,可以使用标量变量:处理单行多列的数据,可以使用pl/sql记录(%rowtype,record):处理单列多行数据,可以使用pl/sql集合. pl/sql集合类型是 ...

  5. js在table指定tr行上或底下添加tr行

    js在table指定tr行上或下面添加tr行 function onAddTR(trIndex)         {             var tb = document.getElementB ...

  6. MongoDB入门教程一[文档与集合]

    MongoDB 是面向集合存储的文档型数据库,其涉及到的基本概念与关系型数据库相比有所不同.举个例子,在关系型数据库中,我们记录一个订单的信息,通常是这样设计表结构的: 设计一个订单基本信息表和一个订 ...

  7. (转)Hibernate框架基础——映射集合属性

    http://blog.csdn.net/yerenyuan_pku/article/details/52745486 集合映射 集合属性大致有两种: 单纯的集合属性,如像List.Set或数组等集合 ...

  8. ActiveRecord模式整理

    DAO Data Access Object,数据访问对象 DAO是一个软件设计的指导原则,在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象 ...

  9. 【Java EE 学习 73】【数据采集系统第五天】【参与调查】【导航处理】【答案回显】【保存答案】

    一.参与调查的流程 单击导航栏上的“参与调查”按钮->EntrySurveyAction做出相应,找到所有的Survey对象并转发到显示所有survey对象的页面上供用户选择->用户单击其 ...

随机推荐

  1. 编程题:利用for循环打印 9*9 表?

    利用for循环打印 9*9  表? 1*1=1 1*2=2  2*2=4 1*3=3  2*3=6  3*3=9 1*4=4  2*4=8  3*4=12  4*4=16 1*5=5  2*5=10  ...

  2. pg_dump命令帮助信息

    仅为参考查阅方便,完全命令行帮助信息,无阅读价值. pg_dump dumps a database as a text file or to other formats. Usage:  pg_du ...

  3. 与班尼特·胡迪一起拿奖学金(HZNU-2273)

    与班尼特·胡迪一起拿奖学金 AC Time Limit:  2 s      Memory Limit:   256 MB Description 班尼特·胡迪这学期的体测终于上80分了,当期末考试的 ...

  4. Mysql 快速指南

    Mysql 快速指南 本文的示例在 Mysql 5.7 下都可以测试通过. 知识点 概念 数据库(database):保存有组织的数据的容器(通常是一个文件或一组文件). 数据表(table):某种特 ...

  5. log4j配置及使用

    一.使用方法: 1.将log4j.properties放到你创建项目的src中 2.引入log4j.jar import org.apache.log4j.*; public class log4jT ...

  6. Maven管理多模块应用

    穿越至目录: 从0开始,构建前后端分离应用 对于概念的一些理解 Maven的作用 管理模块之间的依赖:根据业务需求,系统会划分很多模块,这些模块彼此之间存在着依赖关系.比如系统管理模块依赖着文件上传模 ...

  7. URI和URL的区别 【转】

    源地址:http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html 这两天在写代码的时候,由于涉及到资源的位置,因此,需要在Java ...

  8. httpd基础配置和虚拟主机的配置方法

    RedHat6.5  httpd实验的大概步骤 #解包 tar zxf httpd-2.2.17.tar.gz -C /usr/src#切换到目录 cd /usr/src/httpd-2.2.17/# ...

  9. Django入门四之数据库相关

    1. 数据库设置 在settings.py中配置数据库 我首先使用的是sqlite3,所以配置如下 2. 数据库的数据结构定义 #blog/models.py #定义了一个表(Student),表里两 ...

  10. Centos制作本地yum源

    本地YUM源制作 1. YUM相关概念 1.1. 什么是YUM YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shel ...