Java 静态上下文无法访问收集器中的非静态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40172551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:28:43  来源:igfitidea点击:

Static context cannot access non-static in Collectors

javajava-8java-streammethod-referencecollect

提问by Jude Niroshan

I have group of students. First I want to group them by the marks. Then I want to further group those sets into same name students together.

我有一群学生。首先,我想按标记对它们进行分组。然后我想进一步将这些集合分组为同名学生。

Map<Integer,Map<String,List<String>>> groupping = students.stream()
                                                    .collect(Collectors.groupingBy(Student::getMarks, 
                                                            Collectors.mapping(Student::getName,Collectors.toList())));

I am getting an error saying,

我收到一个错误说,

Non-static method cannot be refered from a static context.

不能从静态上下文中引用非静态方法。

Yes. I am pretty much aware that I cannot refer to a non-static method without having an instance. But with all these stream operations, I'm a bit confused about what has gone wrong really.

是的。我非常清楚我不能在没有实例的情况下引用非静态方法。但是对于所有这些流操作,我对到底出了什么问题感到有些困惑。

Rather than how to fix this; I really want to know what's going on here. Any of your inputs is appreciated!

而不是如何解决这个问题;我真的很想知道这里发生了什么。感谢您的任何意见!

Because If I write the below grouping is completely valid;

因为如果我写下面的分组是完全有效的;

Map<Integer,List<Student>> m = students.stream().
        collect(Collectors.groupingBy(Student::getMarks));

Here is my Student.java class (In case if you need it)

这是我的 Student.java 类(如果你需要的话)

public class Student {
    private String name;
    private int marks;
    // getters, setters, constructor and toString
}

采纳答案by Holger

Unfortunately, the error message “Non-static method cannot be refered from a static context.” is just a place-holder for any type mismatch problem, when method references are involved. The compiler simply failed to determine the actual problem.

不幸的是,错误消息“不能从静态上下文中引用非静态方法。” 当涉及方法引用时,它只是任何类型不匹配问题的占位符。编译器根本无法确定实际问题。

In your code, the target type Map<Integer, Map<String, List<String>>>doesn't match the result type of the combined collector which is Map<Integer, List<String>>, but the compiler didn't try to determine this (stand-alone) result type, as the (nested) generic method invocations incorporating method references requires the target type for resolving the method references. So it doesn't report a type mismatch of the assignment, but a problem with resolving the method references.

在您的代码中,目标类型Map<Integer, Map<String, List<String>>>与组合收集器的结果类型不匹配,即Map<Integer, List<String>>,但编译器并未尝试确定此(独立)结果类型,因为(嵌套)泛型方法调用合并了方法引用需要用于解析方法引用的目标类型。所以它不会报告赋值的类型不匹配,而是解决方法引用的问题。

The correct code simply is

正确的代码就是

Map<Integer, List<String>> groupping = students.stream()
    .collect(Collectors.groupingBy(Student::getMarks, 
             Collectors.mapping(Student::getName, Collectors.toList())));

回答by Supun Wijerathne

I think Holger has given a good explanation about the error and why it doesn't make much sense in one run.

我认为 Holger 已经很好地解释了这个错误以及为什么它在一次运行中没有多大意义。

Considering your goal, I think this is the solution you need to have.

考虑到您的目标,我认为这是您需要的解决方案。

 Map<Integer, Map<String, List<Student>>> grouping = students.stream().collect(Collectors.groupingBy(Student::getMarks,
                Collectors.groupingBy(Student::getName)));

This would simply give you a student list first grouped by marks, then by name. :))

这只会给你一个学生名单,首先按分数分组,然后按姓名分组。:))