热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

作者:Jack47

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

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

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

1. 一些小功能##

集合声明更简单###

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

Map> lookup = new HashMap>();

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

Map> lookup = new HashMap<>();

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

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

集合初始化更简单###

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

Set set = Sets.newHashSet("one", "two", "three");
Map 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 numbers = ImmutableSet.of(10, 30, 40, 50);

  2. 使用copyOf函数

    ImmutableSet another = ImmutableSet.copyOf(numberSet);

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

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

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

3. 新的集合类型##

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

MultiMap multiMap = HashMultiMap.create();

MultiMap###

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

Multiset###

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

Multiset 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 {
	public boolean apply(Customer customer) {
		return CustomerType.LOYAL == customer.getCustomerType();
	}
}
Collection loyalCustomers =  	Collections2.filter(customers, new LoyalCustomer());

filter函数的语法是:
Collection filter(Collection unfiltered, Predicate predicate)

内置的Predicate####

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

Predicate 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
微信打赏
Guava库介绍之集合(Collection)相关的API
支付宝打赏

推荐阅读
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
author-avatar
我我檬檬我我186
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有