强大的Guava中的新集合类型: Multiset, Multimap, BiMap, Table, ClassToInstanceMap, RangeSet, RangeMap等
一 Multiset
/**
* 新类型集合: Multiset: Multiset就是可以保存多个相同的对象,并且无序
* 占据了List和Set之间的一个灰色地带
* 其他实现: TreeMultiset LinkedHashMultiset
* ConcurrentHashMultiset
* ImmutableMultiset
*/
@Test
public void newList(){
HashMultiset<Integer> multiset = HashMultiset.create();
multiset.add(2,3);//添加指定个数的重复元素
multiset.count(2); //获取元素在集合中的个数
multiset.remove(2,2); //移除指定的个数元素
multiset.setCount(5,2); //和add相同
multiset.setCount(5,2,3); //修改集合中元素的个数,2个改为3个
//常见功能,统计每个字符出现的此数
String strWorld="wer|dffd|ddsa|dfd|dreg|de|dr|ce|ghrt|cf|gt|ser|tg|ghrt|cf|gt|" +
"ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr|wer|dffd|ddsa|dfd|dreg|de|dr|" +
"ce|ghrt|cf|gt|ser|tg|gt|kldf|dfg|vcd|fg|gt|ls|lser|dfr";
HashMultiset<String> multisetStr = HashMultiset.create();
multisetStr.addAll(Arrays.asList(strWorld.split("\\|")));
multisetStr.elementSet().forEach(x->System.out.println(x+" :"+multisetStr.count(x)));
}
二 Multimap
/**
* Multimap 提供了一个方便地把一个键对应到多个值的数据结构
* ”键-单个值映射”的集合(例如:a -> 1 a -> 2 a ->4 b -> 3 c -> 5)
* 用于替代 Map<K, List<V>>或Map<K, Set<V>>这种结构
* 提供多种实现 ArrayListMultimap HashMultimap 等
*/
@Test
public void multiMapTest(){
Multimap<String, User> multimap = ArrayListMultimap.create();
for (int i = 1; i <= 5; i++) {
multimap.put("one",User.of().setAge(23).setName("用户"+i).setLevel(i));
}
for (int i = 1; i <= 5; i++) {
multimap.put("two",User.of().setAge(20).setName("用户"+i).setLevel(i));
}
multimap.containsKey("one"); //判断是否包含有key
multimap.size(); //所有元素个数
//转换为map数据结构
Map<String, Collection<User>> map = multimap.asMap();
multimap.remove("key",User.of());//移除key对应下指定的value
multimap.keys();//获取所有的key
multimap.values(); //获取所有的value
multimap.removeAll("one");//移除key对应的所有元素
multimap.replaceValues("two", Lists.newArrayList(User.of()));// 替换key对应的元素
}
三 BiMap
/**
* BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构
* 能非常方便的实现map<key,value>的转置要求,也就是value变为key,key变为value
* 保证值是唯一的,因此返回Set而不是普通的Collection
*/
@Test
public void biMapTest(){
BiMap<Integer, String> hashBiMap = HashBiMap.create();
hashBiMap.put(1,"用户1");
hashBiMap.put(2,"用户2");
hashBiMap.put(3,"用户3");
//键值转换
BiMap<String, Integer> inverseBiMap = hashBiMap.inverse();
inverseBiMap.entrySet().forEach(x->
System.out.println("key:"+x.getKey()+", value:"+x.getValue()));
//因为值唯一(需要翻转时候key唯一),所以添加时如果value存在抛异常,可使用forcePut强制替换键
// hashBiMap.put(4,"用户3"); IllegalArgumentException
hashBiMap.forcePut(4,"用户3"); //强制替换用户3的键为4
//根据kv进行消费返回结果
String compute = hashBiMap.compute(4, (x, y) -> x + y);
System.out.println(compute); // 4用户3
}
四 Table
/**
* Table是Guava提供的一个接口 Interface Table(R,C,V),
* 由rowKey(行)+columnKey(列)+value组成 ,它有两个支持所有类型的键:”行”和”列”
* 其实就是有了双键的Map
* 例如: 学生(rowkey)--课程(columkey)--成绩(value)
*/
@Test
public void tableTest(){
Table<String, String, Integer> hashBasedTable = HashBasedTable.create();
hashBasedTable.put("一班","数学",97);
hashBasedTable.put("二班","英语",85);
hashBasedTable.put("二班","语文",70);
hashBasedTable.get("一班", "数学"); //通过两个key获取value
hashBasedTable.columnKeySet(); //获取列key [数学, 英语, 语文]
hashBasedTable.rowKeySet();//获取行key [一班, 二班]
//获取所有行的set
hashBasedTable.cellSet().forEach(x->
System.out.println("rowKey:"+x.getRowKey()+
", columnKey:"+x.getColumnKey()+", value:"+x.getValue()));
hashBasedTable.row("二班"); //根据rowKey获取所有对应的columnKey和value的 map
hashBasedTable.column("数学"); //根据columnKey获取所有对应的rowKey和value 的 map
hashBasedTable.rowMap(); //获取rowKey对应的 列-value map
hashBasedTable.remove("一班","数学"); //移除元素
hashBasedTable.columnMap(); //获取columnKey对应的 rowKey-value map }
五 ClassToInstanceMap
/**
* ClassToInstanceMap是一种特殊的Map:它的键是类型,而值是符合键所指类型的对象
*/
@Test
public void classToInstanceMapTest(){
//可存放所有数字类型的map
ClassToInstanceMap<Number> numberDefaults= MutableClassToInstanceMap.create();
numberDefaults.putInstance(Integer.class, 1);
numberDefaults.putInstance(Double.class, 1.00);
numberDefaults.putInstance(BigDecimal.class, new BigDecimal("52"));
numberDefaults.put(Integer.class, 2);
numberDefaults.replace(Integer.class, 3); //修改
numberDefaults.getInstance(Integer.class); //获取value 3
//通过传入新值和旧值计算,修改旧值,例: 将Integer,class的值+3
numberDefaults.merge(Integer.class,2,(x,y)->x.intValue()+y.intValue());
numberDefaults.forEach((x,y)-> System.out.println(x+","+y));
/**
* class java.lang.Double,1.0
* class java.math.BigDecimal,52
* class java.lang.Integer,5
*/ }
六 RangeSet
/**
* RangeSet描述了一组不相连的、非空的区间。
* 当把一个区间添加到可变的RangeSet时,所有相连的区间会被合并,空区间会被忽略
*/
@Test
public void rangeSetTest(){
RangeSet<Comparable<?>> treeRangeSet = TreeRangeSet.create();
treeRangeSet.add(Range.closed(1,10));
//连续区间会被合并 [15,22]
treeRangeSet.add(Range.closedOpen(15,20));
treeRangeSet.add(Range.closed(18,22));
treeRangeSet.remove(Range.closed(2,8)); //移除.,会把区间分割
//遍历所有区间
treeRangeSet.asRanges().forEach(x-> System.out.println(x)); // 返回一个目前所有区间里的最小值到最大值的区间
treeRangeSet.span();// [1..22]
//获取互补区间
treeRangeSet.complement();//[(-∞..1), (10..15), (22..+∞)]
treeRangeSet.contains(14); //是否包含此元素 false
//返回元素所在的区间,不包含返回null
treeRangeSet.rangeContaining(14);
// 是否包含某个区间
treeRangeSet.encloses(Range.closed(1, 10)); //true
//返回交集
treeRangeSet.subRangeSet(Range.closed(1, 4));
}
七 RangeMap
/**
* RangeMap描述了”不相交的、非空的区间”到特定值的映射。即 key是区间, value是值的map
* 和RangeSet不同,RangeMap不会合并相邻的映射,即便相邻的区间映射到相同的值
*/
@Test
public void rangeMap(){
RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closed(1, 10), "foo");
rangeMap.put(Range.open(3, 6), "bar");
rangeMap.put(Range.open(10, 20), "foo");
rangeMap.remove(Range.closed(5, 11));
//根据区间里的任意值获取value
rangeMap.get(1); //foo
//获取map视图进行迭代
rangeMap.asMapOfRanges().forEach((x,y)-> {
System.out.println(x); // [1..3]
System.out.println(y); // foo
});
}
rangermap很多用法和rangeSet一样的
/**
* RangeMap描述了”不相交的、非空的区间”到特定值的映射。即 key是区间, value是值的map
* 和RangeSet不同,RangeMap不会合并相邻的映射,即便相邻的区间映射到相同的值
*/
@Test
public void rangeMap(){
RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closed(1, 10), "foo");
rangeMap.put(Range.open(3, 6), "bar");
rangeMap.put(Range.open(10, 20), "foo");
rangeMap.remove(Range.closed(5, 11));
//根据区间里的任意值获取value
rangeMap.get(1); //foo
//获取map视图进行迭代
rangeMap.asMapOfRanges().forEach((x,y)-> {
System.out.println(x); // [1..3]
System.out.println(y); // foo
});
}
强大的Guava中的新集合类型: Multiset, Multimap, BiMap, Table, ClassToInstanceMap, RangeSet, RangeMap等的更多相关文章
- 004-guava 集合-新增集合类型-MultiSet, MultiMap, BiMap , Table, ClassToInstanceMap, RangeSe, RangeMap等
一.概述 Guava引入了很多JDK没有的.但明显有用的新集合类型.这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念.作为一般规则,Guava集合非常精准地遵循了JDK接口契 ...
- [Google Guava]学习--新集合类型Multiset
Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关.Multiset继承于JDK的Cllection接口,而不是Set接口. Multiset主要方法介绍: a ...
- [Guava学习笔记]Collections: 不可变集合, 新集合类型
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3843386.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- Guava集合--新集合类型
Guava引入了很多JDK没有的.但我们发现明显有用的新集合类型.这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念.作为一般规则,Guava集合非常精准地遵循了JDK接口契约 ...
- guava -- 新集合类型
Guava引入了很多JDK没有的.但有用的新集合类型.这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念. 作为一般规则,Guava集合非常精准地遵循了JDK接口契约. 1. ...
- Guava源码学习(四)新集合类型
基于版本:Guava 22.0 Wiki:New collection types 0. 简介 Guava提供了很多好用的集合工具,比如Multiset和BiMap,本文介绍了这些新集合类型的使用方式 ...
- Guava学习笔记:Guava新增集合类型-Multiset
Guava引进了JDK里没有的,但是非常有用的一些新的集合类型.所有这些新集合类型都能和JDK里的集合平滑集成.Guava集合非常精准地实现了JDK定义的接口.Guava中定义的新集合有: Multi ...
- Guava新增集合类型-Multiset
Guava新增集合类型-Multiset Guava引进了JDK里没有的,但是非常有用的一些新的集合类型.所有这些新集合类型都能和JDK里的集合平滑集成.Guava集合非常精准地实现了JDK定义的接口 ...
- [Google Guava]学习--新集合类型Multimap
每个有经验的Java程序员都在某处实现过Map<K, List<V>>或Map<K, Set<V>>,并且要忍受这个结构的笨拙. 假如目前有个需求是给两 ...
随机推荐
- CodeForces 796D
不能一个一个bfs,要一起bfs #include<iostream> #include<vector> #include<cstdio> #include< ...
- TVP访谈 | 贝壳金服史海峰:中台虽百家争鸣,但不是所有企业必需品
导语 | 中台作为一个技术概念,曾一度被捧得火热.那么,中台现在发展到了什么阶段呢?对于所有企业来讲,中台都是普适的么?中台在具体的落地过程中,究竟存在哪些问题呢?腾讯云最具价值专家(TVP)史海峰, ...
- 「2015南阳CCPC D」金砖 解题报告
金砖 Problem 有一个长度为L的板凳,可以放一排金砖,金砖不能重叠.特别的,摆放的金砖可以超出板凳,前提是必须保证该金砖不会掉下去,即该金砖的重心必须在板凳上. 每块金砖都一个长度和价值,且金砖 ...
- luogu 题解 P2380 【狗哥采矿】
拿到dp题我们就要想如何推方程 “最北边有bloggium的收集站,最西边有 yeyenum 的收集站.现在要你在这些格子上面安装向北或者向西的传送带(每个格子只能装一种).” 这说明了什么,对于某一 ...
- Java控制台五子棋(纯算法)
Java五子棋小游戏 本方案是基于控制台写的一个代码 没有花里胡哨的界面,只为研究算法 仅仅用了200行代码 下面是的是运行结果 游戏运行结果 这里我就很简单的复制了一个结果 第9回合,下子方:玩家2 ...
- Java之File类用法总结
File类概述:文件和文件目录路径的抽象表达形式,与平台无关.1.File能新建.删除.重命名文件和目录,但File不能访问文件内容本身.如果需要访问文件内容本身,则需要使用输入/输出流.2.想要在J ...
- 原生js实现音乐列表(隔行换色、全选)
一.实现原理: 1.使用 % 运算符实现各行换色,规律:当%前面的值和后面的值相同时 结果为0: 2.使用开关思想,实现在同一个元素上反复点击时的条件判断,并且把开关以属性方式绑定在每个元素上: 3 ...
- 通过例子进阶学习C++(五)计算2的1次方至2的64次方之和
本文是通过例子学习C++的第五篇,通过这个例子可以快速入门c++相关的语法. 1.上篇回顾 在上一篇中,我们通过字符数组计算264次方: 通过例子进阶学习C++(四)计算2的64次方 带着这个问题:为 ...
- python的range()
range() 是一个函数,用来生成一个自然数的序列 用list()显示具体内容 扩展 # range()是一个函数,可以用来生成一个自然数的序列 r = range(5) # 生成一个这样的序列 ...
- java 魔术
每4个字节都有对应的含义