Java 8 个流聚合通用列表以映射

Java 8 stream agregate generic list to map

我试图通过在一个小型家庭项目中应用它来使用 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

你不应该使用原始类型。要么完全删除 t 的类型规范:

Map<Object, List<Double<Object, Object>>> myMap =
        listOfTriples.stream().collect(groupingBy(t -> t.a,
            mapping(t -> new Double<>(t.b, t.c),toList())));

或完全指定其类型:

Map<Object, List<Double<Object, Object>>> myMap =
        listOfTriples.stream().collect(groupingBy(t -> t.a,
            mapping((Triple<String, String, String> t) -> new Double<>(t.b, t.c),toList())));

您的映射中有 Triple 的原始类型。

如果您这样调整代码:

Map<String, List<Double<String, String>>> myMap =  
listOfTriples
.stream()
.collect(
  groupingBy(t -> t.a, 
    mapping((Triple<String, String, String> t) -> new Double<>(t.b, t.c), toList())
));

它应该有效