java - 尽管是 Collections.unmodifiableList(),但 Java List 被从某处修改
问题描述
我的程序中有三个列表。
- ONE 所有项目的全局列表。全部
- 二 显示用户可用的所有项目的列表。可见的
- 三 屏幕上当前可见的所有项目的列表。显示
列表是这样声明的:
ONE = 外部来源
二 = 一
三=一
响应用户过滤特定项目时,我遇到了这个问题。该函数将遍历与过滤项匹配的三个和 List.remove(index) 项。该函数不与 TWO 交互。尽管最初的声明没有再次运行,但这两个被修改为等同于三个(我用调试器检查过,当两个被修改时无法解决)。
我尝试将 TWO 更改为 Collections.unmodifiableList() 但它仍然被修改?
我用一些严重的问题解决了这个问题。
Object[] temp = new Object[ONE.size()];
temp=ONE.toArray(temp);
TWO = Arrays.asList(temp);
糟糕,我知道......它之所以有效,是因为 Arrays.asList 是不可变的,但不可修改的列表肯定也是不可变的?
为请求者添加了代码。初始化代码:
protected void onPostExecute(List<SpaceObject> visibleObjects){
hideLoading();
SpaceObject[] atom = new SpaceObject[visibleObjects.size()];
atom=visibleObjects.toArray(atom);
VISIBLE_OBJECTS = Arrays.asList(atom);
SHOWING_OBJECTS = visibleObjects;
addToView(visibleObjects);
}
响应删除或添加项目。
private void showSpecificItems(String itemType, Boolean remove){
int i = 0;
if (remove) {
while (i < SHOWING_OBJECTS.size()){
if(SHOWING_OBJECTS.get(i).getType().toLowerCase().matches(itemType.toLowerCase())){
SHOWING_OBJECTS.remove(i);
}else{
i++;
}
}
}else{
System.out.println("remove");
while(i < VISIBLE_OBJECTS.size()){
if(VISIBLE_OBJECTS.get(i).getType().toLowerCase().matches(itemType.toLowerCase())){
SHOWING_OBJECTS.add(VISIBLE_OBJECTS.get(i));
}
i++;
}
SHOWING_OBJECTS = sortBrightest(SHOWING_OBJECTS);
}
addToView(SHOWING_OBJECTS);
}
解决方案
如果你有这样的代码
List<Object> ONE = someMagic();
List<Object> TWO = ONE;
List<Object> THREE = ONE;
然后你有三个东西都指向同一个列表。
如果你想让它们不同,你可以尝试这样的事情:
List<Object> ONE = someMagic();
List<Object> TWO = ONE.clone();
List<Object> THREE = ONE.clone();
通过这种方式,他们制作了实际不同的列表。
protected void onPostExecute(List<SpaceObject> visibleObjects){
hideLoading();
// this line is useless - you allocate an array only to immediately toss it away?!
SpaceObject[] atom = new SpaceObject[visibleObjects.size()];
atom=visibleObjects.toArray(atom);
// this uses atom as its backing array, which comes from visibleObjects
VISIBLE_OBJECTS = Arrays.asList(atom);
// this obviously atom as a backing array
SHOWING_OBJECTS = visibleObjects;
addToView(visibleObjects);
}
所以要解决这个问题,您需要删除对该支持数组的依赖
protected void onPostExecute(List<SpaceObject> visibleObjects){
hideLoading();
VISIBLE_OBJECTS = visibleObjects.clone();
SHOWING_OBJECTS = visibleObjects.clone();
addToView(visibleObjects); // probably bad form, but I doubt this will keep a reference, so it's "acceptable"
}
如果clone
不适合你,你可以做得更复杂一点
protected void onPostExecute(List<SpaceObject> visibleObjects){
hideLoading();
VISIBLE_OBJECTS = new ArrayList(visibleObjects);
SHOWING_OBJECTS = new ArrayList(visibleObjects);
addToView(visibleObjects); // probably bad form, but I doubt this will keep a reference, so it's "acceptable"
}
推荐阅读
- python - 查找两个字符串模式之间的文本
- java - 可以将服务器配置为禁用自签名证书吗?
- java - Maven:创建依赖项的 uber jar
- marklogic - 是否可以在 MarkLogic 中对三元组执行变音符号、区分大小写/不区分大小写和通配符搜索?
- reactjs - 如何在渲染函数中使用 if 语句?
- jquery - jquery 可排序脚本 - 获取拖动项 id
- javascript - 在浏览器中启动 Ubuntu/Linux 上的 JNLP 文件(Chrome(67) /Mozilla)
- c# - 如何从 EF Core 中的父实体中删除子实体?
- json - 使用 alamofire 在 Swift 上解析 Json
- mysql - Mysql选择查询3个表