Guava库介绍之集合(Collection)相关的API

作者: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写作,打赏一个鸡蛋灌饼钱吧
pay_weixin
微信打赏
pay_alipay
支付宝打赏
Guava 是一个 Google 的基于java1.6的类集合的扩展项目,包括 collections, caching, primitives support, concurrency libraries, common annotations, string processing, I/O, 等等. 这些高质量的 API 可以使你的JAVa代码更加优雅,更加简洁,让你工作更加轻松愉悦。下面我们就开启优雅Java编程学习之旅!   项目相关信息:   官方首页:http://code.google.com/p/guava-libraries   官方下载:http://code.google.com/p/guava-libraries/downloads/list   官方文档:http://docs.guava-libraries.googlecode.com/git/javadoc http://www.ostools.net/apidocs/apidoc?api=guava   源码包的简单说明:   com.google.common.annotations:普通注解类型。   com.google.common.base:基本工具类和接口。   com.google.common.cache:缓存工具包,非常简单易用且功能强大的JVM内缓存。   com.google.common.collect:带泛型的集合接口扩展和实现,以及工具类,这里你会发现很多好玩的集合。   com.google.common.eventbus:发布订阅风格的事件总线。   com.google.common.hash: 哈希工具包。   com.google.common.io:I/O工具包。   com.google.common.math:原始算术类型和超大数的运算工具包。   com.google.common.net:网络工具包。   com.google.common.primitives:八种原始类型和无符号类型的静态工具包。   com.google.common.reflect:反射工具包。   com.google.common.util.concurrent:多线程工具包。   类使用手册:   一. 基本工具类:让使用Java语言更令人愉悦。   1. 使用和避免 null:null 有语言歧义, 会产生令人费解的错误, 反正他总是让人不爽。很多 Guava 的工具类在遇到 null 时会直接拒绝或出错,而不是默默地接受他们。   2. 前提条件:更容易的对你的方法进行前提条件的测试。   3. 常见的对象方法: 简化了Object常用方法的实现, 如 hashCode() 和 toString()。   4. 排序: Guava 强大的 "fluent Comparator"比较器, 提供多关键字排序。   5. Throwable类: 简化了异常检查和错误传播。   二. 集合类:集合Guava 对 JDK 集合类的扩展, 这是 Guava 项目最完善和为人所知的部分。   1. Immutable collections(不变的集合): 防御性编程, 不可修改的集合,并且提高了效率。   2. New collection types(集合类型):JDK collections 没有的一些集合类型,主要有:multisets,multimaps,tables, bidirectional maps等等   3. Powerful collection utilities(强大的集合工具类): java.util.Collections 中未包含的常用操作工具类   4. Extension utilities(扩展工具类): 给 Collection 对象添加一个装饰器? 实现迭代器? 我们可以更容易使用这些方法。   三. 缓存: 本地缓存,可以很方便的操作缓存对象,并且支持各种缓存失效行为模式。   四. Functional idioms(函数式): 简洁, Guava实现了Java的函数式编程,可以显著简化代码。   五. Concurrency(并发):强大,简单的抽象,让我们更容易实现简单正确的并发性代码。   1. ListenableFuture(可监听的Future): Futures,用于异步完成的回调。   2. Service: 控制事件的启动和关闭,为你管理复杂的状态逻辑。   六. Strings: 一个非常非常有用的字符串工具类: 提供 splitting,joining, padding
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值