3

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.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 1
    If you would have placed that lengthy solution, it would have been clear as per what you are actually looking for and the cases you intend to address in your solution. for, e.g. if all three are `null`, what do you expect the output to be? – Naman Jun 28 '20 at 15:50

3 Answers3

7

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"));
Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • What if all three limits can be null. Is there a way that this could be adapted to work with the case where all three limits can be null? –  Jun 28 '20 at 15:31
  • 1
    @MilanPopescu yes my solution work even all the three are null – Youcef LAIDANI Jun 28 '20 at 15:31
  • 3
    Instead of `BigDecimal::compareTo`, you can also use `Comparator.naturalOrder()` – Holger Jun 28 '20 at 15:48
  • Thank you @Holger can you please explain what is the difference between them? – Youcef LAIDANI Jun 28 '20 at 15:52
  • 5
    `Comparator.naturalOrder()` returns a shared singleton, reusable for all classes implementing `Comparable` whereas `BigDecimal::compareTo` requests a `Comparator` implementation calling `compareTo` of `BigDecimal`, which in the current implementation creates a distinct class. – Holger Jun 28 '20 at 15:55
1

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);
}
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • What if all three limits can be null. Is there a way that this could be adapted to work with the case where all three limits can be null? –  Jun 28 '20 at 15:30
  • 3
    @MilanPopescu **Please** don't edit your question to change the requirements like that with-in 10 minutes of asking the question. You asked *BigDecimal min() method with one operand null*. Extract this logic to a method. Then you can play with it as long as you want, and the caller can use a one line invocation to get the `min`. – Elliott Frisch Jun 28 '20 at 15:35
1

You can also use Optional from java 8

BigDecimal minLimit = Optional.ofNullable(firstLimit)
                              .map(fl->fl.min(secondLimit.min(thirLimit)))
                              .orElse(secondLimit.min(thirLimit));
Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
  • What if all three limits can be null. Is there a way that this could be adapted to work with the case where all three limits can be null? –  Jun 28 '20 at 15:30
  • 1
    I wouldn't like to add duplicate answer, but for you comment approach you can go with YCF_L answer https://stackoverflow.com/a/62624614/9959152 – Ryuzaki L Jun 28 '20 at 15:34