当前位置: 首页 > 科技观察

老司机阿粉带你玩转Guava集合类

时间:2023-03-20 15:23:33 科技观察

在日常开发中,阿粉经常需要使用Java提供集合类来满足各种需求。Java集合类虽然很强大很实用,但是在提供功能上还是有点弱。例如,阿芬最近收到一个请求,要统计输入文档中某个关键字的出现次数。代码如下:虽然这个需求可以用Map轻松解决,但是阿芬还是觉得这种写法有点笨拙。如果没有空判断,就会引发NPE异常。如果很多地方都需要函数,我们可以将它们抽象出来,封装成工具类。但是,您不需要自己封装上述功能。来自谷歌的一款开源工具——Guava,可以轻松解决上述统计问题。Guava简介Guava是Google开源的一个工具类,包含了很多Google内部Java项目所依赖的核心类。Guava扩展了Java基础类项目,如集合、并发等,还增加了一些其他强大的功能,如缓存、限流等功能。此外,Guava还引入了一些类,比如Optional,Java开发者甚至学习了这些类,后来加入到JDK中。目前GuavaGithub仓库有36kstar,可见Guava的火爆程度。Guava的核心功能包括多个模块。今天阿粉主要带大家玩转Guava收藏课。扩展集合类Guava创建了许多新的集合类型,JDK没有,但显然对我们的日常生活很有用。这些新类型使用JDK集合接口规范,所以使用方法与JDK集合框架类似,并没有增加使用难度。Multiset阿粉第一次看到Multiset类,还以为是Set接口的子类。其实这个“集合”只是集合的一个数学概念。Multiset继承了JDK的Collection接口,我们可以多次添加同一个元素。另外,Multiset最大的特异性就是对元素进行计数。我们可以把它当作Map,用Multiset来轻松解决一开始的问题。使用Multiset简化您的代码,再也不用担心新的NPE。与JDK集合类一样,Multiset有许多子类。这里来自Github,提醒一下大家,虽然上面说了我们可以把Multiset看成一个MapMultimap,有时候我用的是Map1a->[1,2,3]b->4,c->[6业务要求。,5]使用Map+List的结构比较笨拙,代码实现也比较繁琐。Multimap是官方在Guava中解决这个问题的新矿。使用Multimap的实现代码如下:这里阿粉使用了Multimap的子类HashMultimap,其行为类似于MapMultimap等子类,如图:来自Github的BiMapBiMap可以用来实现键值对的双向映射需求,这样我们就可以通过Key找到对应的Value,或者使用Value来找到对应的Key。如果这个需求是用Map来实现的,我们就得用两个Map来维护双向关系,任何变化都必须保持同步。使用BiMap修改以上代码:这里需要注意的是BiMap#put方法不能添加重复的元素。如果添加,将抛出错误。如果必须替换特定值,则可以改用BiMap#forcePut。敲黑板,把这个知识点记下来。在使用的过程中,阿芬就踩到了这个坑。同样的BiMap还有各种实现类:从Github上其他的扩展集合类,Guava也提供了其他的集合类,但是这些类使用起来有点复杂,阿芬也没有在业务代码中使用过。这里简单提一下,有兴趣的同学可以多了解一下。TableClassToInstanceMapRangeSetRangeMap集合工具类除了上面提到的新的集合类,Guava还提供了通用的工具类:这些工具类需要用到的方法来自Github,我们可以快速的创建集合,拆分集合,变换集合等。创建集合实例使用工具类,我们可以快速创建集合。例如:1Listlist=Lists.newArrayList();2Setset=Sets.newHashSet();3Mapma??p=Maps.newHashMap();与新的集合方式相比,Guava方式的创建方式更加简单。1Listlist=newArrayList();2Setset=newHashSet();3Mapma??p=newHashMap();Guava工具智能推导List类型,不再需要两边重复泛型类型。此外,您还可以指定集合类的初始化大小。Lists.transformLists#transform方法可以代替繁琐的for循环来转换元素并创建一个新的集合类。但是,我们必须注意这个方法。Lists#transform内部使用了延迟加载机制。只有在调用获取到的元素时,如result.get,才会使用Function从源List中获取元素,并进行相应的转换。每次获取元素时,都会使用函数对其进行转换。所以使用Lists#transform得到一个List只是对源List的一个视图,对源List的元素的任何修改都会反映到创建的List中。创建后对List中元素的任何修改都不会生效。下次再次读取该元素时,会发现相应的修改丢失了。..这个圈套阿芬以前踩过。如果你有这样的需求,可以通过以下方式创建一个新的集合:在JDK8之前的版本中,阿芬经常使用这种方式来转换List中的元素。但是如果使用JDK8,阿芬还是推荐使用Stream编程。IntersectionuniondifferenceSets提供了几种快速求两个Set集合的交、并、差的方法。不可变集合不可变(Immutable)集合,顾名思义,集合不能被修改。最初创建不可变集合时,需要传入数据源。创建完成后,集合不能再修改、添加、删除元素,否则会报错。这是一种防御策略,可以防止集合在后续操作中被修改,从而导致问题。不可变集合的优点是:由于不可变集合只能读,多线程并发自然是安全的。由于不可变集合是固定的,可以看作是常量安全的,不需要其他人一行修改不可变集合,占用内存空间小。Immutable集合是不可修改的,不用担心其他程序任意修改集合。Guava不可变集合支持JDK的所有集合接口:我们可以使用以下方法创建不可变集合。以ImmutableList为例:总结一下这篇文章。如何使用开源工具Guava合集的相关类,我们在日常开发中善于使用这些工具类,不要自己重复造轮子。本文只介绍了Guava的一小部分功能,还有很多其他的功能阿芬也觉得很好用。在这里我建议你查看官方的Guavawiki以了解如何使用它。如果大家还想了解其他的开源工具,就给阿粉点个赞吧,下次我会给大家带来非常好用的开源工具~