java – 为什么我的`unmodifiableList`可以修改?
参见英文答案 >
Why can we change the unmodifiable list if we have the original one?7个
我想要一个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] 解决方法
不可修改的列表由原始列表支持
这在课程文档中有详细说明:
第四个词是关键:观点.新列表对象不是新列表.这是一个叠加.就像图纸上的tracing paper或transparency film阻止您在图纸上制作标记一样,它不会阻止您在下面修改原始图纸. 故事的道德:不要使用Collections.unmodifiableList来制作列表的防御性副本. 同上 谷歌番石榴 对于防御性编程而不是Collections类,我建议使用Google Guava库及其ImmutableCollections工具. 你可以列一个新的清单. public static final ImmutableList<String> ANIMALS = ImmutableList.of( dog,bird ); 或者您可以制作现有列表的防御性副本.在这种情况下,您将获得一个新的单独列表.从原始列表中删除不会影响(缩小)不可变列表. ImmutableList<String> ANIMALS = ImmutableList.copyOf( originalList ); // defensive copy! 但请记住,虽然集合自己的定义是独立的,但是包含的对象由原始列表和新的不可变列表共享.在制作防御性副本时,我们不会复制“狗”对象.只有一个狗对象保留在内存中,两个列表都包含指向同一只狗的引用.如果修改了“dog”对象中的属性,则两个集合都指向同一个单个dog对象,因此两个集合都将看到dog的新属性值. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |