Given:
import com.google.common.collect.ImmutableMap;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;
public class Testcase
{
public static <T, K, V> MapCollectorBuilder<T, K, V>
toImmutableMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper)
{
return null;
}
public static final class MapCollectorBuilder<T, K, V>
{
public Collector<T, ?, ImmutableMap<K, V>> build()
{
return null;
}
}
public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap2(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper)
{
return null;
}
public void main(String[] args)
{
Function<String, String> keyMapper = i -> i;
Function<String, Integer> valueMapper = Integer::valueOf;
ImmutableMap<String, Integer> map1 = Stream.of("1", "2", "3")
.collect(Testcase.toImmutableMap(keyMapper, valueMapper).build());
ImmutableMap<String, Integer> map2 = Stream.of("1", "2", "3")
.collect(Testcase.toImmutableMap(i -> i, Integer::valueOf).build());
ImmutableMap<String, Integer> map3 = Stream.of("1", "2", "3")
.collect(Testcase.toImmutableMap2(i -> i, Integer::valueOf));
}
}
The statements involving map1
and map3
compile fine, but map2
fails with:
Testcase.java:[41,57] incompatible types: cannot infer type-variable(s) T,K,V
(argument mismatch; invalid method reference
no suitable method found for valueOf(java.lang.Object)
method java.lang.Integer.valueOf(java.lang.String) is not applicable
(argument mismatch; java.lang.Object cannot be converted to java.lang.String)
method java.lang.Integer.valueOf(int) is not applicable
(argument mismatch; java.lang.Object cannot be converted to int))
The compiler error can be solved by providing explicit type parameters <String, String, Integer>
.
- When does Java 8 require explicit type parameters? Meaning, is there a known pattern that breaks type inference?
- Can
toImmutableMap()
andMapCollectorBuilder
be changed to avoid explicit type parameters without losing the use of a Builder for configuring the Collector?
UPDATE:
- Why does the statement involving
map3
work? How does it differ from the statement involvingmap2
?