【问题标题】:Performing specific operation on first element of list using Java8 streaming使用 Java8 流对列表的第一个元素执行特定操作
【发布时间】:2016-11-16 06:34:38
【问题描述】:

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

这是我的代码 sn-p:

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);
});

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

【问题讨论】:

  • 我认为您的方法已经简洁明了:)
  • 防止 NPE 的一件事是检查 tokens 是否为 null
  • 是的,这只是解释问题的虚拟代码。我想知道是否有某种方法可以合并流式调用中的 if 条件并减少更多的行数。
  • @vatsalmevada No.

标签: java java-stream


【解决方案1】:

表达意图的一种方式是

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);
}

它适用于任意Collections,不仅适用于Lists,而且当更高级的Stream 操作被链接时,它可能比基于skip 的解决方案更有效。此模式也适用于 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);
}

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

如果您只想应用forEach 之类的操作,您也可以使用Iterator

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

【讨论】:

  • 迭代器应该是接受的解决方案恕我直言。 +1
【解决方案2】:

这样会更干净吗

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

【讨论】:

  • 那个或 findFirst()
  • 尝试对 same 流进行操作会抛出 IllegalStateException: stream has already been operated upon or closed
猜你喜欢
  • 1970-01-01
  • 2010-10-06
  • 2010-12-15
  • 2018-12-09
  • 2011-06-17
  • 2011-10-30
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多