Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static context cannot access non-static in Collectors

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
}
like image 631
Jude Niroshan Avatar asked Oct 21 '16 09:10

Jude Niroshan


People also ask

Can static context access non static content?

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.

Can we access non static variable in static method?

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.

What does non static variable Cannot be referenced from a static context?

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.

Why we Cannot use this in static context?

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.


2 Answers

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())));
like image 178
Holger Avatar answered Oct 02 '22 15:10

Holger


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. :))

like image 4
Supun Wijerathne Avatar answered Oct 02 '22 14:10

Supun Wijerathne