I recently made it through to the final round interview for a company in which they dissected the week-long take-home project they assigned me (Angular Spring Boot "Rock, Paper, Scissors" app). The details of the project don’t matter, my question is very specific. 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 this approach (they said optional.of() or stream.of() would suffice) and I was completely froze, 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! Thanks so much in advance
Summary
So to summarize they specifically asked me to reduce these 2 lines with Optional.of() or Stream.of() (overall code snippet below for context) and I couldn’t do it.
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());
}
>Solution :
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.
Here’s an example of Optional-abuse:
@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 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.