在下面的代码中,我想在第一个" for循环"中从ArrayList中删除null或arraylist大小为零的项。运行第一个循环后,我再次进行第二个循环。在第二个循环中,我测试了它是否包含任何null或项目大小为零的项目。虽然我在第一个循环中擦除,但ArrayList BS包含从列表中删除的项目。
ArrayList<ArrayList<Record>> BS = new ArrayList<>();
.
.// some codes
.
for (int j = 0; j < BS.size(); j++) {
if(BS.get(j) == null || BS.get(j).size() == 0){
BS.remove(j);
}
}
for (int j = 0; j < BS.size(); j++) {
if(BS.get(j) == null || BS.get(j).size() == 0){
System.out.println("Again, fall into if condition");
}
}
答案 0 :(得分:3)
您遇到的问题是您在删除项目后不会立即检查该项目。
或者:
BS.removeIf(a -> a == null || a.isEmpty());
或反向迭代列表:
for (int j = BS.size() - 1; j >= 0; j--) { ... }
或使用Iterator
,并使用remove()
方法。
Iterator<? extends List<Record>> it = BS.iterator();
while (it.hasNext()) {
List<Record> list = it.next();
if (list == 0 || list.isEmpty()) it.remove();
}
removeIf
是最好的方法,因为它已被优化以了解如何有效地删除许多元素:删除除ArrayList
的最后一个元素之外的任何元素都需要移位具有更大索引的所有元素在内部数组中,所以通过简单地调用remove
来删除元素的时间复杂度是二次的。
但是,它仅适用于Java 8+。 (您可以在早期版本的Java中轻松实现高效删除;它只需要更多工作)。
答案 1 :(得分:1)
从数组中删除项目时,通常您希望从最后一项转到第一项,否则每次执行删除时索引都会跳转一项。
这是因为移除项目将剩余的项目移回一个位置,即从位置“j + 1”移动到位置j。所以下一个循环你跳过一个位置j(这是前一个循环中位置j + 1的项目)。
试试这个:
for (int j = BS.size() - 1; j >= 0; j--) {
if(BS.get(j) == null || BS.get(j).size() == 0){
BS.remove(j);
}
}
答案 2 :(得分:0)
问题是当项目被删除时,如果条件为真,则不会删除下一项。为此,您应该在删除项目时减少索引。
更改如下。
ArrayList<ArrayList<Record>> BS = new ArrayList<>();
.
.// some codes
.
for (int j = 0; j < BS.size(); j++) {
if(BS.get(j) == null || BS.get(j).size() == 0){
BS.remove(j);
j--;
}
}