BigDecimal min() method with one operand null

Viewed 593

I have this comparison:

BigDecimal firstLimit = null; <<-------------------------sometimes firstLimit could be null
BigDecimal secondLimit = BigDecimal.valueof(10); <<--- sometimes secondLimit can be null
BigDecimal thirdLimit = BigDecimal.valueof(20);  <<--- sometimes thirdLimit can be null
BigDecimal minLimit = firstLimit.min(secondLimit.min(thirLimit))

Initially I tried to set any value that ends up being null with an arbitrary ceiling value but I am not allowed to do that. This means that I would need to get rid of this one line comparison solution for a lengthy if-else-if and I would really prefer not to. Is there an elegant way to handle the null case scenario. Any suggestions would be much appreciated. Thank you.

3 Answers

I think you can use Stream.of like this:

BigDecimal minLimit = Stream.of(firstLimit, secondLimit, thirdLimit)
        .filter(Objects::nonNull)
        .min(BigDecimal::compareTo)
        .orElse(null); // Or return a default value

Or you can throw an exception if all inputs are null:

BigDecimal minLimit = Stream.of(firstLimit, secondLimit, thirdLimit)
        .filter(Objects::nonNull)
        .min(BigDecimal::compareTo)
        .orElseThrow(() -> new IllegalArgumentException("All values are null"));

Or as Holger mentioned in comment, instead of .min(BigDecimal::compareTo) you can use .min(Comparator.naturalOrder())

BigDecimal minLimit = Stream.of(firstLimit, secondLimit, thirdLimit)
        .filter(Objects::nonNull)
        .min(Comparator.naturalOrder())
        .orElseThrow(() -> new IllegalArgumentException("All values are null"));

Assuming I understand your question, this seems like a place you could use a ternary. Like,

BigDecimal minLimit = firstLimit != null ?
        firstLimit.min(secondLimit.min(thirdLimit)) :
        secondLimit.min(thirdLimit);

Alternatively, a default initial value and one if should suffice (order of comparisons doesn't matter to find the minimum). Like,

BigDecimal minLimit = secondLimit.min(thirdLimit);
if (firstLimit != null) {
    minLimit = minLimit.min(firstLimit);
}

You can also use Optional from java 8

BigDecimal minLimit = Optional.ofNullable(firstLimit)
                              .map(fl->fl.min(secondLimit.min(thirLimit)))
                              .orElse(secondLimit.min(thirLimit));
Related