Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic toMap Collector cannot compile

I am trying to create a fairly simple Collector that converts a Stream<Map.Entry> into a Map, but javac is complaining about the generics. Can't figure out why it's not working.

import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CollectorSO {
    public static <K, V> void main(String[] args) {
        Collector<Entry<K, V>, ?, Map<K, V>> collector = Collectors.toMap(Entry::getKey, Entry::getValue);
        Stream<Entry<String, Object>> stream = Stream.empty();
        Map<String, Object> map = stream.collect(collector);
    }
}

Compiler output:

Error:(11, 41) java: no suitable method found for collect(java.util.stream.Collector<java.util.Map.Entry<K,V>,capture#1 of ?,java.util.Map<K,V>>)
method java.util.stream.Stream.<R>collect(java.util.function.Supplier<R>,java.util.function.BiConsumer<R,? super java.util.Map.Entry<java.lang.String,java.lang.Object>>,java.util.function.BiConsumer<R,R>) is not applicable
  (cannot infer type-variable(s) R
    (actual and formal argument lists differ in length))
method java.util.stream.Stream.<R,A>collect(java.util.stream.Collector<? super java.util.Map.Entry<java.lang.String,java.lang.Object>,A,R>) is not applicable
  (cannot infer type-variable(s) R,A
    (argument mismatch; java.util.stream.Collector<java.util.Map.Entry<K,V>,capture#1 of ?,java.util.Map<K,V>> cannot be converted to java.util.stream.Collector<? super java.util.Map.Entry<java.lang.String,java.lang.Object>,A,R>))

This looks similar on the surface, but I'm having the problem even with JDK 1.8.0_60.

like image 988
Yosef Weiner Avatar asked Mar 29 '26 20:03

Yosef Weiner


1 Answers

It's because of the type variables you declare for your main method. They are not captured in that context, and hence you can not collect your Entry<String, Object> stream with your Entry<K, V>, ?, Map<K, V> collector. What you are looking is probably something like this:

public class CollectorSO
{
    public static void main(String[] args)
    {
        Stream<Entry<String, Object>> stream = Stream.empty();
        Map<String, Object> map = stream.collect(entryToMapCollector());
    }

    private static <K, V> Collector<Entry<K, V>, ?, Map<K, V>> entryToMapCollector()
    {
        return Collectors.toMap(Entry::getKey, Entry::getValue);
    }
}

Good luck!

like image 132
Per Huss Avatar answered Apr 02 '26 12:04

Per Huss



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!