java列表在某处被修改,尽管它是collections.unmodifiablelist()

vi4fp9gy  于 2021-07-07  发布在  Java
关注(0)|答案(2)|浏览(371)

我的程序里有三个列表。
一个是所有项目的全局列表。全部的
两个列表显示用户可用的所有项目。看得见的
三个是屏幕上当前可见的所有项目的列表。显示
名单宣布如下:
一个=外部源
二=一
三=一
我在响应用户筛选特定项目时遇到此问题。该函数将遍历三个并列出与筛选项匹配的(索引)项。函数不与两个对象交互。尽管这两个被修改为等价于三个,尽管初始声明不再运行(我用调试器检查了一下,无法确定何时修改了两个)。
我尝试将两个更改为集合。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);

}
fkaflof6

fkaflof61#

如果你有这样的代码

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"
}
kcugc4gi

kcugc4gi2#

我试着把两个换成一个 Collections.unmodifiableList() 但还是被修改了?
javadocs是这样描述由该方法创建的不可修改视图的:
不可修改的视图集合是不可修改的集合,也是备份集合上的视图。它的变异方法 UnsupportedOperationException ,而读取和查询方法被委托给备份集合。其效果是提供对备份集合的只读访问。。。
请注意,对备份集合的更改仍然是可能的,如果发生更改,则可以通过不可修改的视图看到这些更改。因此,不可修改的视图集合不一定是不变的。
总之, unmodifiableList() 没有您期望的属性。如果您想要可变列表的不可变快照,则需要复制它。

相关问题