Reputation: 1693
I have a list of Students which I want to convert into a Map<String, Integer>
, where the map key should be the first name of the student. To keep the code sample simple, I specified the map value as 1
:
final Map<String, Integer> map = someStudents.stream().collect(
Collectors.toMap(Student::getFirstName, 1));
The compiler complains about:
non-static method getFirstName() cannot be referenced from a static context
Any idea? I am confused because many examples use the same approach of passing a reference to the non-static method. Why does the compiler see a static context here?
Upvotes: 12
Views: 16476
Reputation: 10560
The issue here is that first of all, this message is very misleading and that seems to be a java bug. Second, you are providing an int value in place of a function reference. Correct is this:
final Map<String, Integer> map = someStudents.stream().collect(
Collectors.toMap(Student::getFirstName, val -> 1));
Here val -> 1
is a function which for any val
will always return 1.
Another situation where you would get the same error would be this:
final Map<String, Integer> map = someStudents.stream().collect(
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
If someStudents
is of type Map<String, String>
but map is Map<String, Integer>
you would get the same:
non-static method Map.Entry::getValue cannot be referenced from a static context
Upvotes: 1
Reputation: 8086
Firstly, you are accessing getFirstName
using a class name -Student
(as if its a static memeber) rather than using object reference. Java tutorial - Method Refrences.
Secondly, second parameter of toMap
method must be a Function
type.
So, the correct statement is:
someStudents.stream().collect( Collectors.toMap( student -> student.getFirstName(), student -> 1 ) );
Edit:
Or, it can also be as posted by @Aomine. Both answers are correct. For more info, refer to comments on @Aomine's answers.
Edit 2:
Though, @Aomine's and this answer give expected result, note difference in first parameter.
Upvotes: 4
Reputation: 56469
The value mapper should be a function, i.e.:
.collect(Collectors.toMap(Student::getFirstName, s -> 1));
The function s -> 1
essentially takes a student as input and returns 1
in this specific case for the map values.
The below code is not valid as the literal value 1
is not a function.
.collect(Collectors.toMap(Student::getFirstName, 1));
Upvotes: 4