【问题标题】:Conditional filter before foreach for streams javaforeach for streams java 之前的条件过滤器
【发布时间】:2022-12-05 21:29:16
【问题描述】:

有没有办法在流上执行 foreach 之前添加条件?例如,如果我只想在列表不包含重复项时执行 foreach,这对流是否可行?

students.getNames().(if contains duplicates stop and return the duplicate else continue with foreach).foreach()....

谢谢!

【问题讨论】:

  • @FedericoklezCulloca 是的,没错,我想避免执行 foreach 以防出现重复。如果有重复,他们将被退回
  • 将您的 foreach 语句嵌入 if 块中
  • AFAIK 不可能在方法链中执行。你需要事先检查
  • @Lola 如果您然后需要对重复项做一些事情(即返回它们),那么在某处简单地使用一个方法从列表中返回重复项可能是值得的,然后如果它是空的,请执行您的forEach。分两步完成可能是您最好的(也是最易读的)选择。
  • forEach(这是空白类型的方法)可以返回一些东西吗?提示:不能。所以你想做的技术是不可能的。这进一步意味着,您必须将这两个任务分开:1) 查找重复项并将其返回(如果有)。 2) 执行 for-each 循环,否则。

标签: java stream


【解决方案1】:

Streams 不支持在一次迭代中使用不同的分支,就像您的情况一样。 Stream 已经迭代了你的集合。

如果您编写没有流的代码,它会像这样:

// some logic by detecting duplicates and process it

for (Name name: students.getNames()) {
//foreach logic here
}

如果你想通过流来做,那会很难,因为forEach 是终止无效操作,什么都不返回在这种情况下最好不要使用流,

但如果你想使用蒸汽,可以狡猾的方式使用mapfindFirst终止方法(这不是使用map操作的正确方法,由于在map操作中处理的数据应该是无国籍的我不建议使用这个) 例如,这个逻辑可以用流来编写:

Set<Name> uniqueNames = new HashSet<>();
for (Name name: students.getNames()) {
if (!uniqueNames.add(name)) {
   return name;
}
//foreach logic here
}

几乎类似于(它不是纯粹的foreach,并且我不建议使用这种方式):

Optional<Name> firstDuplicate = students.getNames().map(name -> {
        if (!uniqueNamse.add(name) {
            return name;
        }
//foreach logic here
        return null;
        })
        .filter(Objects::nonNull).findFirst();

【讨论】:

  • 此代码已损坏。这功能map()操作中使用应该是无国籍的. Stream API documentation 强烈建议不要使用评估所依赖的有状态函数“取决于流管道执行期间可能发生变化的任何状态”.
猜你喜欢
  • 2015-11-13
  • 2018-08-28
  • 2014-07-26
  • 1970-01-01
  • 2020-01-24
  • 2018-01-01
相关资源
最近更新 更多