Java 8 Streams可以对集合中的项目进行操作,然后将其删除吗?

Mic*_*lin 67 java collections filtering java-8 java-stream

就像几乎所有人一样,我仍然在学习新的Java 8 Streams API的复杂性(并且非常喜欢它们).我有一个关于流的使用的问题.我将提供一个简化的例子.

Java Streams允许我们使用a Collection,并使用stream()它上面的方法来接收所有元素的流.在这,有许多有用的方法,比如filter(),map()forEach(),这让我们对内容的使用拉姆达操作.

我的代码看起来像这样(简化):

set.stream().filter(item -> item.qualify())
    .map(item -> (Qualifier)item).forEach(item -> item.operate());
set.removeIf(item -> item.qualify());
Run Code Online (Sandbox Code Playgroud)

我们的想法是获取集合中所有项目的映射,这些项目匹配某个限定符,然后通过它们进行操作.操作后,它们不再用于其他目的,应从原始组中移除.代码运作良好,但我无法摆脱这样的感觉,即有一个操作Stream可以在一行中为我做这件事.

如果它在Javadocs中,我可能会忽略它.

是否有人更熟悉API会看到类似的东西?

Pau*_*ton 120

你可以这样做:

set.removeIf(item -> {
    if (!item.qualify())
        return false;
    item.operate();
    return true;
});
Run Code Online (Sandbox Code Playgroud)

如果item.operate()总是回来,true你可以非常简洁地做到.

set.removeIf(item -> item.qualify() && item.operate());
Run Code Online (Sandbox Code Playgroud)

但是,我不喜欢这些方法,因为它不能立即清楚发生了什么.就个人而言,我会继续使用for循环和Iterator为此.

for (Iterator<Item> i = set.iterator(); i.hasNext();) {
    Item item = i.next();
    if (item.qualify()) {
        item.operate();
        i.remove();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1用于使用for循环; 不要只使用流,以便您可以将代码放在一行上.循环通常比流式解决方案更具可读性,即使它们更冗长. (12认同)
  • for循环的好例子,但为什么你认为它更清楚?对我来说,我实际上认为,在这种情况下,流解决方案更清晰 (7认同)
  • 我对将状态改变代码插入`removeIf()`有点犹豫,但我相信这在理论上是可行的.另外,我的情况适合于函数式编程,因此我对流的需求超越了将所有内容打包成一行; 但是谢谢你 (4认同)
  • 使用带有lambda表达式的`removeIf`是完全合法的,它应该以这种方式使用.状态更改是集合API而非流的一部分. (3认同)