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

时间:2016-10-21 09:07:26

标签: java-8 java-stream method-reference collect

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

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

我收到一条错误说,

  

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

是。我非常清楚,如果没有实例,我就无法引用非静态方法。但是对于所有这些流操作,我真的很困惑。

而不是如何解决这个问题;我真的很想知道这里发生了什么。您的任何投入都表示赞赏!

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

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

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

public class Student {

    private String name;
    private int marks;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMarks() {
        return marks;
    }

    public void setMarks(int marks) {
        this.marks = marks;
    }

    public Student(String name, int marks) {

        this.name = name;
        this.marks = marks;
    }

    @Override
    public String toString() {
        return name + ':' + marks ;
    }
}

2 个答案:

答案 0 :(得分:45)

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

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

正确的代码就是

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

答案 1 :(得分:3)

我认为霍尔格已经对错误给出了一个很好的解释,以及为什么它在一次运行中没有多大意义。

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

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

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