作者:Jack47

转载请保留作者和原文出处

欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源

本文是我写的Google开源的Java编程库Guava系列之一,主要介绍Guava中提供的集合(Collection)相关的API。

1. 一些小功能##

集合声明更简单###

Java中同质的范型集合是一个很大的特色,但是有些时候他们的构造函数有点太啰嗦了,比如:

Map<String, Map<String, Integer>> lookup = new HashMap<String, Map<String, Integer>>();

在Java 7中通过钻石操作符<>来允许有限的非正式的类型推导。上面的例子可以这样写:

Map<String, Map<String, Integer>> lookup = new HashMap<>();

Guava提供了一些使用范型来进行右侧类型推导的静态函数,使得集合的声明更简单,上面的例子可以这么写:

Map<String, Map<String, String>> map = Maps.newHashMap();
List<List<Map<String, String>>> list = Lists.newArrayList();

集合初始化更简单###

可以在集合声明时进行初始化

Set<String> set = Sets.newHashSet("one", "two", "three");
Map<String, String> map = ImmutableMap.of("ON", true, "OFF", false);

2. 不可变性(Immutability)##

大部分google提供的集合都提供不可变的版本。

当你不会修改一个集合,或者期望一个集合是固定不变的,那么一个很好的习惯是防御式地把它拷贝成一个不可变的集合。

注意

Guava中提供的不可变集合的实现是不允许有空值`null`的。因为通过研究Google内部代码库发现在集合中,只有5%的情况下是允许有空值的,剩下的95%情况下最好是遇到空值就快速失败(failing fast)。如果需要空值,可以使用JDK中提供的 Collections.unmodifiableList 这类允许空值的集合实现。

更多关于使用或者避免使用null的细节见Using And Avoiding Null Explained

不可变的好处

  • 可以放心的给不信任的库使用
  • 线程安全:可以被多个线程使用而不会有竞争条件发生
  • 不需要同步(synchronization)的逻辑,不需要支持互斥
  • 设计和实现很简单。所有不可变的集合实现比可变版本的内存效率要高,分析见这里

如何使用###

有多种方法来得到一个不可变的集合:

  1. 使用of函数

    ImmutableSet<Integer> numbers = ImmutableSet.of(10, 30, 40, 50);

  2. 使用copyOf函数

    ImmutableSet<Integer> another = ImmutableSet.copyOf(numberSet);

所有不可变的集合都通过asList()提供了一个不可变的List(ImmutableList)视图。例如数据存储在一个ImmutableSortedSet里,可以通过sortedSet.asList().get(k)来获得第k个最小的元素。

JDK虽然提供了Collections.unmodifiableXXX方法,但是有一些问题:

  • 非常笨重,使用起来很啰嗦,用着不爽
  • 不安全:只有当没有对原始集合的引用时,这个函数返回的集合才是真的不可变的
  • 不够高效:数据结构里还是有可变集合里关于并发修改的检查,存储哈希表的额外空间等。

3. 新的集合类型##

Guava引入的新的集合类型并没有暴露原始的构造函数,或者提供方便初始化操作的工具类,而是直接使用静态工厂函数,例如:

MultiMap<String, Integer> multiMap = HashMultiMap.create();

MultiMap###

容许一个key有多个值的MultiMap, MultiMap<K, V>可以取代传统的Map<K, Collection<V>>。也可以使用值为链表的ListMultiMap或者集合SetMultiMap

Multiset###

Multiset支持添加多次相同的值,支持对值进行计数。

Multiset<Integer> multiSet = HashMultiset.create();
multiSet.add(10);
multiSet.add(30);
multiSet.add(30);
multiSet.add(40);
multiSet.count(30); // 2
multiSet.size(); // 4

Table###

表结构的数据类型Table,它像Map一样,但是支持两种键--行键(row key)和列键(column key)。

4. 谓语(Predicate)和过滤器(Filter)##

谓语(Predicate)是一个只包含一个返回布尔类型的函数的简单接口。它的作用是给定一个输入,判断是否满足条件。它可以用来过滤集合,例如实现一个过滤出老客户的Predicate

static class LoyalCustomer implements Predicate<Customer> {
public boolean apply(Customer customer) {
return CustomerType.LOYAL == customer.getCustomerType();
}
}
Collection<Customer> loyalCustomers = Collections2.filter(customers, new LoyalCustomer());

filter函数的语法是:

Collection<E> filter(Collection<E> unfiltered, Predicate<E> predicate)

内置的Predicate####

Predicates类包含了andornot in这几个静态函数来方便构建复杂的谓语。

Predicate<String> commonList = and(in(list1), in(list2, or(in(list3));

Predicates类也包含了很多非常方便的函数,例如notNull, instanceOf, contains等。

SortedMaps.filterValues(map, Predicates.notNull());

如果看到这里还意犹未尽的话,建议去看看源代码单测的代码,里面有详尽的用法!

参考资料:

Immutable Collections

Collection Utilities


如果您看了本篇博客,觉得对您有所收获,请点击右下角的“推荐”,让更多人看到!

资助Jack47写作,打赏一个鸡蛋灌饼钱吧
微信打赏
支付宝打赏

Guava库介绍之集合(Collection)相关的API的更多相关文章

  1. Guava库介绍之实用工具类

    作者:Jack47 转载请保留作者和原文出处 欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 本文是我写的Google开源的Java编程库Guava系列之一,主要介 ...

  2. java11 Guava:谷歌开发的集合库

    Guava:谷歌开发的集合库,通过build path->Add External JARs 把guava.jar包加进去. 版本控制工具:.CVS .SVN .git 所以需要下载git客户端 ...

  3. GitHub上排名前100的Android开源库介绍(来自github)

    本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍,至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果,然后过滤了 ...

  4. Guava 教程2-深入探索 Google Guava 库

    原文出处: oschina 在这个系列的第一部分里,我简单的介绍了非常优秀的Google collections和Guava类库,并简要的解释了作为Java程序员,如果使用Guava库来减少项目中大量 ...

  5. GitHub上排名前100的Android开源库介绍

    GitHub上排名前100的Android开源库介绍 文章来源: http://www.open-open.com/news/view/1587067#6734290-qzone-1-31660-bf ...

  6. DBoW2库介绍

    DBoW2库是University of Zaragoza里的Lopez等人开发的开源软件库. 由于在SLAM回环检测上的优异表现(特别是ORB-SLAM2),DBoW2库受到了广大SLAM爱好者的关 ...

  7. WCF分布式开发步步为赢(8):使用数据集(DataSet)、数据表(DataTable)、集合(Collection)传递数据

    数据集(DataSet).数据表(DataTable).集合(Collection)概念是.NET FrameWork里提供数据类型,在应用程序编程过程中会经常使用其来作为数据的载体,属于ADO.NE ...

  8. Common Lisp第三方库介绍 | (R "think-of-lisper" 'Albertlee)

    Common Lisp第三方库介绍 | (R "think-of-lisper" 'Albertlee) Common Lisp第三方库介绍 一个丰富且高质量的开发库集合,对于实际 ...

  9. [集合]Collection集合框架源码分析

    Collection接口 在java的集合类库中,基本接口是Collection,该接口的在集合中的源码定义如下(将源码中的注释删掉了): public interface Collection< ...

随机推荐

  1. Oracle跟踪文件

    1.跟踪文件分类 1)计划内的.由用户请求所产生的跟踪文件 2)计划外的.数据库服务器自动产生的跟踪文件 2.计划内的.由用户请求所产生的跟踪文件 2.1 生成 ①alter session set ...

  2. F#之旅7 - 图片处理入门

    首先,隆重介绍今天的主角:ImageProcessor(http://imageprocessor.org/).虽然我并没有在实际工作中用到这个库,但是它干净利索的使用方式打动了我,很久以前就存了下来 ...

  3. JS应用,表单上的一些东西

    例: <body> <form>我的生日是哪一年? <input type="text" value="" id="t1 ...

  4. 展开easyui 树节点到某个点

    $(function () { $('#tt').tree({ url: '/IS/Department/JsonTree?companyID=@(Request.QueryString[" ...

  5. DP套DP HDOJ 4899 Hero meet devil(国王的子民的DNA)

    题目链接 题意: 给n长度的S串,对于0<=i<=|S|,有多少个长度为m的T串,使得LCS(S,T) = i. 思路: 理解的不是很透彻,先占个坑. #include <bits/ ...

  6. solr4.3 java.lang.NumberFormatException

    solr java.lang.NumberFormatException 现象:定时每天全量,每隔5分钟增量DIH从mysql导入数据 solr4j返回加过Id列表,一天偶然出现 java.lang. ...

  7. C++常用特性原理解析

    在我的早期印象中,C++这门语言是软件工程发展过程中,出于对面向对象语言级支持不可或缺的情况下,一群曾经信誓旦旦想要用C统治宇宙的极客们妥协出来的一个高性能怪咖. 它驳杂万分,但引人入胜,出于多(mi ...

  8. python基础01 Hello World!

    摘要:简单的Hello Word! python 命令行 如已经安装python,那么在linux命令行中输入 $python 将进入python.乱吼在命令行提示符>>>后面输入 ...

  9. 调试台自动多出现一个'&#65279;' ,我 用uploadify上传图片时,在给页面写入一个返回值为图片名称的变量的值的时候值的前面始终多出现一个'&#65279;'

    对你有助请点赞,请顶,不好请踩------送人玫瑰,手留余香! 15:54 2016/3/12用uploadify上传图片时,在给页面写入一个返回值为图片名称的变量的值的时候值的前面始终多出现一个' ...

  10. 【枚举】POJ 3279

    直达–>POJ 3279 Fliptile 题意:poj的奶牛又开始作孽了,这回他一跺脚就会让上下左右的砖块翻转(1->0 || 0->1),问你最少踩哪些砖块才能让初始的砖块全部变 ...