java 8 stream:使用map更改List中的最后一个元素

Dou*_*eri 4 java java-8 java-stream

我有以下代码:

List<String> list= Arrays.asList("a","b","c");
list.stream()
    .map(x->{
        //if(isLast()) return "last";
        return x;
    })
    .forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

我想用"last"更改列表中的最后一项,以便程序返回这样的内容

a
b
last
Run Code Online (Sandbox Code Playgroud)

注意:我知道如果没有流,我可以很容易地做到这一点,但我很感兴趣,如果这可以通过流来实现.

注2:我提供了一个简单的例子,因此我可以很容易地理解流概念

Sam*_*Sam 9

这个怎么样:

<T> Stream<T> replaceLast(List<T> items, T last) {
    Stream<T> allExceptLast = items.stream().limit(items.size() - 1);
    return Stream.concat(allExceptLast, Stream.of(last));
}
Run Code Online (Sandbox Code Playgroud)

该方法生成两个单独的流,一个包含除输入列表的最后一项之外的所有流,另一个包含仅替换最终项的流.然后它返回这两个流的串联.

示例调用:

>>> List<String> items = Arrays.asList("one", "two", "three");
>>> replaceLast(items, "last").forEach(System.out::println);
one
two
last
Run Code Online (Sandbox Code Playgroud)

考虑到它,如果使用Stream.limit不舒服,Stream<T> allExceptLast = items.subList(0, items.size() - 1).stream();也是可能的.

  • 虽然它起作用并且不是另一个可怕的黑客攻击,但我认为Stack Overflow上的人不应该试图回答任何问题.有时我们的角色是说*Dude,你想要做的事情没有意义,做其他更好的方式*.对我来说,这绝对不是一个流有益的东西,只看一下循环会有多短 (6认同)
  • 很公平.在更广泛的背景下,它可能是有道理的.+1 (2认同)

Dic*_*ici 5

我不希望这个答案会被否决,因为我不会直接回答您的问题,但是我认为必须有人明确地说出来。

堆栈溢出不是我们应该尝试给出任何问题答案的地方。有时最好的办法是向OP解释他的方法是错误的,并向他展示一种更好的方法。

在这种情况下,我认为流不是您想要的。您应该将流视为序列,并且处理流的方式通常是逐个元素地进行的,在大多数情况下,没有回溯或期待。流可能是无限的,也可能是非常大的,并且您不知道它何时会结束。

相反,列表是具有给定大小的有限数据结构。最后一个元素的概念定义明确。其他人能够给您答案的唯一原因是,他们使用的事实是他们知道流来自列表。有了可能来自任何地方的通用流,您将无法做到这一点。

解决此类问题的流方法是使用迭代器,该迭代器与流的起源完全无关。

Stream<String> stream = someStream;
Iterator<String> it = stream.iterator();
while (it.hasNext()) {
     String next = it.next();
     System.out.println(it.hasNext() ? "last" : next);
}
Run Code Online (Sandbox Code Playgroud)

这不是很漂亮,但这是正确的流线方法。现在,您有了一个列表,因此也可以进行传统for循环。但是,此迭代器循环实际上是使用未知列表执行此操作的最佳方法。该for循环仅适用于随机访问列表,而其他循环则比较慢。

  • 使用“ hasNext()”检查来标识最后一个项目是一种巧妙的方法,并且可以使循环非常优雅。当您将流(或实际上任何可迭代的)作为输入并希望使用迭代器执行此操作时,这是一个绝佳的解决方案。 (2认同)
  • @DouaBeri Sam的解决方案很干净,他提出了一个很好的论据,说明为什么这样做可以有用。如果您将视频流发送给其他人,他的答案会更好。如果信息流来自其他人,我的会更好。实际上,这很有趣,因为它取决于观点(生产者或消费者)。感谢您的好评^^ (2认同)