集合-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,但是它是通过行和列来区分的。
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
集合-Table的更多相关文章
- Guava学习笔记:Guava新集合-Table等
Table 当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map<FirstName, Map<LastName, Person>>来实现.为此Guava ...
- Mongodb命令集合
一.数据库常用命令 1.Help查看命令提示 复制代码代码如下: help db.help(); db.yourColl.help(); db.youColl.find().help(); rs.he ...
- MongoDB创建数据库和集合命令db.createCollection详解(转)
切换/创建数据库 use yourDB; 当创建一个集合(table)的时候会自动创建当前数据库 完整的命令如下:db.createCollection(name, {capped: <Boo ...
- Oracle_PL/SQL(7) 集合
pl/sql集合处理单行单列数据,可以使用标量变量:处理单行多列的数据,可以使用pl/sql记录(%rowtype,record):处理单列多行数据,可以使用pl/sql集合. pl/sql集合类型是 ...
- js在table指定tr行上或底下添加tr行
js在table指定tr行上或下面添加tr行 function onAddTR(trIndex) { var tb = document.getElementB ...
- MongoDB入门教程一[文档与集合]
MongoDB 是面向集合存储的文档型数据库,其涉及到的基本概念与关系型数据库相比有所不同.举个例子,在关系型数据库中,我们记录一个订单的信息,通常是这样设计表结构的: 设计一个订单基本信息表和一个订 ...
- (转)Hibernate框架基础——映射集合属性
http://blog.csdn.net/yerenyuan_pku/article/details/52745486 集合映射 集合属性大致有两种: 单纯的集合属性,如像List.Set或数组等集合 ...
- ActiveRecord模式整理
DAO Data Access Object,数据访问对象 DAO是一个软件设计的指导原则,在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象 ...
- 【Java EE 学习 73】【数据采集系统第五天】【参与调查】【导航处理】【答案回显】【保存答案】
一.参与调查的流程 单击导航栏上的“参与调查”按钮->EntrySurveyAction做出相应,找到所有的Survey对象并转发到显示所有survey对象的页面上供用户选择->用户单击其 ...
随机推荐
- webpack安装使用
一.安装 1.安装node.js,Webpack 需要 Node.js v0.6 以上支持 2.使用npm(软件包管理 )安装webpack (1)全局安装 npm install webpac ...
- mysql海量数据的优化
转载:https://www.cnblogs.com/trying/archive/2013/08/15/3259126.html 下面是一部分比较重要的建议:1.选择正确的存储引擎以 MySQL为例 ...
- path sum II(深度优先的递归实现掌握)
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- Tomcat的缺省是多少,怎么修改
Tomcat的缺省端口号是8080. 修改Tomcat端口号: 1.找到Tomcat目录下的conf文件夹 2.进入conf文件夹里面找到server.xml文件 3.打开server.xml文件 ...
- postgresql 异步流复制hot standby搭建
先说说环境,主从库版本都是9.5,主库在CentOS物理机上,从库在Ubuntu虚拟机上 一.主库上的操作: 1.添加同步访问规则: host replication dbuser ...
- Golang 环境配置建议(Atom)
http://www.philo.top/2015/02/06/golang-%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%BB%BA%E8%AE%AE/ 开发环境的 ...
- android下ViewPager的使用,带下部选项栏的切换动画
(文章针对类似我这种初学者,大神看到不要嘲笑) 演示 我的规矩是先上GIF动画效果(Linux下用转的GIF,清晰度还可以但是不知道为什么放博客上,界面会这么大): 代码: android中有View ...
- C++开发中BYTE类型数组转为对应的字符串
下午密码键盘返回了一个校验码,是BYTE类型数组,给上层应用返回最好是字符串方式,怎样原样的将BYTE数组转为string串呢?不多说,开动脑筋上手干!!! BYTE格式的数组bt{08,D7,B4, ...
- 让 Homebrew 走代理更新 + brew 管理 node 版本
0.前言 环境:MacOS 背景:整理下今天所做的配置. 1. 让 Homebrew 走代理更新 brew update 就卡住了,即使开了 shadowsocks 也不行.因为 shadowsock ...
- 算法训练 2的次幂表示(蓝桥杯C++写法)
问题描述 任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001. 将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0 ...