收集器分组按类型推断失败

时间:2019-05-16 09:19:22

标签: java intellij-idea type-inference

我有一个Map<String, Long>

我想基于Map<Long, List<String>>格式构建一个新地图。

它在第一个映射中给出了给定long值的字符串列表。

示例:

a 1
b 1
c 2

result:
1 [a, b]
2 [c]

要使用已排序的顺序获取地图键,我正在使用TreeMap。下面的代码工作正常

Map<String, Long> originalMap = new HashMap<>();
        //...
TreeMap<Long, List<String>> result = originalMap.entrySet()
            .stream()
           .collect(Collectors.groupingBy(Map.Entry::getValue, TreeMap::new,
                    Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

如果我希望键按降序排列,则可以将TreeMap与Comparator一起使用

new TreeMap<>(Comparator.reverseOrder())

将其放入代码中即可产生

TreeMap<Long, List<String>> result = originalMap.entrySet()
            .stream()
            .collect(Collectors.groupingBy(Map.Entry::getValue, () -> new TreeMap<>(Comparator.reverseOrder()),
                    Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

我的IDE(Intellij)不会显示任何编译错误。但是,当我尝试运行此命令时,它会引发编译错误(在IDE中不会显示任何错误,但在运行时会导致编译失败)。

javac也会编译失败。

Main.java:12: error: no suitable method found for groupingBy((e)->e.getValue(),()->new Tr[...]er()),Collector<Object,CAP#1,List<Object>>)
                .collect(Collectors.groupingBy(e -> e.getValue(), () -> new TreeMap<>(Comparator.reverseOrder()),
                                   ^
    method Collectors.<T#1,K#1>groupingBy(Function<? super T#1,? extends K#1>) is not applicable
      (cannot infer type-variable(s) T#1,K#1
        (actual and formal argument lists differ in length))
    method Collectors.<T#2,K#2,A#1,D#1>groupingBy(Function<? super T#2,? extends K#2>,Collector<? super T#2,A#1,D#1>) is not applicable
      (cannot infer type-variable(s) T#2,K#2,A#1,D#1
        (actual and formal argument lists differ in length))
    method Collectors.<T#3,K#3,D#2,A#2,M>groupingBy(Function<? super T#3,? extends K#3>,Supplier<M>,Collector<? super T#3,A#2,D#2>) is not applicable
      (inferred type does not conform to upper bound(s)
        inferred: Object
        upper bound(s): Comparable<? super T#4>,T#4,Object)
  where T#1,K#1,T#2,K#2,A#1,D#1,T#3,K#3,D#2,A#2,M,T#4 are type-variables:
    T#1 extends Object declared in method <T#1,K#1>groupingBy(Function<? super T#1,? extends K#1>)
    K#1 extends Object declared in method <T#1,K#1>groupingBy(Function<? super T#1,? extends K#1>)
    T#2 extends Object declared in method <T#2,K#2,A#1,D#1>groupingBy(Function<? super T#2,? extends K#2>,Collector<? super T#2,A#1,D#1>)
    K#2 extends Object declared in method <T#2,K#2,A#1,D#1>groupingBy(Function<? super T#2,? extends K#2>,Collector<? super T#2,A#1,D#1>)
    A#1 extends Object declared in method <T#2,K#2,A#1,D#1>groupingBy(Function<? super T#2,? extends K#2>,Collector<? super T#2,A#1,D#1>)
    D#1 extends Object declared in method <T#2,K#2,A#1,D#1>groupingBy(Function<? super T#2,? extends K#2>,Collector<? super T#2,A#1,D#1>)
    T#3 extends Object declared in method <T#3,K#3,D#2,A#2,M>groupingBy(Function<? super T#3,? extends K#3>,Supplier<M>,Collector<? super T#3,A#2,D#2>)
    K#3 extends Object declared in method <T#3,K#3,D#2,A#2,M>groupingBy(Function<? super T#3,? extends K#3>,Supplier<M>,Collector<? super T#3,A#2,D#2>)
    D#2 extends Object declared in method <T#3,K#3,D#2,A#2,M>groupingBy(Function<? super T#3,? extends K#3>,Supplier<M>,Collector<? super T#3,A#2,D#2>)
    A#2 extends Object declared in method <T#3,K#3,D#2,A#2,M>groupingBy(Function<? super T#3,? extends K#3>,Supplier<M>,Collector<? super T#3,A#2,D#2>)
    M extends Map<K#3,D#2> declared in method <T#3,K#3,D#2,A#2,M>groupingBy(Function<? super T#3,? extends K#3>,Supplier<M>,Collector<? super T#3,A#2,D#2>)
    T#4 extends Comparable<? super T#4> declared in method <T#4>reverseOrder()
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
Main.java:13: error: cannot find symbol
                        Collectors.mapping(e -> e.getKey(), Collectors.toList())));
                                                 ^
  symbol:   method getKey()
  location: variable e of type Object
2 errors

要解决此问题,我必须向Comparator.reverseOrder添加类型见证人

() -> new TreeMap<>(Comparator.<Long>reverseOrder())

有趣的一点是Intellij在这里显示为Explicit type arguments can be inferred的警告,即表示不需要在此处添加类型实参/见证。

enter image description here 问题:

1)它是否由于Java(复杂)类型系统的弱点而导致编译失败?

2)为什么Intellij无法捕获编译错误? Intellij编译器和javac之间不匹配?

0 个答案:

没有答案