Is there an elegant way to convert a Map<P, Optional<Q>> to a sparse Map<P, Q>?

  • A+
Category:Languages

Is there an elegant way to convert a Map<P, Optional<Q>> to a sparse Map<P, Q> ?

This should work, but it's a bit meh:

Map<P,Optional<Q>> map = ...; Map<P,Q> map2 = map.entrySet()                   .stream().filter(e -> e.getValue().isPresent())                   .collect(Collectors.toMap(e -> e.getKey(), e->e.getValue().get())); 

 


It's simpler when you create a new map and add values by iterating over the original map:

Map<P, Q> map2 = new HashMap<>(); map.forEach((p, q) -> map2.compute(p, (k, v) -> q.orElse(null))); 

All original entries for which value.isPresent() would return false are skipped (not included in result): Map.compute removes/ignores the key's mapping when remappingFunction yields null.


Here's an example to clarify how nulls are dealt with:

Map<String, Optional<Integer>> map = new HashMap<>(); map.put("one", Optional.of(1)); map.put("two", Optional.of(2)); map.put("three", Optional.empty()); map.put("four", Optional.of(4)); map.put("five", Optional.empty());  Map<String, Integer> map2 = new HashMap<>(); map.forEach((p, q) -> map2.compute(p, (k, v) -> q.orElse(null)));  System.out.println(map2); 

The output is {four=4, one=1, two=2} (when map2.compute gets null from q.orElse, p is not added to map2)

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: