Home > other >  Split a Map<Object, Optional<String>> in two lists, based of Optional.isPresent()
Split a Map<Object, Optional<String>> in two lists, based of Optional.isPresent()

Time:09-30

I have a map of type Map<Object, Optional<String>>. What is the most concise way to split this map into two lists. The first list should have a list of Objects, for which the Optional is present, and the second list should have a list of Objects, for which the Optional is not present.

I came up with that, but is there a better way:

List<Object> a = new ArrayList<>();
List<Object> b = new ArrayList<>();
myMap.forEach((obj, str) -> {
  if (str.isEmpty()) {
    a.add(obj);
  } else {
    b.add(obj);
  }
});

CodePudding user response:

With streams this may look like this:

    Map<Boolean,List<Object>> collect = myMap.entrySet().stream()
        .collect(partitioningBy(e -> e.getValue().isPresent(), 
            mapping(e -> e.getKey(), toList())));

    List<Object> a = collect.get(false);
    List<Object> b = collect.get(true);

Not really more readable, but a more functional style.

CodePudding user response:

I would extract a method with filter logic.

public static void main(String[] args) {
    Map<Object, Optional<String>> map = Map.of();
    List<Object> empty = filterValueAndGetKeys(map, Optional::isEmpty);
    List<Object> notEmpty = filterValueAndGetKeys(map, Optional::isPresent);
}

private static <T> List<T> filterValueAndGetKeys(Map<T, Optional<String>> map,
                                              Predicate<Optional<String>> valueFilter) {
    return map.entrySet().stream()
              .filter(entry -> valueFilter.test(entry.getValue()))
              .map(Map.Entry::getKey)
              .collect(Collectors.toUnmodifiableList());
}
  •  Tags:  
  • java
  • Related