Find max in BigDecimal list using java 8
Suppose I have a class like this:
public class A {
private int id;
private BigDecimal amount;
}
And I have List<A>
. How can I find the maximum number of all objects A
in a list using Java 8 stream?
This method:
List<A> brol = new ArrayList<>();
BigDecimal max = brol.stream().max(Comparator.comparing(A -> A.getAmount())).get().getAmount();
System.out.println("MAX = " + max);
Gives NoSuchElementException
, so I have to create a specific comparator for this?
source to share
What I need to do is check the option
Optional<BigDecimal> max = brol.stream()
.map(a -> a.amount)
.max(Comparator.naturalOrder());
if (max.isPresent()) {
// have a max
}
Instead, Comparator.naturalOrder()
you can use BigDecimal::compare
if you feel it is clearer.
The optional .get () throws NoSuchElementException
as there is no item. You need to specify Comparator
when the object you are getting max is not equalComparable
In this case, you don't need the maximum, A
only the maximum amount
, which is BigDecimal
, which is Comparable
.
You could provide a comparator if you really wanted the bare minimum, but using min()
would be an easier choice in that regard.
source to share
You don't need a specific comparator for this. The comparator is not your problem.
The free-style prompt is nice, hip, and trendy, but it has one major flaw that many don't seem to notice: when an error happens somewhere along this train of function calls, you don't know where it happened.
So, to fix such problems, it is best to split the runaway train into separate cars. (At least for troubleshooting and getting back on the train if you want, all issues are fixed.)
In this case, you will see what it max()
returns Optional<BigDecimal>
, and this Optional
is because if yours is ArrayList
brol
empty (and in the above example it is empty) then max does not exist, because the operation is max
undefined on an empty list.
So, you need to indicate that yours is ArrayList
empty. You can do this before calling stream().max()
, or you can do it as Peter Lowry suggested by calling the method isPresent()
Optional
.
By the way, the fact that you made this mistake shows that either:
-
You are using outdated build tools that cannot give you warnings about your code, or
-
You don't have all the warnings, or
-
You receive warnings but ignore them.
Don't do this, you will never get very far. My IntelliJ IDEA gives me a warning (JetBrains calls this "validation") on your code, saying it .get()
was called without .isPresent()
. This way I can tell right away what is wrong with the code before compiling it, before running it, before troubleshooting it, and before asking a question about its stack.
source to share