当前位置: 首页 > 知识库问答 >
问题:

在只有一个元素的列表中调用stream(). duce()

乐正宜人
2023-03-14

我是java函数编程的新手,不知道如何编写代码来避免(例如)此操作中的NPE:

myList.stream()
      .reduce((prev, curr) -> prev.getTimestamp().isAfter(curr.getTimestamp()) ? prev : curr);
      .get().getTimestamp();

我在这里的目的是在列表中查找最新对象的时间戳。关于如何更好地收集最后一个元素的建议非常受欢迎,但我在这里的主要问题实际上是为什么这有效。

文档显示,如果归约的结果为空,该函数将抛出< code > NullPointerException :

http://docs . Oracle . com/javase/8/docs/API/Java/util/stream/stream . html # reduce-Java . util . function . binary operator-

这是可以的,但我不太明白的是为什么当此代码以仅包含一个元素的列表运行时,我没有得到NullPointerException。在这种情况下,我希望prev为空。我尝试过调试,但当只有一个元素时,它似乎只是跨过了整个lambda表达式。

共有3个答案

常英毅
2023-03-14

如果reduce操作实际导致<code>null

另一方面,要查找最新的时间戳,您可以这样做:

myList.stream()
    .map(t -> t.getTimeStamp())
    .max(Comparator.naturalOrder()
    .get();  // will throw an exception if stream is empty

或者,对于静态导入,假设您的类名为Thing:

myList.stream().map(Thing::getTimeStamp).max(naturalOrder()).get();
何涵衍
2023-03-14

更好:

  Optional<Thingie> max = 
      myList.stream()
            .reduce(BinaryOperator.maxBy(comparing(Thingie::getTimeStamp));

reduce()的重载返回一个可选的;盲目地用get解包是危险的,并且有可能抛出NSEE。使用像<code>orElse这样的安全操作符之一将其解包。

如果流中可能有空值,请首先使用. filter(t-

谭翰海
2023-03-14

正如减少的JavaDoc所说,减少相当于:

 boolean foundAny = false;
 T result = null;
 for (T element : this stream) {
     if (!foundAny) {
         foundAny = true;
         result = element;
     }
     else
         result = accumulator.apply(result, element);
 }
 return foundAny ? Optional.of(result) : Optional.empty();

因此,如果流具有单个元素,则循环只有一次迭代,并返回在该迭代中找到的单个元素。

二进制运算符仅在至少有两个元素时应用。

 类似资料:
  • 我是JOOQ新手,目前无法将连接查询映射到映射 这是我的代码: 假设我在订单中有1行,在订单项目文章中有2行。运行由(在.fetchGroups()之后)按预期返回我2行,所以我假设调用fetchGroups()也会用两个条目填充我的列表?! 我错过了什么? 谢谢 更新: 根据要求,类: 所以这只是JOOQ POJO类的扩展,用于与API客户机的JSON通信。。。

  • 当已知Python列表总是包含单个项时,除了: 你可能会问,'你为什么要这么做?‘。仅仅是好奇心。在Python中似乎有一种替代的方法来完成所有的事情。

  • 我想在java中创建一个方法,该方法接收两个字符串列表:

  • 问题内容: 给出以下列表: 我想将[a]的每个元素重复其在[b]中的对应位置的编号,以产生此结果: 即0发生1次,5发生2次,1发生1次。 问题答案: 内容如下: -重复elem次 从两个列表中组成一个2元组的列表,将每个元素与另一个列表中的对应元素配对。这为您提供了用例中需要传递给的确切信息。 -将迭代器的结果列表展平为单个值列表。您既可以像我一样,也可以像马丁·彼得斯那样。

  • [{codice=欧元,description=欧元,ratio=1},{codice=美元,description=美元,ratio=1.1}] 我想在中转换它,如下所示: {EUR={codice=欧元,description=欧元,ratio=1},USD={codice=美元,description=美元,ratio=1.1}} 但这返回一个而不是我需要的。 我想函数会对我起作用,但不知道

  • 我想知道是否有一种方法可以直接在Java中通过使用stream().filter()过滤出单个元素,而不需要创建列表和获取0索引。