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