小编典典

如何使用Java 8流查找较大值之前的所有值?

java

用例

通过在工作中发布的Katas编码,我偶然发现了这个不确定的问题。

在给定正整数列表的情况下,使用Java 8 Streams会生成整数列表,其中整数在较大值之前。

[10, 1, 15, 30, 2, 6]

上面的输入将产生:

[1, 15, 2]

因为1在15之前,15在30之前,2在6之前。

非流解决方案

public List<Integer> findSmallPrecedingValues(final List<Integer> values) {

    List<Integer> result = new ArrayList<Integer>();
    for (int i = 0; i < values.size(); i++) {
        Integer next = (i + 1 < values.size() ? values.get(i + 1) : -1);
        Integer current = values.get(i);
        if (current < next) {
            result.push(current);
        }
    }
    return result;
}

我尝试过的

我的问题是我不知道如何在lambda中访问下一步。

return values.stream().filter(v -> v < next).collect(Collectors.toList());

  • 是否可以检索流中的下一个值?
  • 我应该使用map并映射到Pair以便访问下一个吗?

阅读 215

收藏
2020-11-13

共1个答案

小编典典

使用IntStream.range

static List<Integer> findSmallPrecedingValues(List<Integer> values) {
    return IntStream.range(0, values.size() - 1)
        .filter(i -> values.get(i) < values.get(i + 1))
        .mapToObj(values::get)
        .collect(Collectors.toList());
}

它肯定比带有大循环的命令式解决方案更好,但就以惯用方式“使用流”的目标而言仍有些不足。

是否可以检索流中的下一个值?

不,不是这样。我所知道的最好的引用是在java.util.stream包装说明中

在流的生存期内,流的元素只能访问一次。与一样Iterator,必须生成新的流以重新访问源中的相同元素。

(检索正在操作的当前元素之外的元素意味着可以多次访问它们。)

从技术上讲,我们还可以通过其他几种方式来做到这一点:

  • 有状态地(非常)。
  • 使用流的iterator在技术上 还是使用流。
2020-11-13