不可变集合

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

为什么要用immutable对象?
线程安全的:immutable对象在多线程下安全
不需要支持可变性, 可以尽量节省空间和时间的开销. 所有的不可变集合实现都比可变集合更加有效的利用内存
可以被使用为一个常量,并且期望在未来也是保持不变的


jdk中的不可变集合API
在JDK中提供了Collections.unmodifiableXXX系列方法来实现不可变集合, 但是存在一些问题,下面我们先看一个具体实例:
public static void testUnmodifiableList(){
        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 unmodifiableList:[a, b, c, baby]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.Collections$UnmodifiableCollection.add(Unknown Source)
	at com.meizu.tv.app.web.stats.Test.testUnmodifiableList(Test.java:44)
	at com.meizu.tv.app.web.stats.Test.main(Test.java:16)

说明:Collections.unmodifiableList实现的不是真正的不可变集合,当原始集合修改后,不可变集合也发生变化。不可变集合不可以修改集合数据,当强制修改时会报错,实例中的最后两个add会直接抛出不可修改的错误。
而且效率低,因为它返回的数据结构本质仍旧是原来的集合类,所以它的操作开销,包括并发下修改检查和原来的集合是一样的。

源码分析:
        final List list;

        UnmodifiableList(List list1)
        {
            super(list1);
            list = list1;
        }


        public boolean add(Object obj)
        {
            throw new UnsupportedOperationException();
        }


        public boolean remove(Object obj)
        {
            throw new UnsupportedOperationException();
        }
Guava的immutable集合
一个immutable集合可以有以下几种方式来创建:
(1)用copyOf方法, 譬如, ImmutableSet.copyOf(set)
(2)使用of方法,譬如,ImmutableSet.of("a", "b", "c")或者ImmutableMap.of("a", 1, "b", 2)
(3)使用Builder类

        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);
        imlist.add("D");
        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]]
源码分析:

 public static ImmutableList copyOf(Collection elements)
    {
        if(elements instanceof ImmutableCollection)
        {
            ImmutableList list = ((ImmutableCollection)elements).asList();
            return list.isPartialView() ? asImmutableList(list.toArray()) : list;
        } else
        {
            return construct(elements.toArray());
        }
    }
 java.util.Map.Entry entries[] = (java.util.Map.Entry[])map.entrySet().toArray(EMPTY_ENTRY_ARRAY);
从上面就可以看出ImmutableCollection是把集合中的内容取出来再封装一次,这就解释了为什么可以是Immutable。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值