HashMap
allows to store NULL
value, but Stream.toMap(r-> r.getName(), r->r.get(obj))
would throw NPE when r.get(obj)
returns null? Do I miss something or Stream
has a special reason to be more careful than Map
? I am trying to use reflection and java8 to achieve (new ObjectMapper()).convertValue(obj, Obj.class);
Asked
Active
Viewed 3,047 times
3

Tiina
- 4,285
- 7
- 44
- 73
-
2Have a look here - http://stackoverflow.com/questions/24630963/java-8-nullpointerexception-in-collectors-tomap – Lachezar Balev Apr 25 '17 at 09:43
-
@LachezarBalev thanks, so they don't have a special reason. but i still don't think it is a good idea to have a different behavior of a well-known structure as they look the same. – Tiina Apr 25 '17 at 09:47
1 Answers
2
Collector.toMap uses HashMap::merge to combine results:
public V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
if (value == null)
throw new NullPointerException();
if (remappingFunction == null)
throw new NullPointerException();
So it may store null values, but merge does not allow it.
You can do a work around, by using forEach
stream.forEach (
r-> map.put(r.getName(), r.get(obj))
)

Beri
- 11,470
- 4
- 35
- 57
-
9I wouldn't use this workaround, but instead a standard collect: `stream().collect(HashMap::new, (m, r) -> m.put(r.getName(), r.get(obj)), Map::putAll);` – Alexis C. Apr 25 '17 at 10:03
-
@AlexisC. Very good idea. Should be the way to do it if HashMap is expected. – Tiina Apr 26 '17 at 00:54
-
@AlexisC. signature for `putall` is `void putAll(Map extends K, ? extends V> m);` while for `collect` is `
R collect(Supplier – Tiina Sep 11 '17 at 03:50supplier, BiConsumer accumulator, BiConsumer combiner);` `combiner` takes two argument, why `putall` taking one `map` fits `combiner` taking `T` and `U`? -
@Tiina Try checking this link: http://www.logicbig.com/tutorials/core-java-tutorial/java-util-stream/collect/ . The combiner is used only in parallel streams, and it must be an associative function. – Beri Sep 11 '17 at 07:21