使用java 8在BigDecimal列表中查找max

时间:2017-08-04 11:22:53

标签: java java-8 java-stream

我们假设我有一个这样的课程:

public class A {
    private int id;
    private BigDecimal amount;
}

我有List<A>。如何使用Java 8流找到列表中所有A个对象的最大数量?

此方法:

List<A> brol = new ArrayList<>();
BigDecimal max = brol.stream().max(Comparator.comparing(A -> A.getAmount())).get().getAmount();
        System.out.println("MAX = " + max);

给出NoSuchElementException所以我应该为此创建一个特定的比较器?

2 个答案:

答案 0 :(得分:16)

我要做的是检查可选

Optional<BigDecimal> max = brol.stream()
                               .map(a -> a.amount)
                               .max(Comparator.naturalOrder());
if (max.isPresent()) {
   // have a max
}

如果您觉得这更清楚,可以使用Comparator.naturalOrder()代替BigDecimal::compare

Optional.get()抛出NoSuchElementException,因为没有元素。当您获得最大值的对象不是Comparator

时,您只需提供Comparable

在这种情况下,您不需要最大A amount BigDecimal Comparable min()

你可以提供一个比较器,如果你真的想要最小值,虽然使用items = ['item1', 'item2', 'item3', 'item4']; currentItem = 'item3'; 在这方面是一个更简单的选择。

答案 1 :(得分:3)

您不需要特定的比较器。比较器不是你的问题。

流畅的调用风格很好,时髦而且时髦,但它有一个主要的缺点,许多人似乎忽略了:当这一系列函数调用发生错误时,你不知道它发生的地方。

因此,为了解决这些问题,最好将流畅的火车分解成单独的货车。 (至少在故障排除方面,如果您愿意,请将其放回列车中,所有故障排除工作都已完成。)

在这种情况下,您会看到max()返回Optional<BigDecimal>,而OptionalArrayList因为brol max为空,(并且您提供的示例,它是空的,然后没有最大值,因为ArrayList操作在空列表中未定义。

因此,您需要提供stream().max()为空的情况。你可以在调用isPresent()之前执行此操作,或者可以像Peter Lawrey建议的那样,通过调用Optional的{​​{1}}方法来执行此操作。

顺便说一下,你犯这个错误的事实表明:

  • 您正在使用一些过时的构建工具,这些工具无法向您发出有关代码的警告,或者

  • 您没有启用所有警告,或

  • 您收到警告但忽略了它们。

不要这样做,你永远不会走得这么远。我的IntelliJ IDEA在你的代码上给我一个警告(JetBrains称之为&#34;检查&#34;),说明.get()在没有.isPresent()的情况下被调用。因此,我可以在编译代码之前,在运行代码之前,在对其进行故障排除之前,以及在询问有关它的stackoverflow问题之前,立即告诉代码有什么问题。