使用Java8流对列表的第一个元素执行特定操作

vat*_*ada 8 java java-stream

我想对列表的第一个元素执行某些操作,对所有剩余元素执行不同的操作.

这是我的代码片段:

List<String> tokens = getDummyList();
if (!tokens.isEmpty()) {
    System.out.println("this is first token:" + tokens.get(0));
}
tokens.stream().skip(1).forEach(token -> {
    System.out.println(token);
});
Run Code Online (Sandbox Code Playgroud)

是否有更简洁的方法来实现这一点,最好使用java 8流API.

Hol*_*ger 6

表达意图的一种方式是

Spliterator<String> sp = getDummyList().spliterator();
if(sp.tryAdvance(token -> System.out.println("this is first token: "+token))) {
    StreamSupport.stream(sp, false).forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)

它与任意Collections一起工作,不仅仅是Lists,并且skipStream链接更高级的操作时,它可能比基于解决方案更有效.该模式也适用于Stream源,即当多次遍历不可能或可能产生不同结果时.

Spliterator<String> sp=getDummyList().stream().filter(s -> !s.isEmpty()).spliterator();
if(sp.tryAdvance(token -> System.out.println("this is first non-empty token: "+token))) {
    StreamSupport.stream(sp, false).map(String::toUpperCase).forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)

但是,与平均处理所有流元素相比,第一个元素的特殊处理可能仍会导致性能损失.

如果你想做的就是应用类似的动作forEach,你也可以使用Iterator:

Iterator<String> tokens = getDummyList().iterator();
if(tokens.hasNext())
    System.out.println("this is first token:" + tokens.next());
tokens.forEachRemaining(System.out::println);
Run Code Online (Sandbox Code Playgroud)


Aim*_*rda 5

这会更干净吗

    items.stream().limit(1).forEach(v -> System.out.println("first: "+ v));
    items.stream().skip(1).forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

  • 尝试对*相同*流进行操作会抛出“IllegalStateException:流已被操作或关闭” (2认同)