使用一个迭代器删除多个列表的条目
Remove entries of multiple lists with one iterator
我有 2 个 int
列表 A、B 和 1 个 String
列表 C。它们都具有 相同的 长度。我想查看 C 并删除所有 empty 字符串以及 A 和 B 的条目,具有相同的索引。例如:
A:[1, 2, 3] A:[1, 3]
B:[4, 5, 6] should turn into B:[4, 6]
C:["C", "", B"] C:["C", "B"]
我当前的代码如下所示:
int i = 0;
for (Iterator<String> iterator = C.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
// Remove the current element from the iterator and the list.
iterator.remove();
A.remove(i);
B.remove(i);
}
i++;
}
但这不起作用。
当您按索引删除元素时,以下所有元素的索引都会递减,因此您必须为此调整代码:
int i = 0;
for (Iterator<String> iterator = C.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
// Remove the current element from the iterator and the list.
iterator.remove();
A.remove(i);
B.remove(i);
// don't increment i in this case, since the former i+1'th element
// of A and B just became the new i'th element
} else {
i++;
}
}
您可以完全避免使用索引,而只是同时遍历所有三个列表:
List<Integer> a = new ArrayList<Integer>(Arrays.asList(1,2,3));
List<Integer> b = new ArrayList<Integer>(Arrays.asList(4,5,6));
List<String> c = new ArrayList<String>(Arrays.asList("a","","c"));
Iterator<Integer> a_iterator = a.iterator();
Iterator<Integer> b_iterator = b.iterator();
Iterator<String> c_iterator = c.iterator();
while (c_iterator.hasNext() && b_iterator.hasNext() && a_iterator.hasNext()){
a_iterator.next();
b_iterator.next();
String cString = c_iterator.next();
if (cString == null || cString.isEmpty()){
a_iterator.remove();
b_iterator.remove();
c_iterator.remove();
}
}
就是说,我会尽量避免在单独的列表中处理它们。试图让迭代器和索引保持直线是容易出错的。相反,我更喜欢有一个包含更复杂对象的列表来保存关联的整数和字符串:
public class ABC {
private final Integer a;
private final Integer b;
private final String c;
private ABC(Integer a, Integer b, String c){
this.a = a;
this.b = b;
this.c = c;
}
// Add Getters
}
然后我就可以拥有 List<ABC>
并且我始终知道我拥有与每个 'a' 相关联的权利 'b' 和 'c' 等等。您可以遍历该列表并删除具有空白 c 的整个 ABC。如果我控制生成列表的代码,我会直接跳到 List<ABC>
。如果像这样给我,我可能还会把它们组合起来,但如果它们用得不多,我可能会按原样处理。不过,总的来说,我不喜欢必须编写代码来维护列表之间的隐含关系。
我有 2 个 int
列表 A、B 和 1 个 String
列表 C。它们都具有 相同的 长度。我想查看 C 并删除所有 empty 字符串以及 A 和 B 的条目,具有相同的索引。例如:
A:[1, 2, 3] A:[1, 3]
B:[4, 5, 6] should turn into B:[4, 6]
C:["C", "", B"] C:["C", "B"]
我当前的代码如下所示:
int i = 0;
for (Iterator<String> iterator = C.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
// Remove the current element from the iterator and the list.
iterator.remove();
A.remove(i);
B.remove(i);
}
i++;
}
但这不起作用。
当您按索引删除元素时,以下所有元素的索引都会递减,因此您必须为此调整代码:
int i = 0;
for (Iterator<String> iterator = C.iterator(); iterator.hasNext();) {
String string = iterator.next();
if (string.isEmpty()) {
// Remove the current element from the iterator and the list.
iterator.remove();
A.remove(i);
B.remove(i);
// don't increment i in this case, since the former i+1'th element
// of A and B just became the new i'th element
} else {
i++;
}
}
您可以完全避免使用索引,而只是同时遍历所有三个列表:
List<Integer> a = new ArrayList<Integer>(Arrays.asList(1,2,3));
List<Integer> b = new ArrayList<Integer>(Arrays.asList(4,5,6));
List<String> c = new ArrayList<String>(Arrays.asList("a","","c"));
Iterator<Integer> a_iterator = a.iterator();
Iterator<Integer> b_iterator = b.iterator();
Iterator<String> c_iterator = c.iterator();
while (c_iterator.hasNext() && b_iterator.hasNext() && a_iterator.hasNext()){
a_iterator.next();
b_iterator.next();
String cString = c_iterator.next();
if (cString == null || cString.isEmpty()){
a_iterator.remove();
b_iterator.remove();
c_iterator.remove();
}
}
就是说,我会尽量避免在单独的列表中处理它们。试图让迭代器和索引保持直线是容易出错的。相反,我更喜欢有一个包含更复杂对象的列表来保存关联的整数和字符串:
public class ABC {
private final Integer a;
private final Integer b;
private final String c;
private ABC(Integer a, Integer b, String c){
this.a = a;
this.b = b;
this.c = c;
}
// Add Getters
}
然后我就可以拥有 List<ABC>
并且我始终知道我拥有与每个 'a' 相关联的权利 'b' 和 'c' 等等。您可以遍历该列表并删除具有空白 c 的整个 ABC。如果我控制生成列表的代码,我会直接跳到 List<ABC>
。如果像这样给我,我可能还会把它们组合起来,但如果它们用得不多,我可能会按原样处理。不过,总的来说,我不喜欢必须编写代码来维护列表之间的隐含关系。