003-guava 集合-不可变集合
一、概述
二、使用
2.1、不可变集合
1、为什么使用不可变集合
不可变对象有很多优点,包括:
当对象被不可信的库调用时,不可变形式是安全的;
不可变对象被多个线程调用时,不存在竞态条件问题
不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节);
不可变对象因为有固定不变,可以作为常量来安全使用。
所有Guava不可变集合的实现都不接受null值。我们对Google内部的代码库做过详细研究,发现只有5%的情况需要在集合中允许null元素,剩下的95%场景都是遇到null值就快速失败。如果你需要在不可变集合中使用null,请使用JDK中的Collections.unmodifiableXXX方法。更多细节建议请参考“使用和避免null”。
2、JDK中的Collections.unmodifiableXXX方法
// jdk
@Test
public void testJDKImmutable(){
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c"); //通过list创建一个不可变的unmodifiableList集合
List<String> unmodifiableList= Collections.unmodifiableList(list);
System.out.println(unmodifiableList); //通过list添加元素
list.add("ddd");
System.out.println("往list添加一个元素:"+list);
System.out.println("通过list添加元素之后的unmodifiableList:"+unmodifiableList); //通过unmodifiableList添加元素
unmodifiableList.add("eee");
System.out.println("往unmodifiableList添加一个元素:"+unmodifiableList);
}
输出
[a, b, c]
往list添加一个元素:[a, b, c, ddd]
通过list添加元素之后的unmodifiableList:[a, b, c, ddd] java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1055)
通过运行结果我们可以看出:虽然unmodifiableList不可以直接添加元素,但是我的list是可以添加元素的,而list的改变也会使unmodifiableList改变。
所以说Collections.unmodifiableList实现的不是真正的不可变集合。
3、Guava 的immutable集合
Guava提供了对JDK里标准集合类里的immutable版本的简单方便的实现,以及Guava自己的一些专门集合类的immutable实现。当你不希望修改一个集合类,
或者想做一个常量集合类的时候,使用immutable集合类就是一个最佳的编程实践。
注意:每个Guava immutable集合类的实现都拒绝null值。我们做过对Google内部代码的全面的调查,并且发现只有5%的情况下集合类允许null值,而95%的情况下
都拒绝null值。万一你真的需要能接受null值的集合类,你可以考虑用Collections.unmodifiableXXX。
immutable集合可以有以下几种方式来创建:
1、用copyOf方法, 譬如, ImmutableSet.copyOf(set)
2、使用of方法,譬如,ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)
3、使用Builder类
使用
@Test
public void testGuavaImmutable(){
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c"); //ImmutableList.copyOf
ImmutableList<String> imlist=ImmutableList.copyOf(list);
System.out.println("imlist:"+imlist); //ImmutableList.of
ImmutableList<String> imOflist=ImmutableList.of("peida","jerry","harry");
System.out.println("imOflist:"+imOflist); ImmutableSortedSet<String> imSortList=ImmutableSortedSet.of("a", "b", "c", "a", "d", "b");
System.out.println("imSortList:"+imSortList); list.add("baby");
//关键看这里是否imlist也添加新元素了
System.out.println("list添加新元素之后看imlist:"+imlist); ImmutableSet<Color> imColorSet =
ImmutableSet.<Color>builder()
.add(new Color(0, 255, 255))
.add(new Color(0, 191, 255))
.build(); System.out.println("imColorSet:"+imColorSet);
}
输出
imlist:[a, b, c]
imOflist:[peida, jerry, harry]
imSortList:[a, b, c, d]
list添加新元素之后看imlist:[a, b, c]
imColorSet:[java.awt.Color[r=0,g=255,b=255], java.awt.Color[r=0,g=191,b=255]]
智能的copyOf
copyOf方法比你想象的要智能,ImmutableXXX.copyOf会在合适的情况下避免拷贝元素的操作-先忽略具体的细节,但是它的实现一般都是很“智能”的。譬如:
@Test
public void testCotyOf(){
ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa");
System.out.println("imSet:"+imSet); //set直接转list
ImmutableList<String> imlist=ImmutableList.copyOf(imSet);
System.out.println("imlist:"+imlist); //list直接转SortedSet
ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet);
System.out.println("imSortSet:"+imSortSet); List<String> list=new ArrayList<String>();
for(int i=0;i<=10;i++){
list.add(i+"x");
}
System.out.println("list:"+list); //截取集合部分元素
ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 8));
System.out.println("imInfolist:"+imInfolist);
}
关联可变集合和不可变集合
| 可变集合接口 | 属于JDK还是Guava | 不可变版本 |
| Collection | JDK | ImmutableCollection |
| List | JDK | ImmutableList |
| Set | JDK | ImmutableSet |
| SortedSet/NavigableSet | JDK | ImmutableSortedSet |
| Map | JDK | ImmutableMap |
| SortedMap | JDK | ImmutableSortedMap |
| Multiset | Guava | ImmutableMultiset |
| SortedMultiset | Guava | ImmutableSortedMultiset |
| Multimap | Guava | ImmutableMultimap |
| ListMultimap | Guava | ImmutableListMultimap |
| SetMultimap | Guava | ImmutableSetMultimap |
| BiMap | Guava | ImmutableBiMap |
| ClassToInstanceMap | Guava | ImmutableClassToInstanceMap |
| Table | Guava | ImmutableTable |
反倒是
003-guava 集合-不可变集合的更多相关文章
- [Google Guava] 2.1-不可变集合
范例 01 public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( 02 "red&quo ...
- Java源码分析:Guava之不可变集合ImmutableMap的源码分析
一.案例场景 遇到过这样的场景,在定义一个static修饰的Map时,使用了大量的put()方法赋值,就类似这样-- public static final Map<String,String& ...
- Guava Immutable 不可变集合
Immutable是为了创建不可变集合使用,不可变集合在很多情况下能提高系统性能.一般使用 .of()或者.builder()<>().put().build()初始化创建不可变集合
- Guava学习笔记:Immutable(不可变)集合
不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对象有以下的优点: 1.对不可靠的客 ...
- java代码之美(4)---guava之Immutable(不可变)集合
Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...
- Immutable(不可变)集合
Immutable(不可变)集合 不可变集合,顾名思义就是说集合是不可被修改的.集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变. 为什么要用immutable对象?immutable对 ...
- Java中的不可变集合,我们换个方式理解!!!
不可变集合例: public static final ImmutableSet<String> COLOR_NAMES = ImmutableSet.of( "red" ...
- Object-C,NSSet,不可变集合
又到晚上了,继续码代码. 正在此时,老爸一个电话"海阔凭鱼跃,天高任鸟飞",老爸不在为老问题烦我了. 自由了,突然感觉压力好大啊. 将来混的太惨,可咋办啊- 第1个例子是,不可变集 ...
- 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?
==知识梳理== ==重难点梳理== ==今日目标== 1.能够了解什么是可变参数 2.能够了解如何去创建不可变集合 3.能够掌握Stream流的使用 ==知识点== 1.可变参数 2.Stream流 ...
随机推荐
- Spark-2.3.2 Java SparkSQL的自定义HBase数据源
由于SparkSQL不支持HBase的数据源(HBase-1.1.2),网上有很多是采用Hortonworks的SHC,而SparkSQL操作HBase自定义数据源大多数都是基于Scala实现,我就自 ...
- keras模块之-优化器(optimizers)--笔记
本笔记由博客园-圆柱模板 博主整理笔记发布,转载需注明,谢谢合作! 优化器是调整每个节点权重的方法,如: model = Sequential() model.add(Dense(64, init=' ...
- machine learning (7)---normal equation相对于gradient descent而言求解linear regression问题的另一种方式
Normal equation: 一种用来linear regression问题的求解Θ的方法,另一种可以是gradient descent 仅适用于linear regression问题的求解,对其 ...
- TVS瞬态抑制二极管选型指南
一.TVS二极管工作原理 TVS(Transient Voltage Suppressors)二极管,即瞬态电压抑制器,又称雪崩击穿二极管,是采用半导体工艺制成的单个PN结或多个PN结集成的器件.TV ...
- kth-largest-element
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...
- SpringBoot官方文档学习(一)SpringApplication
Springboot通过main方法启动,在许多情况下,委派给静态SpringApplication.run方法: public static void main(String[] args) { S ...
- 【shell】2、判断表达式、if语句
文件类型判断 test -e filename:该文件名是否存在 test -f filename:该文件名是否存在且为文件(file) test -d filename:该文件名是否存在且为目录(d ...
- PostgreSQL 抛出错误信息(错误行号)
抛出错误行号是我们在写SQL中常用到的,在SQL Server和Oracle中都很简单,但是在PostgreSQL怎么实现呢?在网上查了下资料只有pg_exception_context包含错误行,我 ...
- MySQL-linux系统下面的配置文件
一般linux 上都放在 /etc/my.cnf ,window 上安装都是默认可能按照上面的路径还是没找到, window 上 可以登录到mysql中 使用 show variables ...
- linux学习6 Linux系统组成及初始
一.linux发行版回顾 1.版本回顾 2.Linux基础 a.CPU架构 32位CPU: X86 64位CPU:X64因为最早的X64位CPU是amd公司生产的所以也叫 amd64(可以兼容X86) ...