使用Google Guava快乐编程

目前Google Guava在实际应用中很是普遍,本篇博客将以博主对Guava使用的认识以及在项目中的经验来给你们分享!正如标题所言,学习使用Google Guava可让你快乐编程,写出优雅的JAVA代码!java

以面向对象思想处理字符串:Joiner/Splitter/CharMatcher

JDK提供的String还不够好么?面试

也许还不够友好,至少让咱们用起来还不够爽,还得操心!redis

举个栗子,好比String提供的split方法,咱们得关心空字符串吧,还得考虑返回的结果中存在null元素吧,只提供了先后trim的方法(若是我想对中间元素进行trim呢)。spring

那么,看下面的代码示例,guava让你没必要在操心这些:数据库

Joiner/Splitter

Joiner是链接器,Splitter是分割器,一般咱们会把它们定义为static final,利用on生成对象后在应用到String进行处理,这是能够复用的。要知道apache commons StringUtils提供的都是static method。更加剧要的是,guava提供的Joiner/Splitter是通过充分测试,它的稳定性和效率要比apache高出很多,这个你能够自行测试下~apache

发现没有咱们想对String作什么操做,就是生成本身定制化的Joiner/Splitter,多么直白,简单,流畅的API!编程

对于Joiner,经常使用的方法是 跳过NULL元素:skipNulls() / 对于NULL元素使用其余替代:useForNull(String)缓存

对于Splitter,经常使用的方法是: trimResults()/omitEmptyStrings()。注意拆分的方式,有字符串,还有正则,还有固定长度分割(太贴心了!)安全

其实除了Joiner/Splitter外,guava还提供了字符串匹配器:CharMatcher网络

CharMatcher

CharMatcher,将字符的匹配和处理解耦,并提供丰富的方法供你使用!

对基本类型进行支持

guava对JDK提供的原生类型操做进行了扩展,使得功能更增强大!

Ints

guava提供了Bytes/Shorts/Ints/Iongs/Floats/Doubles/Chars/Booleans这些基本数据类型的扩展支持,只有你想不到的,没有它没有的!

对JDK集合的有效补充

灰色地带:Multiset

JDK的集合,提供了有序且能够重复的List,无序且不能够重复的Set。那这里其实对于集合涉及到了2个概念,一个order,一个dups。那么List vs Set,and then some ?

Multiset

Multiset是什么,我想上面的图,你应该了解它的概念了。Multiset就是无序的,可是能够重复的集合,它就是游离在List/Set之间的“灰色地带”!(至于有序的,不容许重复的集合嘛,guava尚未提供,固然在将来应该会提供UniqueList,我猜的,哈哈)

来看一个Multiset的示例:

Multiset Code

Multiset自带一个有用的功能,就是能够跟踪每一个对象的数量。

Immutable vs unmodifiable

来咱们先看一个unmodifiable的例子:

unmodifiable

你看到JDK提供的unmodifiable的缺陷了吗?

实际上,Collections.unmodifiableXxx所返回的集合和源集合是同一个对象,只不过能够对集合作出改变的API都被override,会抛出UnsupportedOperationException。

也便是说咱们改变源集合,致使不可变视图(unmodifiable View)也会发生变化,oh my god!

固然,在不使用guava的状况下,咱们是怎么避免上面的问题的呢?

defensive copies

上面揭示了一个概念:Defensive Copies,保护性拷贝。

OK,unmodifiable看上去没有问题呢,可是guava依然以为能够改进,因而提出了Immutable的概念,来看:

Immutable

就一个copyOf,你不会忘记,如此cheap~

用Google官方的说法是:we're using just one class,just say exactly what we mean,很了不得吗(不只仅是个概念,Immutable在COPY阶段还考虑了线程的并发性等,很智能的!),O(∩_∩)O哈哈~

guava提供了不少Immutable集合,好比ImmutableList/ImmutableSet/ImmutableSortedSet/ImmutableMap/......

看一个ImmutableMap的例子:

ImmutableMap


可不能够一对多:Multimap

JDK提供给咱们的Map是一个键,一个值,一对一的,那么在实际开发中,显然存在一个KEY多个VALUE的状况(好比一个分类下的书本),咱们每每这样表达:Map<k,List<v>>,好像有点臃肿!臃肿也就算了,更加不爽的事,咱们还得判断KEY是否存在来决定是否new 一个LIST出来,有点麻烦!更加麻烦的事情还在后头,好比遍历,好比删除,so hard......

来看guava如何替你解决这个大麻烦的:

Multimap

友情提示下,guava全部的集合都有create方法,这样的好处在于简单,并且咱们没必要在重复泛型信息了。

get()/keys()/keySet()/values()/entries()/asMap()都是很是有用的返回view collection的方法。

Multimap的实现类有:ArrayListMultimap/HashMultimap/LinkedHashMultimap/TreeMultimap/ImmutableMultimap/......

可不能够双向:BiMap

JDK提供的MAP让咱们能够find value by key,那么能不能经过find key by value呢,能不能KEY和VALUE都是惟一的呢。这是一个双向的概念,即forward+backward。

在实际场景中有这样的需求吗?好比经过用户ID找到mail,也须要经过mail找回用户名。没有guava的时候,咱们须要create forward map AND create backward map,and now just let guava do that for you.

BiMap

biMap / biMap.inverse() / biMap.inverse().inverse() 它们是什么关系呢?

你能够稍微看一下BiMap的源码实现,实际上,当你建立BiMap的时候,在内部维护了2个map,一个forward map,一个backward map,而且设置了它们之间的关系。

所以,biMap.inverse() != biMap ; biMap.inverse().inverse() == biMap

可不能够多个KEY:Table

咱们知道数据库除了主键外,还提供了复合索引,并且实际中这样的多级关系查找也是比较多的,固然咱们能够利用嵌套的Map来实现:Map<k1,Map<k2,v2>>。为了让咱们的代码看起来不那么丑陋,guava为咱们提供了Table。


Table

Table涉及到3个概念:rowKey,columnKey,value,并提供了多种视图以及操做方法让你更加轻松的处理多个KEY的场景。


函数式编程:Functions


Functions

上面的代码是为了完成将List集合中的元素,先截取5个长度,而后转成大写。

函数式编程的好处在于在集合遍历操做中提供自定义Function的操做,好比transform转换。咱们不再须要一遍遍的遍历集合,显著的简化了代码!


对集合的transform操做能够经过Function完成


断言:Predicate

Predicate最经常使用的功能就是运用在集合的过滤当中!

filter

须要注意的是Lists并无提供filter方法,不过你可使用Collections2.filter完成!

check null and other:Optional、Preconditions

在guava中,对于null的处理手段是快速失败,你能够看看guava的源码,不少方法的第一行就是:Preconditions.checkNotNull(elements);

要知道null是模糊的概念,是成功呢,仍是失败呢,仍是别的什么含义呢?

Preconditions/Optional

Cache is king

对于大多数互联网项目而言,缓存的重要性,不言而喻!

若是咱们的应用系统,并不想使用一些第三方缓存组件(如redis),咱们仅仅想在本地有一个功能足够强大的缓存,很惋惜JDK提供的那些SET/MAP还不行!


CacheLoader

首先,这是一个本地缓存,guava提供的cache是一个简洁、高效,易于维护的。为何这么说呢?由于并无一个单独的线程用于刷新 OR 清理cache,对于cache的操做,都是经过访问/读写带来的,也就是说在读写中完成缓存的刷新操做!

其次,咱们看到了,咱们很是通俗的告诉cache,咱们的缓存策略是什么,SO EASY!在如此简单的背后,是guava帮助咱们作了不少事情,好比线程安全。

让异步回调更加简单

JDK中提供了Future/FutureTask/Callable来对异步回调进行支持,可是仍是看上去挺复杂的,能不能更加简单呢?好比注册一个监听回调。


异步回调

咱们能够经过guava对JDK提供的线程池进行装饰,让其具备异步回调监听功能,而后在设置监听器便可!

Summary

到这里,这篇文章也只介绍了guava的冰山一角,其实还有不少内容:

guava package

好比反射、注解、网络、并发、IO等等

好了,但愿这篇文章让你快速进阶,快乐编程!


工做一到五年的java 开发工程师朋友能够加入咱们Java架构交流群:760940986 群内提供 高可用,高并发,spring源码,mybatis源码,JVM,大数据,Netty等多个技术知识的架构视频资料 还有大把大牛在群内交流以及解答面试指导,问题答疑~~要进来和大牛交流学习提高提高本身吗~~~~

相关文章
相关标签/搜索