Immutable(不可变)集合

拥抱Guava之集合操作 深入了解Google Guava库的集合操作功能,本文介绍了其强大的特性,包括不可变集合和高效工具类。通过实例演示,为Java开发者提供全面的集合操作解决方案 阅读详情

原来来自 :http://www.cnblogs.com/peida/p/Guava_ImmutableCollections.html

不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。

  为什么要用immutable对象?immutable对象有以下的优点:
    1.对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象
    2.线程安全的:immutable对象在多线程下安全,没有竞态条件
    3.不需要支持可变性, 可以尽量节省空间和时间的开销. 所有的不可变集合实现都比可变集合更加有效的利用内存 (analysis)
    4.可以被使用为一个常量,并且期望在未来也是保持不变的

  immutable对象可以很自然地用作常量,因为它们天生就是不可变的对于immutable对象的运用来说,它是一个很好的防御编程(defensive programming)的技术实践。

  JDK中实现immutable集合

  在JDK中提供了Collections.unmodifiableXXX系列方法来实现不可变集合, 但是存在一些问题,下面我们先看一个具体实例:

复制代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;

public class ImmutableTest {
    @Test
    public void testJDKImmutable(){                                                                                                                                                                                                                                    
        List<String> list=new ArrayList<String>();                                                                               
        list.add("a");                                                                                                           
        list.add("b");                                                                                                           
        list.add("c");
        
        System.out.println(list);
        
        List<String> unmodifiableList=Collections.unmodifiableList(list); 
        
        System.out.println(unmodifiableList);
        
        List<String> unmodifiableList1=Collections.unmodifiableList(Arrays.asList("a","b","c")); 
        System.out.println(unmodifiableList1);
        
        String temp=unmodifiableList.get(1);
        System.out.println("unmodifiableList [0]:"+temp);
                
        list.add("baby");
        System.out.println("list add a item after list:"+list);
        System.out.println("list add a item after unmodifiableList:"+unmodifiableList);
        
        unmodifiableList1.add("bb");
        System.out.println("unmodifiableList add a item after list:"+unmodifiableList1);
        
        unmodifiableList.add("cc");
        System.out.println("unmodifiableList add a item after list:"+unmodifiableList);        
    }
}
复制代码

  输出:

复制代码
[a, b, c]
[a, b, c]
[a, b, c]
unmodifiableList [0]:b
list add a item after list:[a, b, c, baby]
list add a item after unmodifiableList1:[a, b, c, baby]
复制代码

  说明:Collections.unmodifiableList实现的不是真正的不可变集合,当原始集合修改后,不可变集合也发生变化。不可变集合不可以修改集合数据,当强制修改时会报错,实例中的最后两个add会直接抛出不可修改的错误。

  总结一下JDK的Collections.unmodifiableXXX方法实现不可变集合的一些问题:

  1.它用起来笨拙繁琐你不得不在每个防御性编程拷贝的地方用这个方法
  2.它不安全:如果有对象reference原始的被封装的集合类,这些方法返回的集合也就不是正真的不可改变。
  3.效率低:因为它返回的数据结构本质仍旧是原来的集合类,所以它的操作开销,包括并发下修改检查,hash table里的额外数据空间都和原来的集合是一样的。

  Guava的immutable集合

  Guava提供了对JDK里标准集合类里的immutable版本的简单方便的实现,以及Guava自己的一些专门集合类的immutable实现。当你不希望修改一个集合类,或者想做一个常量集合类的时候,使用immutable集合类就是一个最佳的编程实践。

注意:每个Guava immutable集合类的实现都拒绝null值。我们做过对Google内部代码的全面的调查,并且发现只有5%的情况下集合类允许null值,而95%的情况下都拒绝null值。万一你真的需要能接受null值的集合类,你可以考虑用Collections.unmodifiableXXX。

  Immutable集合使用方法:
  一个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");
        System.out.println("list:"+list);
        
        ImmutableList<String> imlist=ImmutableList.copyOf(list);
        System.out.println("imlist:"+imlist);
        
        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");
         System.out.println("list add a item after list:"+list);
         System.out.println("list add a item after 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);       
    }
复制代码

  输出:

复制代码
list:[a, b, c]
imlist:[a, b, c]
imOflist:[peida, jerry, harry]
imSortList:[a, b, c, d]
list add a item after list:[a, b, c, baby]
list add a item after imlist:[a, b, c]
imColorSet:[java.awt.Color[r=0,g=255,b=255], java.awt.Color[r=0,g=191,b=255]]
复制代码

  对于排序的集合来说有例外,因为元素的顺序在构建集合的时候就被固定下来了。譬如,ImmutableSet.of("a", "b", "c", "a", "d", "b"),对于这个集合的遍历顺序来说就是"a", "b", "c", "d"。

  更智能的copyOf

  copyOf方法比你想象的要智能,ImmutableXXX.copyOf会在合适的情况下避免拷贝元素的操作-先忽略具体的细节,但是它的实现一般都是很“智能”的。譬如:

复制代码
@Test
    public void testCotyOf(){
        ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa");
        System.out.println("imSet:"+imSet);
        ImmutableList<String> imlist=ImmutableList.copyOf(imSet);
        System.out.println("imlist:"+imlist);
        ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet);
        System.out.println("imSortSet:"+imSortSet);
        
        List<String> list=new ArrayList<String>();
        for(int i=0;i<20;i++){
            list.add(i+"x");
        }
        System.out.println("list:"+list);
        ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 18));
        System.out.println("imInfolist:"+imInfolist);
        int imInfolistSize=imInfolist.size();
        System.out.println("imInfolistSize:"+imInfolistSize);
        ImmutableSet<String> imInfoSet=ImmutableSet.copyOf(imInfolist.subList(2, imInfolistSize-3));
        System.out.println("imInfoSet:"+imInfoSet);
    }
复制代码

  输出: 

复制代码
imSet:[peida, jerry, harry, lisa]
imlist:[peida, jerry, harry, lisa]
imSortSet:[harry, jerry, lisa, peida]
list:[0x, 1x, 2x, 3x, 4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x, 15x, 16x, 17x, 18x, 19x]
imInfolist:[2x, 3x, 4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x, 15x, 16x, 17x]
imInfolistSize:16
imInfoSet:[4x, 5x, 6x, 7x, 8x, 9x, 10x, 11x, 12x, 13x, 14x]
复制代码

  在这段代码中,ImmutableList.copyOf(imSet)会智能地返回时间复杂度为常数的ImmutableSet的imSet.asList()。
  一般来说,ImmutableXXX.copyOf(ImmutableCollection)会避免线性复杂度的拷贝操作。如在以下情况:
  这个操作有可能就利用了被封装数据结构的常数复杂度的操作。但例如ImmutableSet.copyOf(list)不能在常数复杂度下实现。
  这样不会导致内存泄漏-例如,你有个ImmutableList<String> imInfolist,然后你显式操作ImmutableList.copyOf(imInfolist.subList(0, 10))。这样的操作可以避免意外持有不再需要的在hugeList里元素的reference。
  它不会改变集合的语意-像ImmutableSet.copyOf(myImmutableSortedSet)这样的显式拷贝操作,因为在ImmutableSet里的hashCode()和equals()的含义和基于comparator的ImmutableSortedSet是不同的。
  这些特性有助于最优化防御性编程的性能开销。

  asList方法

  所有的immutable集合都以asList()的形式提供了ImmutableList视图(view)。譬如,你把数据放在ImmutableSortedSet,你就可以调用sortedSet.asList().get(k)来取得前k个元素的集合。
  返回的ImmutableList常常是个常数复杂度的视图,而不是一个真的拷贝。也就是说,这个返回集合比一般的List更智能-譬如,它会更高效地实现contains这样的方法。

  实例:

复制代码
@Test
    public void testAsList(){
        ImmutableList<String> imList=ImmutableList.of("peida","jerry","harry","lisa","jerry");
        System.out.println("imList:"+imList);
        ImmutableSortedSet<String> imSortList=ImmutableSortedSet.copyOf(imList);
        System.out.println("imSortList:"+imSortList);
        System.out.println("imSortList as list:"+imSortList.asList());
    }
复制代码

  输出:

imList:[peida, jerry, harry, lisa, jerry]
imSortList:[harry, jerry, lisa, peida]
imSortList as list:[harry, jerry, lisa, peida]

  Guava集合和不可变对应关系

可变集合类型 可变集合源:JDK or Guava? 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


【开发工具-Guava】新集合类型 Guava引入了很多JDK没有的、但我们发现明显有用的新集合类型。这些新类型是为了和JDK集合框架共存,而没有往JDK集合抽象中硬塞其他概念。作为一般规则,Guava集合非常精准地遵循了JDK接口契约。 阅读详情

相关推荐

四十二、Fluent欧拉模型流化床模拟:从基础设置到颗粒动力学解析

本文详细解析了Fluent欧拉模型在流化床模拟中的应用,从基础概念到颗粒动力学设置全面覆盖。重点介绍了欧拉模型的颗粒温度概念、多相流配置技巧以及关键参数优化策略,帮助工程师准确模拟气固两相流动现象。通过实用案例演示了网格检查、求解器配置和边界条件设置的最佳实践。

weixin_27303545的博客 445

Guava学习笔记:Immutable(不可变)集合

  不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。   为什么要用immutable对象?immutable对象有以下的优点:     1.对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象    2.线程安全的:immutable对象在多线程下安全,没有竞态条件    3.不需要支持可变性, 可以尽量...

weixin_34144450的博客 392

基于CANopenNode协议栈在正点原子探索者开发板上进行移植

配置好之后进行采用keil IDE进行代码生成即可,还需要进行CANopenNode的代码集成,并参照demo进行代码移植。发送完成后心跳包以1s的周期重新开始发送。正点原子的开发板引出的是CAN1接口。这里的心跳时间间隔设置为100ms。则将心跳包周期设置为0。

wangfandashe的博客 4700

Guava中ImmutableList的copyOf使用-将map转化为list方便遍历

代码】Guava中ImmutableList的copyOf使用-将map转化为list方便遍历。

weixin_43356308的博客 845

DRAM 埋入式字线(Buried Wordline)技术深度解析:从二维平面到三维凹槽

埋入式字线(bWL)及其核心的埋入式沟道阵列晶体管(BCAT)架构,无疑是 DRAM 发展史上的一次关键性革命。它在约 40nm 技术节点被行业主流采纳,成功地帮助 DRAM 产业克服了传统平面晶体管的物理缩放极限。力挽狂澜的续命技术:bWL 通过引入三维沟道结构,从根本上解决了由短沟道效应和漏电流失控引发的数据保持危机,为经典的 1T1C(单晶体管 - 单电容)DRAM 单元架构延续了超过十年的生命力。协同优化的基石技术。

m0_37606066的博客 3333

AI编程实战:用Spec Coding与Codex半小时重构全栈项目

这次我们来看一个能显著提升全栈开发效率的实战方法:利用 AI 编程工具 Codex 和 Spec Coding 工作流,将原本需要数周甚至一个月的全栈项目重构工期,压缩到半小时级别。这不是概念探讨,而是基于现有工具链的、可立即上手的工程实践。 对于前端开发者或全栈工程师而言,面对老旧项目重构、技术栈升级或从零搭建新项目时,最大的痛点往往是重复性、模式化的代码编写工作。手动编写 CRUD 接口、页面组件、状态管理和联调测试,耗时费力且容易出错。而 AI 辅助编程的核心价值,正是在于将开发者从这些“体力活”中解

weixin_33525298的博客 290

guava中ImmutableList使用示例详解

ImmutableList是一个不可变、线程安全的列表集合,它只会获取传入对象的一个副本,而不会影响到原来的变量或者对象; 验证上面的说法代码: int a = 23; ImmutableList&amp;amp;amp;lt;Integer&amp;amp;amp;gt; list = ImmutableList.of(a, 12); System.out.println(list); ...

OceanSky的专栏 2万+

Rocky Linux 9 离线环境Docker部署实战:从依赖打包到服务启动

本文提供了一份详尽的Rocky Linux 9离线环境Docker部署实战指南。针对无法访问外网的生产或内网服务器,文章详细讲解了如何在联网跳板机上下载Docker二进制包及所有系统依赖RPM包,并完成打包。随后,手把手指导在离线服务器上进行依赖安装、二进制文件部署、systemd服务配置、SELinux与防火墙调优,最终实现Docker服务的成功启动与验证。

weixin_28363123的博客 138

guava之Immutable(不可变)集合

java代码之美(4)---guava之Immutable(不可变)集合 Immutable(不可变)集合 一、概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开。Collections是jdk提供的一个工具类。 Guava中不可变对象和Collections工具类的unmodifiableSet...

wienne0417的专栏 246

实干派!网易易盾增强版滑块验证码,全方位讲解识别思路(含源码)

该验证码是异形滑块验证码中的一种,缺口旋转+偏移的处理需要你有很好的图像处理知识,能很好的处理透明通道,同时,该验证码需要你能很好的处理缺口和背景之间匹配的关系,该验证码的处理难点就是两个缺口之间如何找到正确的,两个检测框都有很强的相似度,且加上背景图的干扰,在图像处理和有优化上难度大大增加。

码王吴彦祖的博客 2016

开源3D激光SLAM算法的异同点、优劣势与适配场景总结

本文对比分析了主流开源3D激光SLAM方案的核心差异与适用场景。LOAM架构简洁但精度较低;LeGO-LOAM轻量化适合地面机器人;LIO-SAM采用因子图优化支持多传感器融合;LVI-SAM通过视觉-激光-惯性三重冗余提升鲁棒性;FAST-LIO系列基于滤波架构实现超高实时性。选型需权衡传感器配置(纯激光/激光+IMU/激光+视觉)、运动状态(高速/常规)、计算资源等因素:资源受限选LeGO-LOAM或Faster-LIO,高速运动选FAST-LIO系列,退化环境选LVI-SAM,全局一致性需求选LIO-

Studying…… 651

《Guava学习笔记之一》:不可变集合Immutable

《Guava学习笔记之一》:不可变集合ImmutableGuava,简单来说,就是一些类库,来简化我们常用的一些操作的实现。在学习Guava之前,先看一个场景。这样可以让我们先对这样一个类库有一个感性的认识。现在一个方法,接受list作为参数,当这个方法被调用的时候,我们需要检查list是不是null和是不是空,一般的java解决方案如下所示: public void doSomething(

wojiushimogui的博客 1506

【用unity实现100个游戏之1】制作类元气骑士、挺进地牢——俯视角射击游戏多种射击效果(一)(附源码)

俯视角射击游戏)是一类以俯视视角进行游戏展示的射击游戏。在这种游戏中,玩家控制着一个角色或载具,从俯视的角度上方观察游戏世界,并与敌人进行战斗。这种视角使玩家能够有更好的全局观察和策略性,同时也强调快速反应和精确射击。视角:俯视角度可以是固定的,也可以随着玩家角色的移动而变化,但都允许玩家以全局视角观察整个战场,有利于制定战略和规划行动。射击:玩家通常需要使用各种武器来与敌人进行战斗,包括枪械、爆炸物等。射击动作依赖于玩家的反应速度和准确性。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 7833

immutablelist java_理解不可变集合 | Guava Immutable与JDK unmodifiableList

1、为什么需要不可变集合(1)保证线程安全:在并发程序中,使用Immutable既保证线程安全性,也大大增强了并发时的效率(跟并发锁方式相比)。尤其当一个对象是值对象时,更应该考虑采用Immutable方式;(2)被不可信的类库使用时会很安全;(3)如果一个对象不需要支持修改操作(mutation),将会节省空间和时间的开销;经过分析,所有不可变的集合实现都比可变集合更加有效地利用内存;(4)可以...

weixin_39887577的博客 1663

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Immutable不可变集合

Immutable修饰集合和map时初始化后不可变,线程安全效率高

Hawking_Liang的博客 183

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Guava学习笔记(六):Immutable(不可变)集合

不可变集合,顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。   为什么要用immutable对象?immutable对象有以下的优点:     1.对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象     2.线程安全的:immutable对象在多线程下安全,没有竞态条件     3.不需要支持可变性, 可以尽量节...

liinux-Talk is cheap,show me the code. 566

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

为什么选择immutable?5个理由让你爱上Go不可变集合

在Go语言开发中,处理数据集合时常常面临并发安全、状态管理和性能优化等挑战。**immutable**作为专为Go设计的不可变集合库,通过其独特的设计理念和实现方式,为开发者提供了更安全、高效的数据处理方案。本文将深入探讨选择immutable的5个核心理由,帮助你理解为什么它能成为Go项目中的得力助手。 ## 1. 天生线程安全,告别并发烦恼 🛡️ 并发编程中,数据竞争是最常见的问题之一。

gitblog_00365的博客 832

不可变集合Immutable

不可变集合,集合是不可变的,不可修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中不可以改变。 为什么要用immutable对象?immutable对象有以下的优点:     1.对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象     2.线程安全的:immutable对象在多线程下安全,没有竞态条件     3.不需要支持可变性, 可以尽量节

xuaomo的博客 3160

Guava之Immutable(不可变)集合

一、概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开。Collections是jdk提供的一个工具类。 Guava中不可变对象和Collections工具类的unmodifiableSet/List/Map/etc的区别: 当Collections创建的不可变集合的wrapper类改变的时候,不可变集合...

luzhensmart的专栏 289

EcoPaste 项目中的 Trellis 平台文件体系:从 `.kiro/` 到 `.trellis/` 的适配层实战指南

Trellis 是一套把同一套本地架构接入不同 AI 工具的协作运行时:`.trellis/` 存放共享运行状态(workflow、tasks、spec、scripts),而 `.claude/`、`.codex/`、`.kiro/` 等平台目录则存放"适配文件",负责让对应的 AI 工具能读到 Trellis 状态、调用 Trellis 脚本、加载 Trellis 的 skills/agents

gitblog_01103的博客 737

java代码之美(4)---guava之Immutable(不可变)集合

Immutable(不可变)集合   一、概述       guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开。Collections是jdk提供的一个工具类。       Guava中不可变对象和Collections工具类的unmodifiableSet/List/Map/etc的区别: 当Collections创建的不可变集...

后端元宇宙 436
上一篇: Preconditions优雅的检验参数
下一篇: mysql中交集,并集,差集,左连接,右连接
SnakeMoving
博客等级 码龄11年 65粉丝 97原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值