immutable和mutable

immutable和mutable

复习到了这一部分,记录一下immutable和mutable的性质与区别。

1. 优缺点比较

首先先把二者的优缺点列出来:

优缺点immutablemutable
缺点由于内部数据不可变,所以对其频发修改会产生大量的临时拷贝,浪费空间可变类型由于其内部数据可变,所以其风险更大
优点内部数据的不可变导致其更加安全,可以用作多线程的共享对象而不必考虑同步问题可变类型会减少数据的拷贝次数,从而其效率 要高于immutable

2.各自的定义

immutable:一个immutable的对象其值在指定了之后就不可再改变,如果试图修改其内部的值会新建一个新的地址保存新的值。
mutable:一个mutable的对象其值在指定了之后还是可以修改的。

3.举例

在编程语言中这个概念是通用的,以下使用java来举例。
首先,java中很典型的一个immutable的对象就是String。当对String完成初始化之后,String指向的这一段地址的内容就固定了,如果为这个String赋另外一个值,将会给这个String赋一段新的地址,这个新地址中存着新值,如果旧的地址将没有其他对象指向它,将等待回收。以下使用一个SnapShot图来表示这个过程。
在这里插入图片描述
而mutable的一个例子就是List,java中的List、set、Map等对象都是可变的,这一点从它们都存在类似于add的方法就可以看出。mutable在改变值的时候不改变地址,而是直接修改原本地址中的值。

4.优缺点分析

每一种对象的存在和使用都是存在其合理性的。以下为两种对象使用过程中的优缺点分析。

4.1 immutable

对于immutable来说,优点十分明显,就是它指向的地址的内容是不可变的,也就不存在两个对象都指向一个地址的时候其中一个对象无法知道另外一个对象是否对这个地址的内容进行修改。也就是说,immutable在很大程度上保证了多线程的时候的正确性。但是缺点同样十分明显,就是每一次修改都要进行一次复制,可能会产生很大的时间开销,同时会产生大量的需要回收的垃圾。例如对于如下代码片段:

 public void test(int n)
    {
        String s="";
        for(int i=0;i<n;i++)
        {
            s.concat(String.valueOf(i));
        }
    }

对于第一个i来说进行了n次插入意味着复制了n次,也就是这个过程中时间复杂度是O(n^2)的,而这只是一个最简单的一层循环。

4.2 mutable

mutable由于其指向地址内容可变,因此每次修改的时候不需要复制,因此其开销比immutable小很多。但是其缺点就在于如果多个变量指向同一段地址的时候,其中一个对象对于地址内容的修改会影响到其他所有的变量的值,这种影响很有可能导致程序出错,例如如下代码片段:

public class Zoo {
    private List<String> animals;
    public Zoo(List<String> animals) {
        this.animals = animals;
    }
    public List<String> getAnimals() {
        return this.animals;
    }
    public static void main(String[]argv)
    {
        List<String> a = new ArrayList<>();
        a.addAll(Arrays.asList("lion", "tiger", "bear"));
        Zoo zoo = new Zoo(a);
        a.add("zebra");
        System.out.println(a);
        System.out.println(zoo.getAnimals());
        List<String> b = zoo.getAnimals();
        b.add("flamingo");
        System.out.println(a);
    }
}

其中List是一个Mutable的对象,因此a,zoo.animals,b都指向了同一段内存空间,任何一个内容的修改都会造成三个值一起发生变化,因此main函数的输出如下:
在这里插入图片描述
很显然这种输出在很大可能性下不是我们想要的,因此使用mutable是存在风险的。

5.使用场景

尽可能使用不可变的对象和不可变的引用。如果可以肯定某一段地址空间只会由一个对象指向,可以考虑使用mutable对象,但是使用的时候一定要注意不要产生多个对象修改一段空间内值的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值