平常开发中,小黑哥常常须要用到 Java 提供集合类完成各类需求。Java 集合类虽然很是强大实用,可是提供功能仍是有点薄弱。java
举个例子,小黑哥最近接到一个需求,从输入一个文档中,统计一个关键词出现的次数。代码以下:git
虽然这个需求使用 Map
能够轻松搞定,可是小黑哥仍是以为这种写法有点笨拙,若是没有判空,将会致使 NPE 异常。github
若是不少地方须要功能,咱们就能够抽象出来,将其封装成工具类。编程
不过上面的功能你们就不须要本身封装,一款来自 Google 开源工具类-Guava,能够轻松的解决上面的统计问题。缓存
Guava 是一款 Google 开源工具类,包含许多 Google 内部 Java
项目依赖的核心类。Guava 扩展 Java 基础类工程,好比集合,并发等,也增长一些其余强大功能,好比缓存,限流等功能。安全
另外 Guava 推出一些类,如 Optional
,甚至被 Java 开发者学习,后续增长到 JDK 中。多线程
目前 Guava Github 仓库已有 36k star,能够见到 Guava 受欢迎程度。并发
Guava 核心功能包括多个模块,今天小黑哥主要带你们玩转 Guava 集合类。框架
Guava 创造不少 JDK 没有,可是咱们平常却明显有用的新集合类型。这些新类型使用 JDK 集合接口规范,因此使用方法与 JDK 集合框架差很少,并无增长不少使用难度。ide
小黑哥第一次见到 Multiset
这个类,还觉得是 Set
接口子类。实际上此『Set』,仅仅只是数学上集合概念。
Multiset
继承 JDK Collection
接口,咱们能够屡次增长相同的元素,另外 Multiset
最大特定将会为元素计数,咱们能够将它相似等同为 Map<E, Integer>
。
使用 Multiset
能够轻松解决开头的问题。
使用 Multiset
简化了代码,而且不再用担忧新 NPE 的问题。
跟 JDK 集合类同样,Multiset
也有许多子类。
这里小黑哥提醒一下你们,虽然上面说过咱们能够将 Multiset<E>
看作 Map<E, Integer>
,可是 Multiset
可不是 Map
的子类,它但是 血统纯正的 Collection
子类。
小黑哥有时会在业务需求中使用 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
还有其余子类,如图所示:
BiMap
能够用来实现键值对的双向映射需求,这样咱们就能够经过 Key
查找对对应的 Value
,也可使用 Value
查找对应的 Key
。
这个需求若是使用 Map
实现,咱们就不得不使用两个 Map
,维护双向关系,而且任何改动还要保持同步。
使用 BiMap
修改上面的代码:
这里须要注意,BiMap#put
方法不能加入重复元素, 若加入,将会抛错。若是若特定值必定要替换,可使用 BiMap#forcePut
代替。
敲黑板,这个知识点记下来。小黑哥使用过程当中,就踩过这个坑。
一样的 BiMap
也有各类实现类:
Guava 另外还提供其余集合类,不过这些类使用起来有点复杂,小黑哥还未在业务代码中使用过,这里简单提下,感兴趣同窗能够深刻了解一下。
除了上面提到的新集合类之外,Guava 提供通用的工具类:
这些工具类需对使用的方法,咱们能够快速建立集合,分割集合,转化集合等。
使用工具类,咱们能够快速建立集合。例如:
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
泛型,不再用两侧都重复写泛型了。
另外还能够指定集合类的初始化大小。
Lists#transform
方法能够替代繁琐 for
循环,将元素转化,建立一个新集合类。
不过使用这个方法咱们要注意一点。
Lists#transform
内部使用懒加载的机制,只有在调用获取的元素的时候,如 result.get
才会真正使用 Function
从源 List
获取元素,作相应的转化。每次获取元素都将会使用 function
进行转化。
因此使用 Lists#transform
获得 List
仅仅只是源 List
一个视图,任何对源 List
的元素修改,都将会被反应到建立以后的 List
。任何对建立以后 List 中的元素进行修改,都不会生效。下次再次读取元素时,将会发现相应修改的丢失了。。。
小黑哥以前就踩过这个坑,若是你有这种需求,可使用如下方式建立一个新集合:
JDK8 以前版本,小黑哥常用该方法转化
List
中的元素。不过你若是使用 JDK8,小黑哥仍是推荐使用 Stream 流式编程。
Sets
提供几个方法,能够快速求出两个 Set
集合的交集,并集以及差集。
不可变(Immutable)集合,顾名思义集合不能够被修改。初始建立不可变集合时吗,须要传入数据源,建立完成以后,集合就不再能修改,增长,删除元素,不然将会报错。
这是一种防护性策略,防止集合在后续操做中被修改,从而引起问题。
不可变集合优势在于:
Guava 不可变集合支持 JDK 全部集合接口:
咱们可使用以下几种方式建立不可变集合,以 ImmutableList
为例:
List<String> fromList=Lists.newArrayList("点赞","关注"); // 从一个集合拷贝元素 ImmutableList.copyOf(fromList); ImmutableList.of("关注","Java极客技术"); ImmutableList.builder().add("关注").addAll(fromList).build();
这篇文章小黑哥带你们学习开源工具 Guava 集合的相关类使用方法,平常开发中咱们善于使用这些工具类,不要本身重复造轮子。
本篇文章仅仅只是介绍 Guava 一小部分功能,还有很对功能,小黑哥也以为很好用在。这里推荐你们去查看 Guava 官方 wiki,查看具体使用方法。
若是你们还想知道其余开源工具类,给小黑哥点个赞,下次给你们带来十分好用开源工具类~
欢迎关注个人公众号:程序通事,得到平常干货推送。若是您对个人专题内容感兴趣,也能够关注个人博客: studyidea.cn