不可变与不可移动集合

2022-08-31 06:16:51

集合框架概述

不支持修改操作(如 和 )的集合称为不可修改的集合。不可修改的集合是可修改的addremoveclear

另外保证对象中的任何更改都不可见的集合称为不可变。不可变的集合是可变的Collection

我无法理解其中的区别。
这里不可改变不变之间有什么区别?


答案 1

不可修改的集合通常是其他代码仍可访问的可修改集合的包装器。因此,虽然如果您只引用了不可修改的集合,则无法对其进行任何更改,但您不能依赖内容不变。

不可变集合可保证任何内容都无法再更改集合。如果它包装可修改的集合,则确保没有其他代码有权访问该可修改集合。请注意,尽管没有代码可以更改集合包含对哪些对象的引用,但对象本身可能仍然是可变的 - 创建不可变集合不会以某种方式“冻结”这些对象。StringBuilder

基本上,区别在于其他代码是否能够更改您背后的集合。


答案 2

基本上,集合是一个视图,因此间接地,它仍然可以从其他可修改的引用中“修改”。同样由于它只是一个只读的安other集合视图,当源集合更改时,不可修改的集合将始终显示最新的值。unModifiable

但是,集合可以被视为另一个集合的只读副本,并且不能修改。在这种情况下,当源集合更改时,不可变集合不会反映更改immutable

下面是一个可视化此差异的测试用例。

@Test
public void testList() {

    List<String> modifiableList = new ArrayList<String>();
    modifiableList.add("a");

    System.out.println("modifiableList:"+modifiableList);
    System.out.println("--");


    //unModifiableList

    assertEquals(1, modifiableList.size());

    List<String> unModifiableList=Collections.unmodifiableList(
                                        modifiableList);

    modifiableList.add("b");

    boolean exceptionThrown=false;
    try {
        unModifiableList.add("b");
        fail("add supported for unModifiableList!!");
    } catch (UnsupportedOperationException e) {
        exceptionThrown=true;
        System.out.println("unModifiableList.add() not supported");
    }
    assertTrue(exceptionThrown);

    System.out.println("modifiableList:"+modifiableList);
    System.out.println("unModifiableList:"+unModifiableList);

    assertEquals(2, modifiableList.size());
    assertEquals(2, unModifiableList.size());
            System.out.println("--");



            //immutableList


    List<String> immutableList=Collections.unmodifiableList(
                            new ArrayList<String>(modifiableList));

    modifiableList.add("c");

    exceptionThrown=false;
    try {
        immutableList.add("c");
        fail("add supported for immutableList!!");
    } catch (UnsupportedOperationException e) {
        exceptionThrown=true;
        System.out.println("immutableList.add() not supported");
    }
    assertTrue(exceptionThrown);


    System.out.println("modifiableList:"+modifiableList);
    System.out.println("unModifiableList:"+unModifiableList);
    System.out.println("immutableList:"+immutableList);
    System.out.println("--");

    assertEquals(3, modifiableList.size());
    assertEquals(3, unModifiableList.size());
    assertEquals(2, immutableList.size());

}

输出

modifiableList:[a]
--
unModifiableList.add() not supported
modifiableList:[a, b]
unModifiableList:[a, b]
--
immutableList.add() not supported
modifiableList:[a, b, c]
unModifiableList:[a, b, c]
immutableList:[a, b]
--