Given a Set
of objects that I want to use as keys, how can I easily get a Map
instance leaving the values as null?
The purpose is to pre-populate the map with keys before determining the values to be stored.
Of course, I could create an empty map, then loop the set of would-be key objects, while doing a put
on each, along with null
as the value.
Set< Month > months = EnumSet.of( Month.MARCH , Month.MAY , Month.JUNE ) ;
Map< Month , String > map = new EnumMap<>( Month.class ) ;
for( Month month : months )
{
map.put( month , null ) ;
}
I just wonder if there is a nifty trick to do this with less code. Something like the opposite of Map#keySet
.
Collectors.toMap()
and the static factory methods like Map.of()
use internally Map.merge
which will throw NPE if key or value is null.
See this post: java-8-nullpointerexception-in-collectors-tomap. And see this issue page on the OpenJDK project: JDK-8148463 Collectors.toMap fails on null values
You could work around by using Stream.collect
with the three args signature as a reduction.
collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
Something like:
Set< Month > months = EnumSet.of( Month.MARCH , Month.MAY , Month.JUNE ) ;
Map< Month , String > myMap =
months.stream()
.collect(
HashMap::new ,
( map , val )-> map.put( val , null ) ,
HashMap::putAll
);
System.out.println(myMap);
See that code run live at IdeOne.com.
But I'm not sure if this is either more readable or more elegant than your approach with the classic for-loop