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

时间:2016-05-22 17:20:49

标签: 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));
}

所以我改变了这个:

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

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

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

2 个答案:

答案 0 :(得分:10)

由于SetCollection,我们可以使用removeIf(Predicate<? super E> filter)方法(例如默认方法使用Iterator及其remove方法,就像在第二个示例中一样)。

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));
}

答案 1 :(得分:1)

试试这个

removeIf

public void removeMatchup(Set<Player> players) {
        predefinedMatchups.removeIf(
            value-> players.conainsAll(value.getPlayers())
        );
}