Home > Mobile >  Interview question - How to use Optional.of() or Stream.of() to reduce code
Interview question - How to use Optional.of() or Stream.of() to reduce code

Time:10-25

I recently made it through to the final round of interview.

At one point in the interview, they asked me to demonstrate my Java 8 knowledge on the following piece of code. They asked me to reduce the following code using either Optional.of() or Stream.of(). And I was completely frozen, I only ever used streams on lists and didn't know how to use the optional approach. I didn't get the job specifically for this reason, as they said my understanding of java8 wasn't good enough. Can someone please tell me what they were looking for?

Summary

I've been specifically asked to reduce these 2 lines with Optional.of() or Stream.of():

gameDto = gameplay.playRandomGame(gameDto);
repo.updateTotals(gameDto.getResult());

Overall snippet for a bit of context:

@Service("gameService")
public class GameServiceImpl implements GameService{
    
    @Autowired
    private SessionInMemoryRegistry sessionRegistry;
    
    @Autowired
    private GameInMemoryRepo repo;
    
    @Autowired
    private GamePlay gameplay;

    @Override
    public ResponseDto addGameToSession(GameDto gameDto) {
        gameDto = gameplay.playRandomGame(gameDto);
        repo.updateTotals(gameDto.getResult());
        return sessionRegistry.addGameSession(gameDto.getSessionId(), gameDto.getPlayer1Choice(), gameDto.getPlayer2Choice(), gameDto.getResult());
    }
}

CodePudding user response:

First of all, this code is fishy: @Autowired on fields, reassigned method argument.

And if you ask my opinion, this code doesn't need neither Streams, no Optional (since there's no method involved which return one). It seems like you were asked to rewrite the code in an obscuring way so that it would abuse either an Optional or Stream.

Number of lines is not a metric for code quality.

Here's an example of Stream-abuse:

@Override
public ResponseDto addGameToSession(GameDto gameDto) {
    
    Stream.of(gameDto)
        .map(gameplay::playRandomGame)
        .forEach(gDto -> repo.updateTotals(gDto.getResult()));
    
    return sessionRegistry.addGameSession(gameDto.getSessionId(), gameDto.getPlayer1Choice(), gameDto.getPlayer2Choice(), gameDto.getResult());
}

The code above unnecessarily operates via side-effects, which is disparaged be the Stream API documentation.

And here's an example of Optional-abuse (it can be more frequently observed with Optional.ofNullable()):

@Override
public ResponseDto addGameToSession(GameDto gameDto) {
    
    Optional.of(gameDto)
        .map(gameplay::playRandomGame)
        .ifPresent(gDto -> repo.updateTotals(gDto.getResult()));
    
    return sessionRegistry.addGameSession(gameDto.getSessionId(), gameDto.getPlayer1Choice(), gameDto.getPlayer2Choice(), gameDto.getResult());
}

The Optional is a container of data, which intended to represent a return type. You can wrap it around something nullable and that would allow to interact safely with a result of method call regardless whether it contains a value or not.

Creation an Optional only in order chain methods on it goes against its design goal. It's a smell and should be avoided.

Regarding the usage of Optional, see this and this answers by @Stuart Marks, Java and OpenJDK developer.

  • Related