3
Optional<Long>totalLanding= ....(get it from somewhere);
Optional<Long>totalSharing = ...(get it from somewhere);

I want to do something like this not syntactically but logically

Optional<Long>total = totalLanding+totalSharing;

Such that if both are empty then total should be empty if one of them has the value then total should have that value is both of them have the value then they should get added and stored in total

bhoomeendra
  • 197
  • 1
  • 8

5 Answers5

9

How about using Streams?

Optional<Long> total = Stream.of(totalLanding,totalSharing)
                             .filter(Optional::isPresent)
                             .map(Optional::get)
                             .reduce(Long::sum);

BTW, I'd use OptionalLong instead of Optional<Long>.

The solution would be similar:

OptionalLong total = Stream.of(totalLanding,totalSharing)
                           .filter(OptionalLong::isPresent)
                           .mapToLong(OptionalLong::getAsLong)
                           .reduce(Long::sum);
Eran
  • 387,369
  • 54
  • 702
  • 768
  • You are forgetting that optional is a stream too. See my answer. – kan Dec 31 '19 at 12:30
  • 1
    @kan You mean that `Optional` has a `stream()` method. `Optional` is not a `Stream`. And it's not that I forgot, I'm just less familiar with methods added after Java 8. – Eran Dec 31 '19 at 12:32
  • Agree, I meant logically it's a stream too, alas Java 8 lacks it. Seems Java 8 API authors forgot it then ;) – kan Dec 31 '19 at 13:02
5

Java 9 or newer:

Optional<Long>total = Stream.concat(
        totalLanding.stream(),
        totalSharing.stream())
    .reduce(Long::sum)

Java 8 compatible variant:

Optional<Long>total = Stream.concat(
        totalLanding.map(Stream::of).orElseGet(Stream::empty),
        totalSharing.map(Stream::of).orElseGet(Stream::empty))
    .reduce(Long::sum)

Or better to extract the .map(Stream::of).orElseGet(Stream::empty) as a utility method and reuse. Or other variants here: How to convert an Optional<T> into a Stream<T>?

kan
  • 28,279
  • 7
  • 71
  • 101
0

This should work with Java 8:

Optional<Long> total = totalLanding.map(x -> x + totalSharing.orElse(0L))
        .map(Optional::of)   // wrap it twice for the next line to find an Optional inside
        .orElse(totalSharing);
Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92
-1

How about

BigDecimal zero = BigDecimal.ZERO

Optional<Long> addition = Optional.of(totalLanding.orElse(zero).add(totalSharing.orElse(zero)));
Sid
  • 4,893
  • 14
  • 55
  • 110
  • Something like that was my idea too, but it wouldn't return an empty optional if neither was set. – findusl Dec 31 '19 at 11:36
-2

We can do like:

Optional<Long>result = Optional.of((totalLanding != null ? totalLanding.get() : 0L) + (totalSharing != null ? totalSharing.get() : 0L));
malware
  • 393
  • 1
  • 3
  • 16
  • Have you actually tried that? This should lead to a NullPointerException if any of the Optionals is the result of `Optional.ofNullable(null)`. – Lothar Dec 31 '19 at 11:43
  • Also does not work for requirement _if both are empty then total should be empty_ – kan Dec 31 '19 at 13:48