我正在使用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中修复。
答案 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中,沿途可能会有很多类型推断,其中一些可能不是您所期望的......