使用Google Guava创建收藏和实现不变性

因此,我想看看番石榴提供的一些集合创建模式,以及它提供的某些不可变集合类型。

如果您没有看过我以前的文章,则可能要从这里开始:

番石榴第1部分– MultiMaps

番石榴第2部分– BiMaps

番石榴第3部分–多组

Guava的所有集合实现都包含一个或多个静态create方法,这些方法可以实现您所期望的,并且通常提供一种更为简洁的实例化集合类的方法。 这是创建ArrayListMultimap的两种不同方法

Multimap<String,String> multimap1 = new ArrayListMultimap<String,String>();Multimap<String,String> multimap2 = ArrayListMultimap.create();

好的,因此其中没有太多内容(在此示例中为12个字符),但是从我的角度来看,您正在删除一些冗余,我们真的需要两次重现泛型类型信息吗?

很好,很遗憾,Sun没想到在创建Java 5时向其Collection类型添加create方法!

同样,番石榴在这里为您提供帮助,并提供了一些用于处理标准集合类型的实用程序类。 com.google.common.collect.Lists , com.google.common.collect.Sets和com.google.common.collect.Maps

这些都提供了几种格式为new CollectionType () ,下面是一些示例

List<String> myList1 = new ArrayList<String>(); //old wayList<String> myList2 = Lists.newArrayList();    //guava waySet<String> mySet1 = new HashSet<String>(); //old waySet<String> mySet2 = Sets.newHashSet();     //guava way

由于“ new”方法是静态的,因此您可以通过使用静态导入来剪切出更多字符,即…

import static com.google.common.collect.Lists.newArrayList;import static com.google.common.collect.Sets.newHashSet;//elsewhere in codeList<String> myList2 = newArrayList();Set<String> mySet2 = newHashSet();

明智的按键方式是,使用番石榴方法并不能真正节省很多,所以我想这和其他任何东西都一样。 我个人认为,番石榴的方法读起来要好得多,尽管我认为我不会使用静态导入。

到目前为止,还不错,但是几乎没有崩溃的余地,下一步呢?

不变的收藏

这些本质上是集合对象,创建后就无法更改,并且出于各种原因很有用。 Guava为大多数常规Collection接口提供了Immutable实现: ImmutableList , ImmutableSet和ImmutableMap ,以及某些Guava集合接口( ImmutableMultimap等)的不可变实现。

我对它们的主要用途是创建静态常量。 例如,假设您出于某种目的需要对一组字符串进行硬编码。
一种做到这一点的方法可能是,例如。

private static final Set<String> farmAnimals =new HashSet<String>(Arrays.asList('Cow','Pig','Sheep'));

它看起来并不好看,并且存在一个主要问题。 任何可以访问此Set的代码都可以对其进行更改,这可能导致各种意外问题。

我们不能只使用Collection.unmodifiableSet(Set s)来解决这个问题吗?

好吧,在这个特定的例子中,我想我们可以写……

private static final Set<String> farmAnimals =Collections.unmodifiableSet(new HashSet<String>(Arrays.asList('Cow','Pig','Sheep')));

…但是这开始显得有些笨拙,而且无法unmodifiable方法还有另一个问题。 它们仅返回集合的不可修改视图,如果您引用原始集合,则仍然可以对其进行更改!

尽管在上一个示例中这可能不是问题,但我仍然认为更好的方法是使用ImmutableSet

private static final Set<String> farmAnimals = ImmutableSet.of('Cow','Pig','Sheep');

是不是更好呢! 还有其他几种创建它们的方法,下面是一些示例:

// use copyOf()...public void doStuffWithList(List<Object> unsafeList) {List<Object> safeList = ImmutableList.copyOf(unsafeList);}
// use a builder...public Map<String,Integer> makeImmutableMap() {ImmutableMap.Builder<String,Integer> mapBuilder = new ImmutableMap.Builder<String,Integer>();Entry<String,Integer> entry = null;while((entry = getEntry()) != null) {mapBuilder.put(entry.getKey(), entry.getValue());}return builder.build();}

那么,使用不可变集合还有其他优势吗?

好吧,有几个。 它们可以大大简化逻辑,尤其是在多线程环境中。 如果线程仅具有对对象的读取访问权限,则您无需担心复杂的线程同步逻辑

创建它们后,它们的使用效率也略有提高。 如果一个集合事先知道它需要存储什么,并且永远不会有任何变化,则可以节省各种时间和空间。 例如,大多数ArrayLists或HashMaps的实现都会为新对象保留一些未使用的空间,因此它们不必不断调整自身大小。 如果您知道永远不会有任何新对象,则无需这样做。

最后,您还可以将它们用作哈希键。 如果集合的内容无法更改,那么它的哈希码也不会改变!

有什么缺点吗?

当然,不可变对象有一个很大的缺点,那就是显而易见的。 您不能更改它们! 如果您需要更改集合,则首先需要对其进行复制。 在某些情况下(例如,并发性很重要),您实际上可能希望采用这种方法。 但是,在集合包含许多对象的情况下,这将是不切实际的,并且您可能需要一个老式的可变集合(如果需要,请完成同步代码)。

唯一需要注意的另一件事是,仅仅因为您的集合是不可变的,并不意味着它们中包含的对象是自动的。 如果可以在不可变集合中获得对对象的引用,那么没有什么可以阻止您更改该对象上的任何可变状态! 因此,最佳实践是确保您保存在不可变集合中的任何东西本身都是不可变的!

参考: Tom's Programming Blog博客上的JCG合作伙伴 Tom Jefferys从Google Guava创建的收藏和不变性 。

翻译自: https://www.javacodegeeks.com/2012/12/collection-creation-and-immutability-with-google-guava.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTMLCSS

HTML xml &#xff08;标签名&#xff09;可扩展标记语言 <Stu> </Stu> Html 超文本标记语言&#xff08;文本&#xff0c;图片&#xff0c;链接&#xff09; <> </> Internet网上编写页面&#xff08;H5版本&#xff1a;支持多种标签特性&…

Mysql报错130_mysql 突然报错,连接不上

错误如下&#xff0c; Access denied for user rootlocalhost (using password关掉mysql服务&#xff0c;重新启动如果不行&#xff0c;那应该就是密码被改了&#xff0c;密码不对应1.以系统管理员身份运行cmd.2.查看mysql是否已经启动&#xff0c;如果已经启动&#xff0c;就停…

为内存密集型应用程序转义JVM堆

如果您曾经分配过大的Java堆&#xff0c;您就会知道在某个时候&#xff08;通常从大约4 GiB开始&#xff09;&#xff0c;您将开始遇到垃圾回收暂停的问题。 我不会详细介绍为什么在JVM中会出现暂停&#xff0c;但是总之&#xff0c;当JVM进行完整的收集并且您有很大的堆时&am…

MySQL学习笔记1(增删查改)

创建表&#xff1a; /*创建数据库create database 数据库名; */ CREATE DATABASE mybase; /*使用数据库use 数据库名 */ USE mybase;/*创建数据表的格式create table 表名(列名1 数据类型 约束,列名2 数据类型 约束,列名3 数据类型 约束);创建用户表,用户编号,姓名,用户的地址将…

Angular4 中内置指令的基本用法

ngFor 作用&#xff1a;像 for 循环一样&#xff0c;可以重复的从数组中取值并显示出来。 // .tsthis.userInfo [张三, 李四, 王五];// .html<div class"ui list" *ngFor"let username of userInfo"><div class"item">{{username}}…

初入编程的新世界

准备跨入程序员的行列了&#xff0c; 今天开课第一天&#xff0c; 算起来之前学习的几天&#xff0c; 第一次真正的了解了网页制作包括什么&#xff0c; html&#xff08;结构&#xff09;&#xff0c;css&#xff08;页面美化 层叠样式表&#xff09;&#xff0c;JavaScri…

java中i+=2什么意思_三分钟看懂Java中i++与++i的性能差别以及循环中如何使用

在Java中&#xff0c;自增是一种非常常见的操作&#xff0c;在自增中&#xff0c;有两种写法&#xff0c;一种是前缀自增(i)&#xff0c;一种是后缀自增(i)。这里主要简单介绍两种自增的差别。一、含义差别前缀自增和后缀自增是不同的。前缀自增(i)是从内存中加载i&#xff0c;…

Java / JEE中的有效日志记录–映射的诊断上下文

当我和一位同事坐在一起解决一些应用程序问题时&#xff0c;一切都开始了&#xff0c;当时我注意到了一些有趣的事情。 他正在合并代码&#xff0c;我的眼睛吸引了此类“ org.apache.log4j.MDC”的注意。 这导致了以下发现&#xff1a; 什么是MDC&#xff1f; MDC代表“ 映射诊…

bzoj1049[HAOI2006]数字序列

1049: [HAOI2006]数字序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1813 Solved: 789[Submit][Status][Discuss]Description 现在我们有一个长度为n的整数序列A。但是它太不好看了&#xff0c;于是我们希望把它变成一个单调严格上升的序列。但是不希望改变过多的数&…

具有Aspects的Java中的Mixin –用于Scala特性示例

Scala特征允许将新行为混合到一个类中。 考虑两个特征&#xff0c;可以向JPA实体添加审核和与版本相关的字段&#xff1a; package mvcsample.domainimport javax.persistence.Version import scala.reflect.BeanProperty import java.util.Datetrait Versionable {VersionBea…

前端:HTML

1,web服务的本质 import socketsk socket.socket()sk.bind(("127.0.0.1", 8080)) sk.listen(5)while True:conn, addr sk.accept()data conn.recv(8096)conn.send(b"HTTP/1.1 200 OK\r\n\r\n")conn.secd(b"<h1>Hello world!</h1>"…

动态规划:从新手到专家

作者&#xff1a;Hawstein出处&#xff1a;http://hawstein.com/posts/dp-novice-to-advanced.html前言 本文翻译自TopCoder上的一篇文章&#xff1a; Dynamic Programming: From novice to advanced &#xff0c;并非严格逐字逐句翻译&#xff0c;其中加入了自己的一些理解。水…

小程序 foreach_【第2106期】小程序依赖分析实践

前言这种可视化分析图还是很直观的&#xff0c;很有趣。今日早读文章由自然醒授权分享。正文从这开始~~用过 webpack 的同学肯定知道 webpack-bundle-analyzer &#xff0c;可以用来分析当前项目 js 文件的依赖关系。webpack-bundle-analyzer因为最近一直在做小程序业务&#x…

python----模块

collections---------------------------------------->扩展数据类型 re-------------------------------------------------->正则相关操作&#xff0c;正则 匹配字符串 time----------------------------------------------->时间相关 三种格式&#xff1a;时间戳&…

在MySQL数据库上使用Quartz Scheduler入门

这是一些简单的步骤&#xff0c;可帮助您使用Groovy在MySQL数据库上完全入门Quartz Scheduler。 以下脚本可让您使用外部文件快速尝试不同的Quartz配置设置。 第一步是使用表设置数据库。 假设您已经安装了MySQL&#xff0c;并且有权创建数据库和表。 bash> mysql -u root …

一招搞定css页面布局

如何做出漂亮的页面&#xff1a; 1、 多写页面&#xff0c;多改。 2、 多写页面&#xff0c;多改。 3、 多写页面&#xff0c;多改。 大致的思想步骤&#xff1a; 写页面的时候先规划好大致的分块&#xff0c;无论是用定位或者浮动&#xff0c;首先要确定要应用的场景&#xf…

mysql blob取值_MySQL 数据类型:

MySQL 数据类型&#xff1a;字符型数值型日期时间型内建类型字符型&#xff1a;CHAR, BINARY&#xff1a;定长数据类型&#xff1b;VARCHAR, VARBINARY&#xff1a;变长数据类型&#xff1b;需要结束符&#xff1b;TEXT&#xff1a;TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXTBLOB: …

MySQL 中的三中循环 while loop repeat 的基本用法

-- MySQL中的三中循环 while 、 loop 、repeat 求 1-n 的和-- 第一种 while 循环 -- 求 1-n 的和 /* while循环语法&#xff1a; while 条件 DO循环体; end while; */ -- 实例&#xff1a; create procedure sum1(a int) begindeclare sum int default 0; -- default 是指…

css渲染(二) 文本

一、文本样式 首行缩进  text-indent 首行缩进是将段落的第一行缩进&#xff0c;这是常用的文本格式化效果。一般地&#xff0c;中文写作时开头空两格。[注意]该属性可以为负值&#xff1b;应用于: 块级元素(包括block和inline-block)  <div><p style"text-in…

RTKLIB的主要功能

RTKLIB是全球导航卫星系统GNSS(global navigation satellite system)的标准&精密定位开源程序包&#xff0c;RTKLIB由日本东京海洋大学&#xff08;Tokyo University of Marine Science and Technology&#xff09;的高须知二&#xff08;Tomoji Takasu&#xff09;开发。R…