Setting a value if not null within a java stream

Viewed 2804

How can I handle null checks in the below code using Java 8 when my counterparty can be null. I want to set counterParty only if it has a value and not set if it is empty.

 public static Iterable<? extends Trade> buildTrade (final List<Trade> trade) {
    return () -> trade.stream()
                .map(trade -> Trade.newBuilder()
                    .setType(trade.type())              
                    .setUnit(trade.unit())
                    .setCounterParty(trade.counterParty())                  
                    .build())
                .iterator();
    }
2 Answers

You can use the following code:

trade.stream()
            .map(trade -> {
                TradeBuilder tb = Trade.newBuilder()
                    .setType(trade.type())              
                    .setUnit(trade.unit());
                Optional.ofNullable(trade.counterParty())
                    .ifPresent(tb::setCounterParty);
                return tb.build();
             })
            .iterator();

Or without Optional:

trade.stream()
            .map(trade -> {
                TradeBuilder tb = Trade.newBuilder()
                    .setType(trade.type())              
                    .setUnit(trade.unit());
                if(trade.counterParty() != null) tb.setCounterParty(trade.counterParty());
                return tb.build();
             })
            .iterator();

The stream aspect of this has no relevance to the question; let's strip it out:

 trade -> Trade.newBuilder()
    .setType(trade.type())              
    .setUnit(trade.unit())
    .setCounterParty(trade.counterParty())                  
    .build()

You're asking to not set counterParty if it is null.

A really easy way to do this would be to modify builder class's setCounterParty() to do nothing and return, if the parameter is null.

TradeBuilder setCounterParty(CounterParty cp) {
   if(cp != null) {
      this.counterParty = cp;
   }
   return this;
}

You do need to ensure that this behaviour is consistent with other callers' needs.

If your builder is being dynamically generated by some framework (Lombok etc), you might not have code in which you can easily make this change -- but most such frameworks have mechanisms that allow you to take control of that kind of thing.

If you can't modify the builder, you can break up the calls to it, and surround one call with an if:

 trade -> { 
    TradeBuilder b = Trade.newBuilder()
      .setType(trade.type())              
      .setUnit(trade.unit());
    if(trade.counterParty() != null) {
      b.setCounterParty(trade.counterParty());
    }
    return b.build()
 }
Related