Java Collection框架提供了一个优雅的解决方案,可以创建一个不可修改的集合,如列表,集合,现有映射。
听起来太棒了。它会满足我们的目的吗?有一天正在调试有关可变对象和不可修改列表的问题。有一种非常特殊的行为。
让我们考虑下面的代码片段。
public class UnmodifibleList {
public static void main(String[] args) {
String s1= "Good";
String s2= "Morning";
final List modifiableList = new ArrayList();
modifiableList.add(s1);
modifiableList.add(s2);
final List unmodifiableList = Collections.unmodifiableList(modifiableList);
System.out.println("Before modifying: " + unmodifiableList );
modifiableList .add("nice");
modifiableList .add("day");
System.out.println("After modifying: " + unmodifiableList);
}
}
输出如下:
Before modifying: [Good, Morning]
After modifying: [Good, Morning, nice, day]
看起来有点奇怪吗?方法调用Collections.unmodifiableList()
后,将修改不可修改的列表java doc说的是什么:
返回指定列表的不可修改视图。该方法允许模块为用户提供"只读"访问内部列表。对返回列表的查询操作"通读"到指定的列表,并尝试修改返回的列表,无论是直接还是通过其迭代器,都会导致UnsupportedOperationException。 如果指定的列表是可序列化的,则返回的列表将是可序列化的。同样,如果指定的列表存在,则返回的列表将实现RandomAccess。
参数: 列出要返回不可修改视图的列表。 返回: 指定列表的不可修改的视图。
但它没有说明我们是否修改了基础集合,也会修改返回的不可修改列表。
有些人可能会建议我这种行为。
在链接问题中找不到确切的解决方案,我是如何实现自己的,
public class UnmodifibleList {
public static void main(String[] args) {
String s1= "Good";
String s2= "Morning";
final List modifiableList = new ArrayList();
modifiableList.add(s1);
modifiableList.add(s2);
final List unmodifiableList = Collections.unmodifiableList(new ArrayList(modifiableList));
System.out.println("Before modifying: " + unmodifiableList );
modifiableList .add("nice");
modifiableList .add("day");
System.out.println("After modifying: " + unmodifiableList);
}
}
请查看我们呼叫的上述代码中的行
Collections.unmodifiableList()
。这里我们创建一个全新的ArrayList并将原始列表传递给它。
Before modification: [Good, Morning]
After modification: [bad, Morning]