如何在Java泛型类型推断不起作用时编译代码?

时间:2016-03-15 08:12:07

标签: java eclipse generics java-8 type-inference

我正在使用Java流API来组合多个地图。

逻辑是这样的:{1:a,2:b} + {1:b,3:c} = {1:[a,b],2:[b],3:[c]}

我将地图展平为K-V对,并使用&#34;按键分组&#34;收集结果。结果类型为Map<Key,List<Value>>

    List<Map<Key, Value>> maps = ....;
    maps.stream().flatMap(s->s.entrySet().stream()).collect(
        groupingBy(e -> e.getKey(), 
            mapping(e -> e.getValue(),  toList())
        )
    );

关于代码是好的。

然后我想对结果图的每个值应用一些操作。举个简单的例子,将[a,b]改为&#34; ab&#34;。所以我添加了collectingAndThen来对它们应用转换x->x

    List<Map<Key, Value>> maps = ....;
    maps.stream().flatMap(s->s.entrySet().stream()).collect(
        groupingBy(e -> e.getKey(), 
            mapping(e -> e.getValue(),  collectingAndThen(toList(),x->x))
        )
    );

并且上面的代码不会使用eclipse进行编译JDT说&#34;类型不匹配:无法从List<Value>转换为List<Object>&#34;

如果我将简单x-x更改为&#34;真实的&#34; x->transformValue(x)e -> e.getKey()上显示了e -> e.getValue()个错误消息:

The method getKey() is undefined for the type Object
The method getValue() is undefined for the type Object
The method transformValue(List<Value>) in the type 
Sometype is not applicable for the arguments (List<Object>)

我该如何解决这个问题?有什么办法可以告诉编译器<T> toList() -- public static <T> Collector<T, ?, List<T>> toList()Value类而不是Object?感谢。

编辑:

正如Stephan Herrmann在评论中所说,这是Eclipse JDT http://bugs.eclipse.org/489976的一个错误,将在4.6中修复。

2 个答案:

答案 0 :(得分:3)

你的代码编译没有错误,但我使用的是IntelliJ而不是Eclipse。

要明确指定toList()的类型参数,请使用Collectors.<Value>toList()调用它。

答案 1 :(得分:1)

collectingAndThen消耗的函数添加强制转换,例如.. (List<Value> x) x->x,并将其设为:

List<Map<Key, Value>> maps = ....;
maps.stream().flatMap(s->s.entrySet().stream()).collect(
    groupingBy(e -> e.getKey(), 
        mapping(e -> e.getValue(),  collectingAndThen(toList(),(List<Value> x) x->x))
    )
);

当它进入collectingAndThen时,它推断它应该是一个返回List<Object>的函数,它与预期的List<Value>不匹配...

如果你看到这样的问题,一个有用的做法是从lambda简写版恢复为完整函数,看看是否使用显式类型进行编译,例如:

Function<List<Value>, List<Value>> f = new Function<List<Value>, List<Value>>() {
    @Override
    public List<Value> apply(List<Value> x) {
        return x;
    }
};

另一个提示是,在流畅的API中,沿途可能会有很多类型推断,其中一些可能不是您所期望的......