简体   繁体   English

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

[英]Can not infer functional interface type in groupBy Java 8

I am not sure this has been answered earlier or not. 我不确定早些时候是否回答过。 Can anyone please tell me what is the problem with third groupBy which I've written ? 谁能告诉我第三groupBy的问题是什么我写的? Why it can not infer ? 为何无法推断?

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()));
    }
}

Stop using raw types! 停止使用原始类型!

This is mySupplier without raw types: 这是没有原始类型的mySupplier

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

The key type of an EnumMap must be an enum type, so you should use LifeCycle as the first argument. EnumMap的密钥类型必须是枚举类型,因此您应该使用LifeCycle作为第一个参数。 The second argument is what the collector you use at the end returns. 第二个参数是你在最后使用的收集器返回的内容。 You used toSet here, so I suppose you want a set of TestGroupBy . 你用toSet在这里,所以我想你想的一套TestGroupBy

That's how your supplier should look like, with proper generic arguments and LifeCycle.class as the key type of EnumMap ! 这就是你的供应商的样子, 使用适当的通用参数LifeCycle.class作为EnumMap的关键类型!

Now, you can do this: 现在,你可以这样做:

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

Note that your have to add () -> to make it a supplier. 请注意,您必须添加() ->才能使其成为供应商。

There are two things wrong with code you have shown us. 您向我们展示的代码有两个问题。 Firstly,you have passed wrong object with second argument of Collectors.groupingBy . 首先,你通过Collectors.groupingBy第二个参数传递了错误的对象。 You have passed EnumMap , not Supplier<EnumMap> . 您已通过EnumMap ,而不是Supplier<EnumMap>

Secondly, you cannot instantiate EnumMap with TestGroupBy.class , because TestGrouBy is not an enum. 其次,您无法使用TestGroupBy.class实例化EnumMap ,因为TestGrouBy不是枚举。 In your case it should be new EnumMap<>(LifeCycle.class) : 在你的情况下,它应该是new EnumMap<>(LifeCycle.class)

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

Also change implementation of mySupplier() method, because it's not correct. 还要更改mySupplier()方法的实现,因为它不正确。 It should be: 它应该是:

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

This code above will not work. 上面的代码不起作用。 Instead you should try: 相反,你应该尝试:

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

FInally, the reason for not working the below code: 最后,不使用以下代码的原因:

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

is: 是:

new EnumMap(TestGroupBy.class),

Because groupingBy accepts Supplier, not the kind of object which has been provided. 因为groupingBy接受供应商,而不是已提供的对象类型。

Also note that new EnumMap(TestGroupBy.LifeCycle.class) should have been used. 另请注意,应该使用new EnumMap(TestGroupBy.LifeCycle.class)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM