2

我有多个ArrayList<String>“链接”到我用来构建列表视图的自定义适配器中。现在假设它们总共只有两个,以简化。我想对其中一个进行排序,然后将这个新顺序反映到另一个中,以保持列表一致。

这就是我想要做的,但不起作用,最后IndexOutOfBoundsException: Invalid index 0, size is 0*.

// initial declarations:
List<String> filenameEntries = new ArrayList<String>();
List<String> idEntries = new ArrayList<String>();

/* various operations that fill
the two ArrayList here... */

// sorting:
List<String> oldFilenameEntries = new ArrayList<String>();
List<String> oldIdEntries = new ArrayList<String>();

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

idEntries.clear();

Collections.sort(filenameEntries);

for (int i = 0; i < filenameEntries.size(); i++ ) {
    for (int j = 0; j < oldFilenameEntries.size(); j++ ) {
        if (oldFilenameEntries.get(j) == filenameEntries.get(i)) {
            idEntries.add(oldIdEntries.get(j));  // *
        }
    }
}

我的想法是在旧的 ArrayList 中搜索新元素中的每个元素,然后使用这个“旧”索引重新填充另一个 ArrayList。

(我有另一个“排序的” ArrayList 必须再次的限制idEntries。这就是我进行这种转移的方式)

有什么建议吗?谢谢。

编辑: 我认为这是一个排序问题,然后我错过了为 ArrayLists 制作副本的正确方法。感谢所有指出错误的人

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

以及为什么。

我接受了更快地找到解决方案的答案。我删除了上面的两行并将前一行更改为

List<String> oldFilenameEntries = new ArrayList<String>(filenameEntries);
List<String> oldIdEntries = new ArrayList<String>(idEntries);

从我所看到的 ATM 似乎一切都按预期工作。

4

4 回答 4

3

问题是分配:oldIdEntries = idEntries;这导致两个引用都指向同一个列表,所以当你这样做时,idEntries.clear();你已经清除了两个都指向的一个列表。您需要制作列表的副本,而不仅仅是分配参考。

Collections.copy

列表.copy

不可变列表.copy()

于 2013-09-12T16:29:41.520 回答
1

问题出在这两行:

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

在此之后,两个old...变量和原始变量都指向同一个列表。然后你打电话idEntries.clear()。这会清除两者idEntriesoldIdEntries因为它们指向同一个列表。

为此,您需要复制列表而不仅仅是分配它。你可以使用Collections.copy(). 这是一个例子:

Java Collections 副本列表 - 我不明白

另一方面,这种方法似乎太复杂了——但也不是很清楚你想要完成什么,所以我不能提出更好的方法。

于 2013-09-12T16:30:53.630 回答
0

遍历已排序的列表,克隆每个对象,然后将其添加到新的数组列表中

于 2013-09-12T16:31:22.063 回答
0

两个问题:一:

oldFilenameEntries = filenameEntries;
oldIdEntries = idEntries;

现在,新旧条目都指向同一个列表。然后,idEntries.clear(). 这将清除旧条目和新条目。如果您想以某种方式执行此操作,请使用Collections.copy()

二: 如果你只是要检查是否相等,我不明白为什么你需要有两个 for 循环,并且都已经排序。

你可以这样做:

for (int i = 0; i < filenameEntries.size(); i++ ) {
        if (oldFilenameEntries.contains(filenameEntries.get(i)) {
            idEntries.add(oldIdEntries.get(j));  // *
        }
    }
}

注意:由于我不知道您的代码的原始点是什么,并且我只能从您的代码段中推断出相等性检查,所以我建议这样做。

于 2013-09-12T16:36:46.283 回答