乐趣区

关于java:Google-开源的-Guava-工具库太强大了~

目前 Google Guava 在理论利用中十分宽泛,本篇博客将以博主对 Guava 应用的意识以及在我的项目中的教训来给大家分享!正如题目所言,学习应用 Google Guava 能够让你高兴编程,写出优雅的 JAVA 代码!
以面向对象思维解决字符串:Joiner/Splitter/CharMatcher

JDK 提供的 String 还不够好么?
兴许还不够敌对,至多让咱们用起来还不够爽,还得操心!
举个栗子,比方 String 提供的 split 办法,咱们得关怀空字符串吧,还得思考返回的后果中存在 null 元素吧,只提供了前后 trim 的办法(如果我想对两头元素进行 trim 呢)。
那么,看上面的代码示例,guava 让你不用在操心这些:

Joiner/Splitter
Joiner 是连接器,Splitter 是分割器,通常咱们会把它们定义为 static final,利用 on 生成对象后在利用到 String 进行解决,这是能够复用的。要晓得 apache commons StringUtils 提供的都是 static method。
更加重要的是,guava 提供的 Joiner/Splitter 是通过充沛测试,它的稳定性和效率要比 apache 高出不少,这个你能够自行测试下~
举荐浏览:试试 StringJoiner,真香!
发现没有咱们想对 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 的缺点了吗?Java 汇合系列面试题我都整顿好了,关注公众号 Java 技术栈回复“面试”获取。
实际上,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>,如同有点臃肿!臃肿也就算了,更加不爽的事,咱们还得判断 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 实现!举荐浏览:Java 中初始化 List 汇合的 6 种形式。
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 等等
好了,心愿这篇文章让你疾速进阶,高兴编程!

作者:张丰哲
出处:www.jianshu.com/p/97778b21bd00

总结了一些 2020 年的面试题,这份面试题的蕴含的模块分为 19 个模块,别离是:Java 根底、容器、多线程、反射、对象拷贝、Java Web、异样、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、MyBatis、RabbitMQ、Kafka、Zookeeper、MySQL、Redis、JVM。

获取材料以上材料:关注公众号:有故事的程序员,获取学习材料。
记得点个关注 + 评论哦~

退出移动版