文档章节

Guava table集合类

孟飞阳
 孟飞阳
发布于 2017/02/06 17:52
字数 1379
阅读 134
收藏 0

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。

本文转载自:http://www.cnblogs.com/peida/p/3183505.html

孟飞阳
粉丝 217
博文 1050
码字总数 564830
作品 5
朝阳
个人站长
私信 提问
Guava集合-不可变集合

JDK的Collections.unmodifiableXXX方法实现不可变集合的一些问题:   1.它用起来笨拙繁琐你不得不在每个防御性编程拷贝的地方用这个方法   2.它不安全:如果有对象reference原始的被封装...

Kevin-air
2016/08/04
28
0
【java代码之美】---guava之Immutable(不可变)集合

Immutable(不可变)集合 一、概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开。Collections是jdk提供的一个工具类。 Guava中不可变对象和C...

雨点的名字
2018/08/02
0
0
Guava学习笔记:Immutable(不可变)集合

  不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。   为什么要用immutable对象?immutable对象有以下的优点:    ...

pior
2015/03/31
69
0
Guava一些高效类的使用实践

guava是google的一个强大的工具包,目前已经更新到版本22 https://github.com/google/guava,一直有断断续续的用过一些方法,但是没有系统的撸一遍所有功能 今天参考并发编程网记录一些高效的...

zimingforever
2017/06/15
132
0
Google Guava 笔记

一、引言 Guava 是 google 几个java核心类库的集合,包括集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common ...

qllinhongyu
2014/09/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

作为一个(IT)程序员!聊天没有话题?试试这十二种技巧

首先呢?我是一名程序员,经常性和同事没话题。 因为每天都会有自己的任务要做,程序员对于其他行业来说;是相对来说比较忙的。你会经常看到程序员在发呆、调试密密麻麻代码、红色报错发呆;...

小英子wep
今天
15
0
【SpringBoot】产生背景及简介

一、SpringBoot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要...

zw965
今天
5
0
简述并发编程分为三个核心问题:分工、同步、互斥。

总的来说,并发编程可以总结为三个核心问题:分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共...

dust8080
今天
6
0
OSChina 周四乱弹 —— 当你简历注水但还是找到了工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享成龙的单曲《男儿当自强》。 《男儿当自强》- 成龙 手机党少年们想听歌,请使劲儿戳(这里) @hxg2016 :刚在...

小小编辑
今天
3.4K
22
靠写代码赚钱的一些门路

作者 @mezod 译者 @josephchang10 如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。 今天给大家分享一个精彩的 GitHub 库,这个库整理...

高级农民工
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部