1. Guava 介绍
Guava 是一款 Google 开源工具类,包含许多 Google 内部 Java
项目依赖的核心类。Guava 扩展 Java 基础类工程,比如集合,并发等,也增加一些其他强大功能,比如缓存,限流等功能。
另外 Guava 推出一些类,如 Optional
,甚至被 Java 开发者学习,后续增加到 JDK 中。
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
2.扩展集合类
Guava 创造很多 JDK 没有,但是我们日常却明显有用的新集合类型。这些新类型使用 JDK 集合接口规范,所以使用方法与 JDK 集合框架差不多,并没有增加很多使用难度。
最近接到一个需求,从输入一个文档中,统计一个关键词出现的次数。代码如下:
虽然这个需求使用 Map
可以轻松搞定,但是阿粉还是觉得这种写法有点笨拙,如果没有判空,将会导致 NPE 异常。
2.1 Multiset
阿粉第一次见到 Multiset
这个类,还以为是 Set
接口子类。实际上此『Set』,仅仅只是数学上集合概念。
Multiset
继承 JDK Collection
接口,我们可以多次增加相同的元素,另外 Multiset
最大特定将会为元素计数,我们可以将它类似等同为 Map<E, Integer>
。
使用 Multiset
可以轻松解决开头的问题。
使用 Multiset
简化了代码,并且再也不用担心新 NPE 的问题。
跟 JDK 集合类一样,Multiset
也有许多子类。
这里阿粉提醒一下大家,虽然上面说过我们可以将 Multiset<E>
看做 Map<E, Integer>
,但是 Multiset
可不是 Map
的子类,它可是 血统纯正的 Collection
子类。
2.2 Multimap
阿粉有时会在业务需求中使用 Map<String,List<Integer>
实现下面的需求。
a->[1,2,3] b->4,c->[6,5]
使用 Map
+ List
这种结构比较笨拙,并且代码实现也比较繁琐。Multimap
正式 Guava 中解决这种问题的新出的一个类。
使用 Multimap
实现代码如下:
这里阿粉使用 Multimap
子类 HashMultimap
,其行为类似为 Map<K,Set<V>>
,也就是说 Value
对应的集合内部元素不能重复。如果需要保存的重复的元素我们可以使用 ArrayListMultimap
。
Multimap
还有其他子类,如图所示:
2.3 BiMap
BiMap
可以用来实现键值对的双向映射需求,这样我们就可以通过 Key
查找对对应的 Value
,也可以使用 Value
查找对应的 Key
。
这个需求如果使用 Map
实现,我们就不得不使用两个 Map
,维护双向关系,并且任何改动还要保持同步。
使用 BiMap
修改上面的代码:
这里需要注意,BiMap#put
方法不能加入重复元素, 若加入,将会抛错。如果若特定值一定要替换,可以使用 BiMap#forcePut
代替。
敲黑板,这个知识点记下来。阿粉使用过程中,就踩过这个坑。
同样的 BiMap
也有各种实现类
3. 集合工具类
快速创建集合实例
使用工具类,我们可以快速创建集合。例如:
List<String> list=Lists.newArrayList();
Set<String> set=Sets.newHashSet();
Map<String,String> map=Maps.newHashMap();
相比于 new
集合方法,Guava 方法创建方式更加简单。
List<String> list=new ArrayList<String>();
Set<String> set=new HashSet<String>();
Map<String,String> map=new HashMap<String, String>();
Guava 工具类智能推导 List
泛型,再也不用两侧都重复写泛型了。
另外还可以指定集合类的初始化大小
交集并集差集
Sets
提供几个方法,可以快速求出两个 Set
集合的交集,并集以及差集。
不可变集合
不可变(Immutable)集合,顾名思义集合不可以被修改。初始创建不可变集合时吗,需要传入数据源,创建完成之后,集合就再也不能修改,增加,删除元素,否则将会报错。
这是一种防御性策略,防止集合在后续操作中被修改,从而引发问题。
不可变集合优点在于:
-
由于不可变集合仅仅只能读,多线程并发天然安全
-
由于不可变集合固定不变,可以将其当做常量安全,不用单线其他人修改
-
不可变集合占用更少内存空间
-
不可变集合不可以被修改,所以不用担心其他程序任意修改集合
Guava 不可变集合支持 JDK 所有集合接口