Guava 3: 集合Collections
一、引子
Guava 对JDK集合的拓展,是最成熟且最受欢迎的部分。本文属于Guava的核心,需要仔细看。
二、Guava 集合
2.1 Immutable Collections不可变集合
1.作用
用不变的集合进行防御性编程和性能提升。
2.简单使用
package guava.collect; import com.google.common.collect.ImmutableSet; /**
* @author denny
* @Description 不可变集合
* @date 2018/7/26 下午3:16
*/
public class ImmutableCollectionsTest {
/**
* 1.直接申明静态集合
*/
public static final ImmutableSet<String> COLOR_NAMES_1 = ImmutableSet.of(
"red",
"orange",
"yellow",
"green");
/**
* 2.防御式copy
*/
public static final ImmutableSet<String> COLOR_NAMES_2 = ImmutableSet.copyOf(COLOR_NAMES_1); /**
* 3.builder建造者模式
*/
public static final ImmutableSet<String> COLOR_NAMES_3 = ImmutableSet.<String>builder().addAll(COLOR_NAMES_2).add("blue").build(); public static void main(String[] args) {
System.out.println("of:"+COLOR_NAMES_1);
System.out.println("防御式copy:"+COLOR_NAMES_2);
System.out.println("建造者模式:"+COLOR_NAMES_3);
System.out.println("转换成list:"+COLOR_NAMES_3.asList());
}
}
打印:
of:[red, orange, yellow, green]
防御式copy:[red, orange, yellow, green]
建造者模式:[red, orange, yellow, green, blue]
转换成list:[red, orange, yellow, green, blue]
2.2 新集合类型
1.作用
提供multisets, multimaps, tables, bidirectional maps等,方便各种使用场景。
2.简单使用
很多类,我们只举例分析multiset、multimap接口,其它的就在测试类中体现。
multiset接口
继承自JDK:java.util.Collection接口,支持多次添加相同的元素,且无序。
当把Multiset看成普通的Collection时,它表现得就像无序的ArrayList:
- add(E)添加单个给定元素
- iterator()返回一个迭代器,包含Multiset的所有元素(包括重复的元素)
- size()返回所有元素的总个数(包括重复的元素)
当把Multiset看作Map<E, Integer>时,它也提供了符合性能期望的查询操作:
- count(Object)返回给定元素的计数。HashMultiset.count的复杂度为O(1),TreeMultiset.count的复杂度为O(log n)。
- entrySet()返回Set<Multiset.Entry<E>>,和Map的entrySet类似。
- elementSet()返回所有不重复元素的Set<E>,和Map的keySet()类似。
- 所有Multiset实现的内存消耗随着不重复元素的个数线性增长。
multimap接口
- 支持一个key映射多个value: k1-v1, k1-v2。
- 提供asMap()视图,返回Map<K, Collection<V>>,即k1->v集合(v1,v2)
各种multimap实现类如下:
测试类如下:
package guava.collect; import com.google.common.collect.BiMap;
import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.MutableClassToInstanceMap;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import com.google.common.collect.RangeSet;
import com.google.common.collect.Table;
import com.google.common.collect.TreeRangeMap;
import com.google.common.collect.TreeRangeSet; /**
* @author denny
* @Description 多重集合测试类
* @date 2018/7/26 下午6:29
*/
public class MultiCollectionsTest {
public static void main(String[] args) { System.out.println("====1.Multiset=======");
/** 1.Multiset 专用于统计元素出现次数 */
Multiset<String> wordsMultiset = HashMultiset.create();
// 添加元素
wordsMultiset.addAll(Lists.newArrayList("a", "b", "c", "a", "b", "a"));
//遍历不同元素集合,打印次数
wordsMultiset.elementSet().forEach(e -> System.out.println(e + ":" + wordsMultiset.count(e))); System.out.println("====2.Multimap=======");
/** 2.Multimap 1个key多value映射 */
Multimap<String, Integer> multimap = HashMultimap.create();
multimap.put("a", 1);
multimap.put("b", 2);
multimap.put("c", 3);
multimap.put("a", 4);
System.out.println("键-值集合映射:");
// 键-值集合映射:asMap()转成map(key,Collection<E>),再调用map相关方法,打印
multimap.asMap().entrySet().forEach(e -> System.out.println(e.getKey() + ":" + e.getValue()));
System.out.println("键-单个值映射:");
// 键-单个值映射:包括重复键
multimap.entries().forEach(e -> System.out.println(e.getKey() + ":" + e.getValue())); System.out.println("====3.BiMap=======");
/** 3.BiMap 键值反转 */
BiMap<String, Integer> biMap = HashBiMap.create();
biMap.put("a", 1);
biMap.put("b", 2);
System.out.println("键值对" + biMap);
System.out.println("键值反转:" + biMap.inverse()); System.out.println("====4.Table=======");
/** 4.Table <R rowKey, C columnKey, V value> */
Table<String, String, Integer> table = HashBasedTable.create();
table.put("a", "b", 1);
table.put("a", "c", 2);
table.put("d", "b", 3);
System.out.println(table);
System.out.println("row a=" + table.row("a"));
System.out.println("column b=" + table.column("b")); /** 5.ClassToInstanceMap 类、实例映射 */
System.out.println("====5.ClassToInstanceMap=======");
ClassToInstanceMap<Number> classToInstanceMap = MutableClassToInstanceMap.create();
classToInstanceMap.putInstance(Integer.class, 1);
classToInstanceMap.putInstance(Double.class, 2D);
classToInstanceMap.putInstance(Long.class, 3L);
System.out.println(classToInstanceMap); /** 6. RangeSet 区间运算; RangeMap 区间映射*/
System.out.println("====6.RangeSet、RangeMap=======");
RangeSet<Integer> rangeSet = TreeRangeSet.create();
// [1,10]
rangeSet.add(Range.closed(1,10));
// 不相连区间 [1,10] [11,15)
rangeSet.add(Range.closedOpen(11,15));
// 相连合并[11,15)+[15,20)=[11,20),最终结果:[1,10] [11,20)
rangeSet.add(Range.closedOpen(15,20));
// [1,10]-(5,10)=[1,5][10,10] ,最终结果:[1,5][10,10][11,20]
rangeSet.remove(Range.open(5,10));
System.out.println("rangeSet="+rangeSet);
RangeMap<Integer,String> rangeMap = TreeRangeMap.create();
rangeMap.put(Range.closed(1,10),"区间1");
// 不处理任何key的区间交集,只是简单映射
rangeMap.put(Range.closed(5,20),"区间2");
System.out.println("rangeMap="+rangeMap);
}
}
打印日志如下:
====1.Multiset=======
a:3
b:2
c:1
====2.Multimap=======
键-值集合映射:
a:[4, 1]
b:[2]
c:[3]
键-单个值映射:
a:4
a:1
b:2
c:3
====3.BiMap=======
键值对{a=1, b=2}
键值反转:{1=a, 2=b}
====4.Table=======
{a={b=1, c=2}, d={b=3}}
row a={b=1, c=2}
column b={a=1, d=3}
====5.ClassToInstanceMap=======
{class java.lang.Integer=1, class java.lang.Double=2.0, class java.lang.Long=3}
====6.RangeSet、RangeMap=======
rangeSet=[[1..5], [10..10], [11..20)]
rangeMap=[[1..5)=区间1, [5..20]=区间2]
2.3 强大的集合工具类
1.作用
提供java.util.Collections中没有的集合工具
2.简单使用
集合接口、所属关系、Guava对应的工具映射关系如下表:
package guava.collect; import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.primitives.Ints; import java.util.List;
import java.util.Map;
import java.util.Set; /**
* @Description
* @author denny
* @date 2018/7/27 下午2:46
*/
public class UtilityClassesTest { public static void main(String[] args) {
/** 1.Iterables 迭代器工具集 */
System.out.println("=========Iterables=========");
Iterable<Integer> concate = Iterables.concat(Ints.asList(1,2,3),Ints.asList(2,3,4));
System.out.println("链接:"+concate);
System.out.println("元素2出现次数:"+Iterables.frequency(concate,2));
System.out.println("按照指定长度拆分集合:"+Iterables.partition(concate,2));
System.out.println("取第一个元素,为空返回默认:"+Iterables.getFirst(concate,99));
System.out.println("取最后元素:"+Iterables.getLast(concate)); /** 2.Lists 列表工具集 */
System.out.println("=========Lists=========");
List list = Lists.newArrayList(1,2,3,4,5);
System.out.println("反转:"+Lists.reverse(list));
System.out.println("拆分:"+Lists.partition(list,2)); /** 3.Sets 集合工具集 */
System.out.println("=========Sets=========");
Set<Integer> set1 = Sets.newHashSet(1,2,3);
Set<Integer> set2 = Sets.newHashSet(3,4,5);
System.out.println("并集:"+Sets.union(set1,set2));
System.out.println("交集:"+Sets.intersection(set1,set2));
System.out.println("差集(set1有set2没有):"+Sets.difference(set1,set2));
System.out.println("并集-交集:"+Sets.symmetricDifference(set1,set2));
System.out.println("笛卡尔积:"+Sets.cartesianProduct(set1,set2));
System.out.println("全部子集:");
Sets.powerSet(set1).forEach(System.out::println); /** 4.Maps 集合工具集 */
System.out.println("=========Maps=========");
Map<String,Integer> map1 = Maps.newHashMap();
map1.put("a",1);
map1.put("b",2);
map1.put("d",5);
Map<String,Integer> map2 = Maps.newHashMap();
map2.put("a",1);
map2.put("b",3);
map2.put("c",4);
MapDifference<String,Integer> mapDifference = Maps.difference(map1,map2);
System.out.println("共有的:"+mapDifference.entriesInCommon());
System.out.println("key相同,value不同:"+mapDifference.entriesDiffering());
System.out.println("左边独有的:"+mapDifference.entriesOnlyOnLeft());
System.out.println("右边独有的:"+mapDifference.entriesOnlyOnRight());
// 字符串长度
ImmutableSet<String> allColors = ImmutableSet.of("red", "green", "blue");
ImmutableMap<Integer,String> immutableMap = Maps.uniqueIndex(allColors, input -> input.length());
System.out.println("字符串长度作为唯一key:"+immutableMap);
}
}
打印结果如下:
=========Iterables=========
链接:[1, 2, 3, 2, 3, 4]
元素2出现次数:2
按照指定长度拆分集合:[[1, 2], [3, 2], [3, 4]]
取第一个元素,为空返回默认:1
取最后元素:4
=========Lists=========
反转:[5, 4, 3, 2, 1]
拆分:[[1, 2], [3, 4], [5]]
=========Sets=========
并集:[1, 2, 3, 4, 5]
交集:[3]
差集(set1有set2没有):[1, 2]
并集-交集:[1, 2, 4, 5]
笛卡尔积:[[1, 3], [1, 4], [1, 5], [2, 3], [2, 4], [2, 5], [3, 3], [3, 4], [3, 5]]
全部子集:
[]
[1]
[2]
[1, 2]
[3]
[1, 3]
[2, 3]
[1, 2, 3]
=========Maps=========
共有的:{a=1}
key相同,value不同:{b=(2, 3)}
左边独有的:{d=5}
右边独有的:{c=4}
字符串长度作为唯一key{3=red, 5=green, 4=blue}
2.4 扩展工具类
1.作用
让实现和扩展集合类变得更容易,比如创建Collection的装饰器,或实现迭代器
2.简单使用
不提供。guava本生就是JDK拓展,自己再去拓展,你再逗我吗...
三、总结
本文根据官方文档简单理解并使用了Guava Collect包下的类,主要包含Immutable Collections不可变集合、新集合类型、集合工具类、拓展工具类。其中前三个建议使用,最后一个拓展工具类就算了吧。
Guava 3: 集合Collections的更多相关文章
- Backbone.js 为复杂Javascript应用程序提供模型(models)、集合(collections)、视图(views)的结构
Backbone.js 为复杂Javascript应用程序提供模型(models).集合(collections).视图(views)的结构.其中模型用于绑定键值数据和 自定义事件:集合附有可枚举函数 ...
- Guava新增集合类型-Bimap
Guava新增集合类型-Bimap BiMap提供了一种新的集合类型,它提供了key和value的双向关联的数据结构. 通常情况下,我们在使用Java的Map时,往往是通过key来查找value的,但 ...
- Guava新增集合类型-Multimap
Guava新增集合类型-Multimap 在日常的开发工作中,我们有的时候需要构造像Map<K, List<V>>或者Map<K, Set<V>>这样比 ...
- Guava新增集合类型-Multiset
Guava新增集合类型-Multiset Guava引进了JDK里没有的,但是非常有用的一些新的集合类型.所有这些新集合类型都能和JDK里的集合平滑集成.Guava集合非常精准地实现了JDK定义的接口 ...
- Java集合——Collections工具类
Java集合——Collections工具类 摘要:本文主要学习了Collections工具类的常用方法. 概述 Collections工具类主要用来操作集合类,比如List和Set. 常用操作 排序 ...
- [Guava学习笔记]Collections: 集合工具类
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3861431.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- [Guava学习笔记]Collections: 不可变集合, 新集合类型
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3843386.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- guava学习--集合2&Range
转载:http://www.cnblogs.com/peida/p/Guava_ImmutableCollections.html Table: 当我们需要多个索引的数据结构的时候,通常情况下,我们只 ...
- Guava学习笔记:Guava新集合-Table等
Table 当我们需要多个索引的数据结构的时候,通常情况下,我们只能用这种丑陋的Map<FirstName, Map<LastName, Person>>来实现.为此Guava ...
随机推荐
- HTTP请求处理流程 MVC核心(MVC就是扩展了一个HttpModule)
访问Localhost:8080/Home/index.aspx 在调用MVC扩展的UrlRoutingModule的时候 会先检查物理路径文件是否存在 存在的话就不执行MVC中的路由匹配规则 ...
- 构建oracle12c的Docker镜像
1. 准备工作 需要下载oracle相关的东东,例如安装文件,dockerfile.这些都可以从oracle 的github 上面找到.https://github.com/oracle/docker ...
- gulp点滴
var gulp = require('gulp'), connect = require('gulp-connect'), browserify = require('gulp-browserify ...
- IDEA spirng boot @Autowired注解 mapper出现红色下划线解决方法
如图所示,解决方法为: 把勾去掉即可.
- 《Practical Vim》第十章:复制和粘贴
第十章和第十一章讲了 Vim 的寄存器功能, 寄存器,是用于保存文本的特定的容器.它的内容: 既可以是类似于系统剪切板功能的,用于粘贴的文本 也可以是录制成的宏的命令. 第十章讲使用寄存器使用复制与粘 ...
- Linux下执行.sh命令出现-bash: ./bin/start.sh: /bin/bash^M: bad interpreter: No such file or directory
原因是 文件的格式是dos,修改为unix 就OK了 查看文件格式 用vim 打开出错的文件 按 ESC键 再按shift+冒号 输入 set ff 回车 可以看见 该文件 ...
- 6 款最棒的 Go 语言 Web 框架简介
地址: https://studygolang.com/articles/11897?fr=sidebar
- WCF发布到IIS 7.0,并以https访问
一.IIS 7.0中如何生成服务器证书,并要求网站以http访问可参考: http://www.cnblogs.com/chnking/archive/2008/10/07/1305811.html ...
- bzoj3884 上帝的集合
根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α α ”.“α α 被定义为“元”构成的集合.容 ...
- CentOS 7上安装Pure-FTPd
# 安装 yum install epel-release yum install pure-ftpd 位置文件位于/etc/pure-ftpd/pure-ftpd.conf # 修改配置文件 # 注 ...