2016-10-21 3 views
7

Ich habe eine Gruppe von Studenten. Zuerst möchte ich sie nach den Markierungen gruppieren. Dann möchte ich diese Sets weiter in gleichnamige Studenten zusammen gruppieren.Der statische Kontext kann nicht auf nicht-statische Collectors zugreifen

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

Ich erhalte eine Fehlermeldung, dass,

Nicht statische Methode kann nicht von einem statischen Kontext verwiesen werden.

Ja. Ich bin mir ziemlich bewusst, dass ich eine nicht-statische Methode nicht ohne eine Instanz beziehen kann. Aber bei all diesen Stream-Operationen bin ich etwas verwirrt, was wirklich schiefgelaufen ist.

Anstatt, wie das zu beheben; Ich möchte wirklich wissen, was hier vor sich geht. Irgendwelche Ihrer Eingaben werden geschätzt!

Denn wenn ich schreibe, ist die unten stehende Gruppierung vollständig gültig;

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

Hier ist meine Student.java Klasse (Im Fall, wenn Sie es brauchen)

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

was versuchst du zu speichern? > ?? Ich meine, was ist das String-Objekt, das Sie in List speichern ?? Liste des Namens des Kursteilnehmers ?? –

+0

@SupunWijerathne Eigentlich war es meine Absicht, 'Student's in dieser innersten' List' zu speichern. –

+0

So sollte es eine Liste sein. nicht wahr? :)) –

Antwort

19

Leider ist die Fehlermeldung „Nicht-statische Methode kann nicht von einem statischen Kontext verwiesen werden . "Ist nur ein Platzhalter für jedes Typenkonfliktproblem, wenn Methodenreferenzen beteiligt sind. Der Compiler konnte das tatsächliche Problem einfach nicht ermitteln.

In Ihrem Code stimmt der Zieltyp Map<Integer, Map<String, List<String>>> nicht mit dem Ergebnistyp des kombinierten Kollektors überein, der Map<Integer, List<String>> ist, aber der Compiler hat nicht versucht, diesen (eigenständigen) Ergebnistyp zu ermitteln, da der (verschachtelte) Generische Methodenaufrufe, die Methodenreferenzen enthalten, erfordern den Zieltyp zum Auflösen der Methodenreferenzen. Es wird also kein Typenkonflikt der Zuweisung gemeldet, sondern ein Problem bei der Auflösung der Methodenreferenzen.

Der richtige Code einfach ist

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

Ich habe nicht verstanden, was Sie mit * Ergebnis Typ des kombinierten Kollektor * gemeint haben. Was ist das? –

+1

Der kombinierte Collector ist 'groupingBy (Student :: getMarks, Zuordnung (Student :: getName, toList()))', die einen Ergebnistyp haben würde, wenn wir es als eigenständigen Ausdruck behandeln (wie alle Ausdrücke vor Java) 8).Wenn die Regeln so waren, meldete der Compiler eine einfache 'Map >' kann nicht zugewiesen werden zu 'Map >>' Fehlermeldung. – Holger

+1

Leider sind die Java 8 Regeln nicht mehr so ​​einfach. Bei sogenannten "Poly-Ausdrücken" bestimmt der Zieltyp den Ergebnistyp, so dass Sie "gruppieren" als "Map >" ohne Fehler deklarieren könnten. Dies würde die Funktionstypen der Verfahrensreferenzen nachrüsten, z. 'Student :: getMarks' wäre' Function 'und' Student :: getName' wäre dann 'Function '. Die seltsame Fehlermeldung stammt von dem Versuch, geeignete Methoden für Ihren falschen Zieltyp zu finden. – Holger

1

Ich denke, Holger eine gute Erklärung über den Fehler gegeben hat und warum es nicht viel Sinn in einem Durchlauf machen.

In Anbetracht Ihres Ziels, denke ich, dass dies die Lösung ist, die Sie haben müssen.

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

Dies würde Ihnen einfach eine Schülerliste zuerst nach Marken, dann nach Namen gruppiert. :))

Verwandte Themen