从集中删除元素

f3d*_*d0r 13 java string foreach set string-length

我正在尝试删除一组中长度均匀的所有字符串.到目前为止,这是我的代码,但是我无法从增强型for循环中的迭代器中获取索引.

public static void removeEvenLength(Set<String> list) {
    for (String s : list) {
        if (s.length() % 2 == 0) {
            list.remove(s);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

man*_*uti 24

A Set没有元素索引的概念.元素在集合中没有顺序.此外,您应该使用Iteratorwhen迭代来避免在循环ConcurrentModificationException时从集合中删除元素:

for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String s =  iterator.next();
    if (s.length() % 2 == 0) {
        iterator.remove();
    }       
}
Run Code Online (Sandbox Code Playgroud)

请注意调用Iterator.remove()而不是Set.remove().

  • 不是真的,我只使用了`for`,因为OP已经使用了一个.一个`while`循环可以工作,但你可以在`for`循环之外设置`Iterator`的范围. (3认同)

Leo*_*ima 14

Java 8 引入了Collection.removeIf(),它允许您执行以下操作:

set.removeIf(s -> s.length() % 2 == 0)
Run Code Online (Sandbox Code Playgroud)


was*_*ren 7

只是想我会发布一个可能在将来帮助某人的Java 8解决方案.Java 8 Streams提供了许多很好的方法,比如filtercollect.该filter方法只是过滤掉流中应该进行下一步的元素.该collect方法将元素组合Collection为某种类型或a Map.

// The data to filter
final Set<String> strings = 
        new HashSet<>(Arrays.asList("a", "ab", "abc", "abcd"));

// Now, stream it!
final Set<String> odds =
        strings.stream()
               .filter(s -> s.length() % 2 != 0) // keep the odds
               .collect(Collectors.toSet());     // collect to a new set
Run Code Online (Sandbox Code Playgroud)

这实际上并不修改原始集合,而是创建一个Set包含String奇数长度对象的新集合.

有关Java 8 Streams的更多阅读,请查看Oracle优秀JavaDocs的优秀教程.