Bas*_*que 6 java collections list unmodifiable
我想要一个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]
Run Code Online (Sandbox Code Playgroud)
实用程序类中的该unmodifiableList方法Collections不会创建新列表,它会创建由原始列表支持的伪列表.通过"不可修改"对象进行的任何添加或删除尝试都将被阻止,因此名称符合其目的.但实际上,如您所示,原始列表可以被修改,同时影响我们的次要非完全不可修改的列表.
这在课程文档中有详细说明:
返回指定列表的不可修改视图.此方法允许模块为用户提供对内部列表的"只读"访问.对返回列表的查询操作"读取"到指定列表,并尝试修改返回的列表,无论是直接还是通过其迭代器,都会导致UnsupportedOperationException.
第四个词是关键:view.新列表对象不是新列表.这是一个叠加.就像在图纸上描绘纸张或透明胶片阻止您在图纸上制作标记一样,它也不会阻止您在下面修改原始图纸.
故事的道德:不要使用Collections.unmodifiableList来制作列表的防御性副本.
同上Collections.unmodifiableMap,Collections.unmodifiableSet等等.
Collections对于防御性编程,我建议使用Google Guava库及其ImmutableCollections工具,而不是课程.
你可以列一个新的清单.
public static final ImmutableList<String> ANIMALS = ImmutableList.of(
dog,
cat,
bird );
Run Code Online (Sandbox Code Playgroud)
或者您可以制作现有列表的防御性副本.在这种情况下,您将获得一个新的单独列表.从原始列表中删除不会影响(缩小)不可变列表.
ImmutableList<String> ANIMALS = ImmutableList.copyOf( originalList ); // defensive copy!
Run Code Online (Sandbox Code Playgroud)
但请记住,虽然集合自己的定义是独立的,但是包含的对象由原始列表和新的不可变列表共享.在制作防御性副本时,我们不会复制"狗"对象.只有一个狗对象保留在内存中,两个列表都包含指向同一只狗的引用.如果修改了"dog"对象中的属性,则两个集合都指向同一个单个dog对象,因此两个集合都将看到dog的新属性值.
| 归档时间: |
|
| 查看次数: |
1459 次 |
| 最近记录: |