无法推断 groupBy 中的功能接口类型 Java 8

Can not infer functional interface type in groupBy Java 8

我不确定这是否已得到较早的回答。谁能告诉我我写的第三个 groupBy 有什么问题?为什么不能推断呢?

class TestGroupBy
{
    enum LifeCycle {
        ANNUAL, PERENNIAL
    }

    private String name;
    private LifeCycle lifeCycle;

    TestGroupBy(String name, LifeCycle lifeCycle) {
        this.name = name;
        this.lifeCycle = lifeCycle;
    }

    LifeCycle getLifeCycle() {
        return this.lifeCycle;
    }

    static EnumMap mySupplier() {
        return new EnumMap(TestGroupBy.class);
    }

    public static void main(String[] args) {
        List<TestGroupBy> garden = new ArrayList<>();
        garden.add(new TestGroupBy("Test1", TestGroupBy.LifeCycle.ANNUAL));
        garden.add(new TestGroupBy("Test2", TestGroupBy.LifeCycle.PERENNIAL));
        garden.add(new TestGroupBy("Test4", TestGroupBy.LifeCycle.ANNUAL));
        garden.add(new TestGroupBy("Test5", TestGroupBy.LifeCycle.PERENNIAL));

        // This works
        garden.stream()
            .collect(Collectors.groupingBy(e -> e.getLifeCycle()));

        // This works
        garden.stream()
            .collect(Collectors.groupingBy(
                e -> e.getLifeCycle(),
                TestGroupBy::mySupplier,
                Collectors.toSet()
            ));
        // This does not work
        garden.stream()
            .collect(Collectors.groupingBy(
                e -> e.getLifeCycle(),   // Can not resolve method getLifeCycle()
                new EnumMap(TestGroupBy.class),
                Collectors.toSet()));
    }
}

您向我们展示的代码有两处错误。首先,您使用 Collectors.groupingBy 的第二个参数传递了错误的对象。您通过了 EnumMap,而不是 Supplier<EnumMap>

其次,您不能用 TestGroupBy.class 实例化 EnumMap,因为 TestGrouBy 不是枚举。在您的情况下,它应该是 new EnumMap<>(LifeCycle.class):

garden.stream()
        .collect(Collectors.groupingBy(
              e -> e.getLifeCycle(),   // Can not resolve method getLifeCycle()
              () -> new EnumMap<>(LifeCycle.class),
              Collectors.toSet()));

同时更改 mySupplier() 方法的实现,因为它不正确。应该是:

static EnumMap mySupplier() {
    return new EnumMap<>(LifeCycle.class);
}

停止使用原始类型!

这是 mySupplier 没有原始类型:

static EnumMap<LifeCycle, Set<TestGroupBy>> mySupplier() {
    return new EnumMap<>(LifeCycle.class);
}

EnumMap 的键类型必须是枚举类型,因此您应该使用 LifeCycle 作为第一个参数。第二个参数是你最后使用的收集器returns。您在这里使用了 toSet,所以我想您想要一组 TestGroupBy.

这就是您的供应商应有的样子,使用适当的通用参数LifeCycle.class 作为 EnumMap 的键类型!

现在,您可以这样做:

    garden.stream()
            .collect(Collectors.groupingBy(
                    e -> e.getLifeCycle(),
                    () -> new EnumMap<>(LifeCycle.class),
                    Collectors.toSet()));

请注意,您必须添加 () -> 才能使其成为供应商。

static EnumMap mySupplier() {
    return new EnumMap(TestGroupBy.class);
}

上面的代码将不起作用。相反,您应该尝试:

static EnumMap<LifeCycle, Set<TestGroupBy>> mySupplier() {
    return new EnumMap<>(TestGroupBy.LifeCycle.class); // Key class is changed.
}

最后,以下代码无法运行的原因:

garden.stream()
        .collect(Collectors.groupingBy(
            e -> e.getLifeCycle(),   
            new EnumMap(TestGroupBy.class),
            Collectors.toSet()));

是:

new EnumMap(TestGroupBy.class),

因为groupingBy接受的是Supplier,而不是已经提供的那种object。

另请注意,应该使用 new EnumMap(TestGroupBy.LifeCycle.class)