使用Java 8安全地从集合中删除项目

dab*_*aba 3 java java-8

我试图迭代一个集合使用,forEach但实现调用remove(Object o)该集合是不安全的,可能会导致ConcurrentModificationException.这就是我想要做的事情:

public void removeMatchup(Set<Player> players) {
        predefinedMatchups.stream().filter(m -> m.getPlayers().equals(players)).forEach(m -> predefinedMatchups.remove(m));
}
Run Code Online (Sandbox Code Playgroud)

所以我改变了这个:

public void removeMatchup(Set<Player> players) {
    Iterator<Matchup> iterator = predefinedMatchups.iterator();
    while (iterator.hasNext())
        if (iterator.next().getPlayers().equals(players))
            iterator.remove();
}
Run Code Online (Sandbox Code Playgroud)

我真的很喜欢简洁的流,这就是为什么我要重新整理我的整个项目以包含Java 8的新功能.

是否有解决此问题的方法,我可以在执行安全删除时使用流?

Psh*_*emo 10

因为Set就是Collection我们可以使用removeIf(Predicate<? super E> filter)的方法(例如默认的内部使用Iteratorremove方法只是在你的第二个例子一样).

409  default boolean removeIf(Predicate<? super E> filter) {
410 Objects.requireNonNull(filter);
411 boolean removed = false;
412 final Iterator<E> each = iterator();
413 while (each.hasNext()) {
414 if (filter.test(each.next())) {
415 each.remove();
416 removed = true;
417 }
418 }
419 return removed;
420 }

所以你的代码看起来像:

public void removeMatchup(Set<Player> players) {
    predefinedMatchups.removeIf(m -> m.getPlayers().equals(players));
}
Run Code Online (Sandbox Code Playgroud)

  • @Pshemo:添加到`removeIf`中的另一个集合以某种方式向后执行.然后,做Set <...> toRemove = orig.stream().filter(...).collect(toSet()); orig.removeAll(文档,删除);`.除此之外,`default`实现是否使用`Iterator`并不重要,因为每个集合都可以覆盖它.重要的是,该方法的*合同*. (2认同)