2016-10-21 13 views
7

У меня есть группа студентов. Сначала я хочу сгруппировать их по меткам. Затем я хочу вместе сгруппировать эти группы в одно и то же имя вместе.Статический контекст не может получить доступ к нестационарным в коллекторах

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

Я получаю сообщение об ошибке сказав,

Non-статический метод не может refered от быть в статическом контексте.

Да. Я в значительной степени понимаю, что я не могу ссылаться на нестатический метод без экземпляра. Но со всеми этими потоковыми операциями я немного смущен тем, что пошло не так.

Вместо того, чтобы исправить это; Я действительно хочу знать, что здесь происходит. Любой из ваших входов оценен!

Потому что, если я пишу, приведенная ниже группировка полностью действительна;

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 ; 
    } 
} 
+0

что вы пытаетесь сохранить внутри Карта > ?? Я имею в виду, что такое объект String, который вы собираетесь хранить внутри списка ?? Список имени студента ??? –

+0

@SupunWijerathne На самом деле, мое намерение состояло в том, чтобы хранить 'Студентов' в этом самом внутреннем« Листе ». –

+0

Так что это должен быть список . не так ли? :)) –

ответ

19

К сожалению, сообщение об ошибке «Non-статический метод может не было ссылаться из статического контекста . »Является просто владельцем места для проблемы несоответствия любого типа, когда задействованы ссылки на методы. Компилятор просто не смог определить фактическую проблему.

В вашем коде целевой тип Map<Integer, Map<String, List<String>>> не соответствует типу результата объединенного коллектора, который равен Map<Integer, List<String>>, но компилятор не попытался определить этот (автономный) тип результата, поскольку (вложенный) Общие вызовы методов, включающие ссылки на методы, требуют целевого типа для разрешения ссылок на методы. Таким образом, он не сообщает о несоответствии типа присваивания, но проблема с решением ссылок на метод.

Правильный код просто

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

Я не понял, что вы подразумевали под * результатом типа комбинированного коллектора *. Что это? –

+1

Комбинированный сборщик - 'groupingBy (Student :: getMarks, mapping (Student :: getName, toList())), который будет иметь тип результата, если рассматривать его как автономное выражение (как и все выражения перед Java 8).Если бы правила были такими, компилятор сообщал о простом 'Map >' не может быть присвоен 'Map >>' сообщение об ошибке. – Holger

+1

К сожалению, правила Java 8 не так просты. Для так называемых «poly-выражений» целевой тип определяет тип результата, поэтому вы можете объявлять «группировать» как «Map >» без каких-либо ошибок. Это позволило бы модифицировать типы функций ссылок на методы, например. 'Student :: getMarks' будет' Function 'и' Student :: getName' будет тогда 'Function '. Странное сообщение об ошибке связано с попыткой найти подходящие методы для вашего неправильного целевого типа. – Holger

1

Я думаю, что Хольгер дал хорошее объяснение об ошибке, и почему это не имеет особого смысла в один проход.

Учитывая вашу цель, я думаю, что это решение, которое вам нужно иметь.

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

Это просто даст вам список студентов, сначала сгруппированных по маркам, а затем по имени. :))