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)
public class Student {
private String name;
private int marks;
// getters, setters, constructor and toString
}
Of course, they can, but the opposite is not true, i.e. you cannot obtain a non-static member from a static context, i.e. static method. The only way to access a non-static variable from a static method is by creating an object of the class the variable belongs to.
Yes, a static method can access a non-static variable. This is done by creating an object to the class and accessing the variable through the object.
Non-static Variable X Cannot be Referenced from a Static Context & Non-static Method X Cannot be Referenced from a Static Context. A static variable is initialized once, when its class is loaded into memory, and its value is shared among all instances of that class.
But static contexts(methods and blocks) doesn't have any instance they belong to the class. In a simple sense, to use “this” the method should be invoked by an object, which is not always necessary with static methods. Therefore, you cannot use this keyword from a static method.
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.
The correct code simply is
Map<Integer, List<String>> groupping = students.stream()
.collect(Collectors.groupingBy(Student::getMarks,
Collectors.mapping(Student::getName, Collectors.toList())));
I think Holger has given a good explanation about the error and why it doesn't make much sense in one run.
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. :))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With