如何通过一组位置从java列表中删除项目?

时间:2015-04-06 08:51:37

标签: java list set

根据一组职位Set<Integer> positionsToRemove,我要删除列表List<?> list中的所有项目,表明其位置与集合中的值相对应。

public static void remove(List<?> list, Set<Integer> positionsToRemove) {
  // ?
}

注意:

  • 列表可能很长。
  • 该套装可能很长。
  • 注意不要掉落IndexOutOfBounds或ConcurrentModificationException。
  • 您可以假设列表和集合不包含空值。

3 个答案:

答案 0 :(得分:4)

您必须确保删除反向项,否则索引将无效。

您可以使用List

轻松完成此操作
public static void remove(List<?> list, Set<Integer> positionsToRemove) {
    final ListIterator<?> iter = list.listIterator(list.size());
    while (iter.hasPrevious()) {
        iter.previous();
        if (positionsToRemove.contains(iter.nextIndex())) {
            iter.remove();
        }
    }
}

这利用了ListIterator提供当前索引的能力以及它反向迭代的能力。

它也不依赖于&#34;标记值&#34;因此输入null中允许List

显然,你可以用一种旧式的方式更简单地做到这一点&#34;索引循环:

public static void remove(List<?> list, Set<Integer> positionsToRemove) {
    for (int i = list.size() - 1; i >= 0; --i) {
        if (positionsToRemove.contains(i)) {
            list.remove(i);
        }
    }
}

但需要注意的是,如果List缺少RandomAccess,则O(n^2)将为ListIterator,而基于O(n)的解决方案为List {1}} O(1) remove

返回new List可能会更快,具体取决于您要移除的元素的方式以及List ArrayList remove操作的类型很贵:

public static <T> List<T> remove(List<T> list, Set<Integer> positionsToRemove) {
    return IntStream.range(0, list.size())
            .filter(i -> !positionsToRemove.contains(i))
            .mapToObj(list::get)
            .collect(toList());
}

答案 1 :(得分:0)

public static void remove(List<?> list, Set<Integer> positionsToRemove) {
    for (Integer position : positionsToRemove) {
        list.set((int)position, null);
    }
    for (Iterator<?> iterator = list.iterator(); iterator.hasNext(); ) {
        Object o =  iterator.next();
        if (o == null) iterator.remove();
    }
}

答案 2 :(得分:0)

public static void remove(List<?> list, Set<Integer> positionsToRemove) {
    int i = 0;
    for (Iterator<?> iterator = list.iterator(); iterator.hasNext(); ++i) {
        iterator.next();
        if (positionsToRemove.contains(i)) iterator.remove();
    }
}