我正在通过将Java 8 流功能应用于一个小型家庭项目中来逐渐熟悉它。最近,我遇到了以下问题,尽管我理解这个问题,但是我找不到解决方法。我在这里发布帖子,希望得到一些解释和正确的解决方案。
public class GroupingByStreamTest {
class Double<A, B> {
A a;
B b;
public Double(A a, B b) {
this.a = a;
this.b = b;
}
}
class Triple<A, B, C> extends Double<A, B> {
C c;
public Triple(A a, B b, C c) {
super(a, b);
this.c = c;
}
}
@Test
public void shouldGroupToMap() throws Exception {
List<Triple<String, String, String>> listOfTriples = asList(
new Triple<>("a-1", "b-1", "c-1"),
new Triple<>("a-1", "b-2", "c-2"),
new Triple<>("a-1", "b-3", "c-3"),
new Triple<>("a-2", "b-4", "c-4"),
new Triple<>("a-2", "b-5", "c-5"));
// This code below compiles and executes OK. If I put a breakpoint
// in my EDI I can even see the expected Map being created. However
// if you uncomment the line below and comment the one after it the
// code will no longer compile.
// Map<String, List<Double<String, String>>> myMap =
Map<Object, List<Double<Object, Object>>> myMap =
listOfTriples.stream().collect(groupingBy(t -> t.a,
mapping((Triple t) -> new Double<>(t.b, t.c),toList())));
assertEquals(2, myMap.size());
}
}
我遇到的编译错误是:
Error:(49, 39) java: incompatible types: inference variable A has incompatible bounds
equality constraints: java.lang.String
lower bounds: java.lang.Object
mapping
收集器中使用了原始类型Triple
参数。尝试使用Triple<String, String, String>
,或者更简单地使用mapping(t -> new Double<>(...))
,编译器会自动推断出它是一个Triple<String, String, String>
。(顺便说一下,在groupingBy(t -> t.a)
中没有指定它。) - Alexis C.Double
,因为它会与java.lang.Double
发生冲突,这会导致未来的问题。可以将其命名为Pair
或类似的名称。而在另一个代码中,Triple extends Double
也是一种坏味道。三元组不是二元组,一旦尝试为其添加正确的equals
和hashCode
方法,就会注意到问题。 - Holger