如果我写
List<Integer> a1 = Arrays.asList(1, 2, 3);
List<Integer> a2 = Collections.unmodifiableList(a1);
Run Code Online (Sandbox Code Playgroud)
a2 是只读的,但如果我写
a1.set(0,10);
Run Code Online (Sandbox Code Playgroud)
然后a2也被修改了.
如果在API中说:
返回指定集合的不可修改视图.此方法允许模块为用户提供对内部集合的"只读"访问.
那么,为什么我修改原始集合也修改了目标复制集合?
也许我误解了它的意思,如果是这样,那么写一个防御性的副本是什么方式?
我有一个常量图,如下所示:
private static Map<String, Character> _typesMap =
new HashMap<String, Character>() {
{
put ("string", 'S');
put ("normalizedString", 'N');
put ("token", 'T');
// (...)
}
Run Code Online (Sandbox Code Playgroud)
我真的需要Collections.unmodifiableMap()用来创建这张地图吗?使用它有什么好处?有没有使用它的缺点,除了明显的事实,它们并没有真正变得不变?
我可以看到Collections.unmodifiableSet返回给定集合的不可修改的视图但我不明白为什么我们不能只使用final修饰符来完成此操作.
在我的理解中,final声明一个常量:无法修改的东西.因此,如果将一个集合声明为常量,则无法修改它:无法从集合中删除任何内容,也无法添加任何内容.
我们为什么需要Collections.unmodifiableSet?
我建议返回Collections.unmodifiableList()而不是直接返回一个成员变量,我的同事担心会有性能损失.当然,最好的答案是衡量它,我们可能会这样做 - 但我想知道你的经验和任何参考,赞成或反对.
Collections.unmodifiableList(...)返回静态内部类 的新实例UnmodifiableList.其他不可修改的集合类以相同的方式构造.
如果公开这些课程,一个有两个好处:
UnmodifiableList),因此API用户不会想到修改该集合;List是instanceof UnmodifiableList.那么,是否有任何优势不让这些课程公开?
编辑:没有提出绝对令人信服的论据,所以我选择了最受欢迎的答案.
我需要使ArrayLists的ArrayList线程安全.我也无法让客户对集合进行更改.不可修改的包装器是否会使其线程安全,或者我需要在集合上使用两个包装器?
使用Collections.unmodifiableMap(...),我试图返回一个不可修改的地图视图.假设我有以下方法,
public final Map<Foo, Bar> getMap(){
...
return Collections.unmodifiableMap(map);
}
Run Code Online (Sandbox Code Playgroud)
为什么在其他地方合法执行以下操作,
Map<Foo, Bar> map = getMap();
map.put(...);
Run Code Online (Sandbox Code Playgroud)
这并不UnsupportedOperationException像我想的那样.有人可以解释一下,或者建议我如何成功地返回真正无法修改的地图?
在从getter方法返回之前,我经常使集合字段不可修改:
private List<X> _xs;
....
List<X> getXs(){
return Collections.unmodifiableList(_xs);
}
Run Code Online (Sandbox Code Playgroud)
但如果上面的X本身就是一个List,我想不出一个方便的方法:
private List<List<Y>> _yLists;
.....
List<List<Y>> getYLists() {
return Collections.unmodifiableList(_yLists);
}
Run Code Online (Sandbox Code Playgroud)
上面的问题当然是虽然客户端无法修改列表列表,但它可以从嵌入列表中添加/删除Y对象.
有什么想法吗?
本Collections类有很多的静态辅助方法来提供只读视图各种集合类型,例如unmodifiableSet(),unmodifiableList()等等.对于这些视图对象中,hashCode()和equals()方法前调用底层集合......随着一个奇怪的例外:unmodifiableCollection().
JavaDoc 明确指出:
返回的集合并没有将hashCode并传递给底层集合等于操作,但依靠
Object的equals和hashCode方法.在后备集合是集合或列表的情况下,这对于保留这些操作的合同是必要的.
我的问题:wtf是这个在谈论?如果支持集合是集合或列表,我希望行为与unmodifiableSet()和一致unmodifiableList().怎么会违反hashCode/equals合约?
我试图设置一个List不可修改的.
在我的代码中,我有一个返回列表的方法.
不应修改此列表,但我不想捕获unmodifiableList返回的异常.
private List<T> listeReferenceSelectAll = null;
List<T> oListeRet = new ArrayList<T>();
oListeRet = listeReferenceSelectAll;
return new ArrayList<T>(oListeRet);
Run Code Online (Sandbox Code Playgroud)
它是一个现有的代码,我必须将其转换为返回一个不可修改的列表,但是如果调用了"add"方法,则不必捕获任何异常.
首先,我创建了一个实现List的类,以覆盖"add"方法来记录异常而不是捕获它.
但我不知道如何正确实例化它...