This question already has answers here:
Why can we change the unmodifiable list if we have the original one?
(7个答案)
5年前关闭。
我想要一个
但是,当我从原始列表中删除一个元素时,我的不可修改列表也会被修改。到底是怎么回事?
请参阅此演示代码。从原始删除时,我的不可修改列表从3个元素缩小到2个。
或者,您可以为现有列表制作一份防御性副本。在这种情况下,您将获得一个新的单独列表。从原始列表中删除不会影响(缩小)不可变列表。
但是请记住,虽然集合自己的定义是分开的,但是包含的对象由原始列表和新的不可变列表共享。在制作该防御性副本时,我们不会复制“dog”对象。内存中仅保留一个狗对象,两个列表均包含指向同一狗的引用。如果修改了“狗”对象中的属性,则两个集合都指向同一个狗对象,因此这两个集合都将看到狗的新鲜属性值。
(7个答案)
5年前关闭。
我想要一个
List
,其元素无法删除或添加。我以为我在Java 8中找到了Collections.unmodifiableList的答案。我通过了原始列表,并获得了一个据说不可修改的列表。但是,当我从原始列表中删除一个元素时,我的不可修改列表也会被修改。到底是怎么回事?
请参阅此演示代码。从原始删除时,我的不可修改列表从3个元素缩小到2个。
String dog = "dog";
String cat = "cat";
String bird = "bird";
List< String > originalList = new ArrayList<>( 3 );
originalList.add( dog );
originalList.add( cat );
originalList.add( bird );
List< String > unmodList = Collections.unmodifiableList( originalList );
System.out.println( "unmod before: " + unmodList ); // Yields [dog, cat, bird]
originalList.remove( cat ); // Removing element from original list affects the unmodifiable list?
System.out.println( "unmod after: " + unmodList ); // Yields [dog, bird]
最佳答案
unmodifiableList由原始列表支持
unmodifiableList
实用程序类中的 Collections
方法不会创建新列表,而是创建一个由原始列表支持的伪列表。通过“不可修改”的对象进行的任何添加或删除尝试都将被阻止,因此该名称符合其用途。但是确实,正如您所显示的,原始列表可以修改,同时会影响我们的第二个非相当不可修改的列表。
这在类文档中有详细说明:
第四个单词是关键:view
。新列表对象不是新列表。它是一个覆盖。就像工程图上的tracing paper或transparency film阻止您在工程图上进行标记一样,它也不会阻止您深入修改原始工程图。
故事的寓意:不要使用Collections.unmodifiableList来制作防御性的列表副本。
与 Collections.unmodifiableMap
, Collections.unmodifiableSet
等类似。
谷歌 Guava
对于防御性编程,我建议使用Google Guava库及其ImmutableCollections工具,而不是Collections
类。
您可以列出一个新 list 。
public static final ImmutableList<String> ANIMALS = ImmutableList.of(
dog,
cat,
bird );
或者,您可以为现有列表制作一份防御性副本。在这种情况下,您将获得一个新的单独列表。从原始列表中删除不会影响(缩小)不可变列表。
ImmutableList<String> ANIMALS = ImmutableList.copyOf( originalList ); // defensive copy!
但是请记住,虽然集合自己的定义是分开的,但是包含的对象由原始列表和新的不可变列表共享。在制作该防御性副本时,我们不会复制“dog”对象。内存中仅保留一个狗对象,两个列表均包含指向同一狗的引用。如果修改了“狗”对象中的属性,则两个集合都指向同一个狗对象,因此这两个集合都将看到狗的新鲜属性值。
关于java - 为什么我的 `unmodifiableList`可以修改? [复制],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32362721/
10-15 10:42