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

来源:互联网 发布:51单片机控制继电器 编辑:程序博客网 时间:2024/06/05 02:12

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

Guava,简单来说,就是一些类库,来简化我们常用的一些操作的实现。

在学习Guava之前,先看一个场景。这样可以让我们先对这样一个类库有一个感性的认识。

现在一个方法,接受list作为参数,当这个方法被调用的时候,我们需要检查list是不是null和是不是空,一般的java解决方案如下所示:

    public void doSomething( List<Object> list ) {      if( list == null ) {        throw new IllegalArgumentException( "List must not be null" );      }      if( list.isEmpty() ) {        throw new IllegalArgumentException( "List must not be empty" );      }      doSomethingMore( list );    }

当使用guava的预判断,代码的数量明显减少,解决方案如下所示.

    public void doSomething( List<Object> list ) {      checkArgument( list != null, "List must not be null" );      checkArgument( !list.isEmpty(), "List must not be empty" );      doSomethingMore( list );    }

看到guava的解决方案,是不是很爽,很霸气。guava在很多方面都为我们编写简洁的代码提供了便利。

关于Guava在这篇博文中,有一个比较详细的介绍:http://www.cnblogs.com/snidget/archive/2013/02/05/2893344.html

在并发编程网:http://ifeve.com/google-guava/也有关于guava的详细介绍。

以下是自己学习guava的一点学习笔记。本篇博文先来看下不可变集合Immutable.

Immutable(不可变)集合

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

为什么要用Immutable对象?Immutable对象有以下的优点:

1.对不可靠的客户代码库来说,它使用安全,可以在未受信任的类库中安全的使用这些对象

2.线程安全的:Immutable对象在多线程下安全,没有竞态条件

3.不需要支持可变性, 可以尽量节省空间和时间的开销. 所有的不可变集合实现都比可变集合更加有效的利用内存 (analysis)
    

4.可以被使用为一个常量,并且期望在未来也是保持不变的

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

在JDK中提供了Collections.unmodifiableXXX系列方法来实现不可变集合, 但是存在一些问题,看一个例子

    @Test    public void testUnmodifiableCollection(){        List<String> list = Lists.newArrayList("a","b","c");        List<String> unmodifyList = Collections.unmodifiableList(list);        System.out.println(unmodifyList);        //unmodifyList.add("d"); //抛异常        list.add("e");        System.out.println(unmodifyList);    }

输出结果如下:

[a, b, c][a, b, c, e]

从以上可以看出,Collections.unmodifiableList实现的不是真正的不可变集合,当原始集合修改后,不可变集合也发生变化。不可变集合不可以修改集合数据,当强制修改时会报错,实例中的unmodifyList.add(“d”);会直接抛出不可修改的错误。

Guava的Immutable集合

  Guava提供了对JDK里标准集合类里的Immutable版本的简单方便的实现,例如:ImmutableList、ImmutableList等,以及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 testImmutable(){        List<String> list = Lists.newArrayList("a","b","c");        ImmutableList<String> imList = ImmutableList.copyOf(list);        System.out.println(imList);        list.add("d");        System.out.println("修改原始集合之后,imList的内容为:"+imList);        ImmutableList<String> imOfList = ImmutableList.of("wo", "jiu","shi","mogui");        System.out.println(imOfList);        ImmutableSet<String> imBuildSet = ImmutableSet.<String>builder().add("hello")                .add("world").build();        System.out.println(imBuildSet);    }

输出结果

[a,b,c][a,b,c]

从这里可以看出,Immutable集合是不会随着原始集合的改变而改变的。

比想象中更智能的copyOf

请注意,ImmutableXXX.copyOf方法会尝试在安全的时候避免做拷贝——实际的实现细节不详,但通常来说是很智能的。例如:

    ImmutableSet<String> foobar = ImmutableSet.of("foo", "bar", "baz");     thingamajig(foobar);     void thingamajig(Collection<String> collection) {        ImmutableList<String> defensiveCopy = ImmutableList.copyOf(collection);        ...    }

在这段代码中,ImmutableList.copyOf(foobar)会智能地直接返回foobar.asList(),它是一个ImmutableSet的常量时间复杂度的List视图。

asList视图

asList方法是在ImmutableCollection中定义,而所有的不可变集合都会从ImmutableCollection继承,所以所有的不可变集合都会有asList()方法返回当前不可变集合的list视图,这个视图也是不可变的。因此所有不可变集合都可以用asList()方法来获得ImmutableList视图,来帮助我们用列表形式方便地读取集合元素。例如,你可以使用sortedSet.asList().get(k)从ImmutableSortedSet中读取第k个最小元素。

asList()返回的ImmutableList通常是——并不总是——开销稳定的视图实现,而不是简单地把元素拷贝进List。也就是说,asList返回的列表视图通常比一般的列表平均性能更好。

参考资料

1、http://ifeve.com/google-guava-immutablecollections/

2、http://www.cnblogs.com/snidget/archive/2013/02/05/2893112.html

3、Guava在线参考API:http://tool.oschina.net/apidocs/apidoc?api=guava。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 wps打字字上移了怎么办 微信里黑圈里面的白字是怎么办 脖子比脸黑好多怎么办 河南许昌小学生生病办休学怎么办 1岁宝宝内向胆小怎么办 3岁宝宝内向胆小怎么办 数学物理好不喜欢学医怎么办 孩子眉毛太浓了怎么办 小娃一年级成绩太差怎么办 孩子晚上睡得晚怎么办 在深圳买房难小孩读书怎么办 上海小孩读书积分不够怎么办 读书时静不下心怎么办 初中生静不下心读书怎么办 孩子学习静不下心怎么办 退烧后体温35度怎么办 孩子体温34度多怎么办 宝宝感冒咳嗽流鼻涕出汗怎么办 养的小鸡总打架怎么办 小鸡一条腿瘸了怎么办 同窝小斗鸡打架怎么办 夏季羊长的慢怎么办 1岁吃母乳不吃饭怎么办 5个月宝宝黏妈妈怎么办 九个月宝宝不爱吃饭怎么办 20个月宝宝吐了怎么办 十个月的宝宝消化不好怎么办 两岁宝宝不爱喝水怎么办 两岁宝宝不爱喝水吃饭怎么办 两岁的宝宝不爱喝水怎么办 宝宝不爱吃饭不爱喝水怎么办 一多半宝宝爱喝水 不爱吃饭怎么办 1岁宝宝不爱吃饭喝水怎么办 两岁小宝宝不爱吃饭怎么办 4个月小宝宝咳嗽怎么办 3个月小宝宝咳嗽怎么办 2个月小宝宝咳嗽怎么办 8的岁儿童腿不直怎么办 作业盒子选错年级怎么办 两岁x型腿怎么办 绿萝叶子有水滴怎么办