Java开源工具类:Guava

Guava 介绍

Guava 是一款 Google 开源工具类,包含许多 Google 内部 Java 项目依赖的核心类。Guava 扩展 Java 基础类工程,比如集合,并发等,也增加一些其他强大功能,比如缓存,限流等功能。

另外 Guava 推出一些类,如 Optional,甚至被 Java 开发者学习,后续增加到 JDK 中。

目前 Guava Github 仓库已有 36k star,可以见到 Guava 受欢迎程度。

Guava 核心功能包括多个模块,这里主要介绍 Guava 集合类。

扩展集合类

Guava 创造很多 JDK 没有,但是日常却明显有用的新集合类型。这些新类型使用 JDK 集合接口规范,所以使用方法与 JDK 集合框架差不多,并没有增加很多使用难度。

Multiset

实际上此『Set』,仅仅只是数学上集合概念。

Multiset 继承 JDK Collection 接口,可以多次增加相同的元素,
另外Multiset 最大特定将会为元素计数,可以将它类似等同为 Map<E, Integer>
使用 Multiset 简化了代码,并且再也不用担心新 NPE 的问题。

跟 JDK 集合类一样,Multiset也有许多子类。

虽然上面说过可以将 Multiset<E> 看做 Map<E, Integer>,但是 Multiset 可不是 Map 的子类,它可是 血统纯正的 Collection 子类。

Multimap

有时业务需求中会使用 Map<String,List<Integer>实现下面的需求。

1a->[1,2,3] b->4,c->[6,5]

使用 Map + List 这种结构比较笨拙,并且代码实现也比较繁琐。Multimap 正是 Guava 中解决这种问题的新出的一个雷。

使用 Multimap 实现代码如下:

这里使用 Multimap 子类 HashMultimap,其行为类似为 Map<K,Set<V>>,也就是说 Value 对应的集合内部元素不能重复。如果需要保存的重复的元素可以使用ArrayListMultimap

Multimap还有其他子类,如图所示:

BiMap

BiMap 可以用来实现键值对的双向映射需求,这样就可以通过 Key 查找对对应的Value,也可以使用 Value 查找对应的 Key

这个需求如果使用 Map 实现,就不得不使用两个 Map,维护双向关系,并且任何改动还要保持同步。


使用 BiMap 修改上面的代码:

这里需要注意,BiMap#put方法不能加入重复元素, 若加入,将会抛错。如果若特定值一定要替换,可以使用 BiMap#forcePut代替。

同样的 BiMap 也有各种实现类:

其他扩展集合类

Guava 另外还提供其他集合类,不过这些类使用起来有点复杂,这里简单提下,感兴趣同学可以深入了解一下。

  • Table
  • ClassToInstanceMap
  • RangeSet
  • RangeMap

集合工具类

除了上面提到的新集合类以外,Guava 提供通用的工具类:

image

这些工具类需对使用的方法,可以快速创建集合,分割集合,转化集合等。

快速创建集合实例

使用工具类,可以快速创建集合。例如:

// 1
List<String> list=Lists.newArrayList();
// 2
Set<String> set=Sets.newHashSet();
// 3
Map<String,String> map=Maps.newHashMap();

相比于 new 集合方法,Guava 方法创建方式更加简单。

// 1
List<String> list=new ArrayList<String>();
// 2
Set<String> set=new HashSet<String>();
// 3
Map<String,String> map=new HashMap<String, String>();

Guava 工具类智能推导 List 泛型,再也不用两侧都重复写泛型了。
另外还可以指定集合类的初始化大小。

List<String> list = Lists.newArrayList("hello", "world");
List<String> list1 = Lists.newArrayListWithExpectedSize(100);
List<String> list2 = Lists.newArrayListWithCapacity(100);

Lists.transform

Lists#transform方法可以替代繁琐 for 循环,将元素转化,创建一个新集合类。

List<String> formList = Lists.newArrayList("hello", "world");
List<String> result = Lists.transform(fromList, new Function<String, String>() {
    @Override
    public String apply(String input) {
        return input.toLowerCase();
    }
});

不过使用这个方法要注意一点。

Lists#transform 内部使用懒加载的机制,只有在调用获取的元素的时候,如result.get 才会真正使用 Function 从源 List 获取元素,做相应的转化。每次获取元素都将会使用 function 进行转化。

所以使用 Lists#transform 得到 List 仅仅只是源 List 一个视图,任何对源List 的元素修改,都将会被反应到创建之后的 List 。任何对创建之后 List 中的元素进行修改,都不会生效。下次再次读取元素时,将会发现相应修改的丢失了。。。

如果有相关需求,可以使用以下方式创建一个新集合:

Lists.newArrayList(Lists.transform(fromList, new Function<String, String>(){
    @Override
    public String apply(String input) {
        return input.toLowerCase();
    }
}));

JDK8 之前版本,可以使用该方法转化 List 中的元素。如果使用 JDK8,还是推荐使用 Stream 流式编程。

交集并集差集

Sets 提供几个方法,可以快速求出两个 Set 集合的交集,并集以及差集。

不可变集合

不可变(Immutable)集合,顾名思义集合不可以被修改。初始创建不可变集合时吗,需要传入数据源,创建完成之后,集合就再也不能修改,增加,删除元素,否则将会报错。

这是一种防御性策略,防止集合在后续操作中被修改,从而引发问题。

不可变集合优点在于:

  • 由于不可变集合仅仅只能读,多线程并发天然安全
  • 由于不可变集合固定不变,可以将其当做常量安全,不用单线其他人修改
  • 不可变集合占用更少内存空间
  • 不可变集合不可以被修改,所以不用担心其他程序任意修改集合

Guava 不可变集合支持 JDK 所有集合接口:

可以使用如下几种方式创建不可变集合,以 ImmutableList 为例:

List<String> fromList = Lists.newArrayList("hello", "world");
// 从一个集合拷贝元素
ImmtableList.copyOf(fromList);
ImmtableList.of("Guava", "java");
ImmtableList.builder().add("hello").addAll(fromList).builder();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355