Search code examples
javalambdajava-streamoption-type

Can this code be reduced using Java 8 Streams?


I want to use Java 8 lambdas and streams to reduce the amount of code in the following method that produces an Optional. Is it possible to achieve?

My code:

protected Optional<String> getMediaName(Participant participant) {

  for (ParticipantDevice device : participant.getDevices()) {

      if (device.getMedia() != null && StringUtils.isNotEmpty(device.getMedia().getMediaType())) {

          String mediaType = device.getMedia().getMediaType().toUpperCase();
          Map<String, String> mediaToNameMap = config.getMediaMap();

          if (mediaMap.containsKey(mediaType)) {
              return Optional.of(mediaMap.get(mediaType));
          }
      }
  }
  return Optional.empty();
}

Solution

  • Firstly, since your Map of media types returned by config.getMediaMap() doesn't depend on a particular device, it makes sense to generate it before processing the collection of devices. I.e. regurless of the approach (imperative or declarative) do it outside a Loop, or before creating a Stream, to avoid generating the same Map multiple times.

    And to implement this method with Streams, you need to use filter() operation, which expects a Predicate, to apply the conditional logic and map() perform a transformation of stream elements.

    To get the first element that matches the conditions apply findFirst(), which produces an optional result, as a terminal operation.

    protected Optional<String> getMediaName(Participant participant) {
        
        Map<String, String> mediaToNameMap = config.getMediaMap();
        
        return participant.getDevices().stream()
            .filter(device -> device.getMedia() != null
                && StringUtils.isNotEmpty(device.getMedia().getMediaType())
            )
            .map(device -> device.getMedia().getMediaType().toUpperCase())
            .filter(mediaToNameMap::containsKey)
            .map(mediaToNameMap::get)
            .findFirst();
    }