【问题标题】:Java 8 Streams - Iterator doesn't work like expectedJava 8 Streams - 迭代器不像预期的那样工作
【发布时间】:2014-06-23 19:57:54
【问题描述】:

为什么 .next() 返回 7 而不是我预期的 8?

List<Integer> intList = new ArrayList<>();

IntStream.range(0, 10)
    .forEach(i -> intList.add(i));

int value = intList.stream()
            .filter(number -> number == 7)
            .iterator()
            .next();         // returns 7, not 8.

【问题讨论】:

  • 我还没有真正有机会查看流 API,但不会使用 number -&gt; number == 7 进行过滤意味着流只有7s留在里面?你能解释一下你为什么期待8吗?
  • 这对我来说是一个很大的误解。我试图将我的问题简化为上面的这段代码,但同时我失去了实际问题的本质。我想我必须打开另一个问题。很抱歉。

标签: java lambda iterator java-8


【解决方案1】:

过滤器将流过滤到仅匹配条件 number == 7 的元素(即仅一个元素,恰好是整数 7),然后 next() 返回第一个(也是唯一的)元素。请记住,为了从Iterator 中获取第一个元素,您需要调用一次next()

如果您确实想要此有序列表中 7 之后的第一个元素,您可以将过滤器更改为 number -&gt; number &gt; 7

【讨论】:

  • 如果我只知道它是基础列表中的前身 7,我能以某种方式到达 8 吗?
  • 您可以根据需要使用&gt; 7&gt;= 7
  • 好尴尬。 :-) 这使得 .filter 与 .iterator 结合的功能对我来说更加清晰。谢谢。
  • 您需要花一些时间才能理解这种来自 regular Java 的范式。这就是为什么像你这样的小测试程序是好的 - 它们有助于让你的大脑“进入心情”。
【解决方案2】:

除了其他答案指出的错误过滤谓词的问题之外,使用iterator() 应该是您最后的选择。此方法(及其朋友spliterator())由“逃生舱口”组成,用于标准流方法无法满足您需要的情况。

在这种情况下,如果你只想要第一个元素,你可以调用findFirst()。如果要将结果放入数组或集合中,请使用toArray()collect()

【讨论】:

  • 感谢这些提示。我试图将问题简化为上述问题,处理一个Player-Objects 列表,其中一个对象存储在Player::currentPlayerfield 中。 API 为返回 Player 对象的 currentPlayer 提供了一个 getter,为播放器列表提供了一个 getter,它将列表作为流返回。 players.stream()。玩家完成动作后,列表中的下一个必须设置为 currentPlayer(循环),我不知道如何访问后继玩家。我唯一的想法是迭代器。
【解决方案3】:

这实际上是正确的,因为您正在过滤列表并且只考虑满足 lambda 表达式 number -&gt; number == 7 的元素。因此,您的列表中只有一个元素通过。

【讨论】:

    猜你喜欢
    • 2014-05-16
    • 1970-01-01
    • 2012-06-13
    • 2018-11-19
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 2021-02-08
    • 1970-01-01
    相关资源
    最近更新 更多