我有一堆索引,想从 ArrayList
中删除这些索引对应的元素。我不能简单地连续使用 remove()
方法,因为每次删除后元素都会被移动。我该如何解决这个问题?
要删除 indexes
处的元素:
Collections.sort(indexes, Collections.reverseOrder());
for (int i : indexes)
strs.remove(i);
或者,使用Java 8中的Stream API:
indexes.sort(Comparator.reverseOrder());
indexes.stream().mapToInt(i -> i).forEach(l::remove);
将索引按降序排序,然后逐个删除。这样做,就不会影响到你之后想要删除的任何索引。
如何进行排序取决于你用来存储索引的集合类型。如果是列表,你可以这样做:
List<Integer> indices;
Collections.sort(indices, new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
//todo: handle null
return b.compareTo(a);
}
}
@aioobe找到了我没能找到的帮助程序。 相比上面的方法,您可以使用
Collections.sort(indices, Collections.reverseOrder());
{ 8, 5, 9, 1, 4, 7 }
,用户想要移除1
、5
和4
。如果你将数组逆向排序为{ 9, 8, 7, 5, 4, 1 }
,那也无法更接近实现目标。 - Hatefiend我来这里是为了删除特定范围内的元素(即在两个索引之间的所有元素),然后找到了这个:
list.subList(indexStart, indexEnd).clear()
public static void main(String[] args) {
ArrayList<String> animals = new ArrayList<String>();
animals.add("cow");
animals.add("dog");
animals.add("chicken");
animals.add("cat");
animals.subList(0, 2).clear();
for(String s : animals)
System.out.println(s);
}
结果将会是: 鸡 猫
removeRange
方法,除非您扩展ArrayList
,因为该方法是protected
。 - Sanghyun Leeprotected
呢? - android developerList<T> toRemove = new LinkedList<T>();
for (T t : masterList) {
if (t.shouldRemove()) {
toRemove.add(t);
}
}
masterList.removeAll(toRemove);
你可以像其他人建议的一样对索引进行排序,或者你可以使用迭代器并调用 remove() 方法
List<String> list = new ArrayList<String>();
list.add("0");
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
List<Integer> indexes = new ArrayList<Integer>();
indexes.add(2);
indexes.add(5);
indexes.add(3);
int cpt = 0;
Iterator<String> it = list.iterator();
while(it.hasNext()){
it.next();
if(indexes.contains(cpt)){
it.remove();
}
cpt++;
}
这取决于你的需求,但在大多数情况下,排序会更快。
如果您需要删除很多元素(并且列表很长),那么迭代列表并将所有不需要删除的元素添加到新列表中可能会更快,因为 arraylist 中每个 remove()
步骤都会逐个复制被移除后的所有元素。在这种情况下,如果您的索引列表尚未排序(并且您可以与主列表并行迭代),则可能希望使用 HashSet、BitSet 或某些类似的 O(1) 访问结构来进行 contains()
检查:
/**
* creates a new List containing all elements of {@code original},
* apart from those with an index in {@code indices}.
* Neither the original list nor the indices collection is changed.
* @return a new list containing only the remaining elements.
*/
public <X> List<X> removeElements(List<X> original, Collection<Integer> indices) {
// wrap for faster access.
indices = new HashSet<Integer>(indices);
List<X> output = new ArrayList<X>();
int len = original.size();
for(int i = 0; i < len; i++) {
if(!indices.contains(i)) {
output.add(original.get(i));
}
}
return output;
}
使用guava!你要找的方法是Iterators.removeAll(Iterator removeFrom, Collection elementsToRemove)