1

Based on the answer: https://stackoverflow.com/a/47693998/8760211

Following Compile Error occurs, when I try to sort a list with elements of Type Student from within the class Invoker. Student is an innerclass of class University:

Type mismatch: cannot convert from ToIntFunction<University.Student> to ToIntFunction<? super T>

Code:

public class University implements Serializable {
    private List<Student> values = new ArrayList<Student>();

    public static final class Student implements Serializable {
        private int id;
        private String name;
        private String location;
        private Date date;

        Student(int id, String name, String location, Date date) {
            this.id = id;
            this.name = name;
            this.location = location;
            this.date = date;
        }

        // Problem occurs even with getters!!
}


public class Invoker implements Serializable {
    public static void main(String[] args) {
        List<University.Student> students = new ArrayList<>();

        Map<String, Integer> locationOrder = students.stream().collect(HashMap::new,
                (m, s) -> m.putIfAbsent(s.getName(), m.size()),
                (m1, m2) -> m2.keySet().forEach(l -> m1.putIfAbsent(l, m1.size())));

        students.sort(Comparator.comparingInt((University.Student s) -> locationOrder.get(s.name)).thenComparing(s -> s.id));        
    }
}

The following code snippet is marked in IDE as cause of the Compiler error: comparingInt((University.Student s) -> locationOrder.get(s.name)

If I move the innerclass into the class Invoker everything works fine!!

Any help would be much appreciated. Thanks in advance.

ThomasMuller
  • 279
  • 1
  • 3
  • 12

2 Answers2

2

This is a strange error to get, but the reason is just that s.name is not accessible in the Invoker: it's private. Neither is s.id. So you should add getter methods to Student like

public String getName() {
    return name;
}

and use them instead. Enclosing classes can access the inner classes' private members which is why it works if moved to Invoker.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Hi Alexey, Many thanks for your reply. I have the getters in the class Student. But even with those getters I get the compiler error!! It's really very strange. – ThomasMuller Dec 09 '17 at 11:05
  • I tested by copying your code, making classes non-public (so they can all go in one file) and adding the getters, and it works: https://ideone.com/cQz7R5. Please double-check that your code is as in the question (different code would explain the error much better). – Alexey Romanov Dec 09 '17 at 12:28
  • Hi Alexey, thanks for your reply. Yes, if all classes are in one file it works! But I have to seperated the classes in different files and so then I get the described error!! – ThomasMuller Dec 11 '17 at 09:28
  • Then something really weird is going on. How exactly are you compiling and running the code? – Alexey Romanov Dec 11 '17 at 10:12
  • Hi Alexey, I'm using eclipse with JDK 1.8. I will try it today with another IDE and then give you feedback. – ThomasMuller Dec 11 '17 at 10:30
  • Thanks so much, using getName() everywhere solves this problem: `students.sort(Comparator.comparingInt((University.Student s) -> locationOrder.get(s.>>>>getName()<<<<)).thenComparing(s -> s.id));` – ThomasMuller Dec 19 '17 at 16:21
1

Try changing it to this

students.sort(Comparator.<University.Student>comparingInt(s -> locationOrder.get(s.name)).thenComparing(s -> s.id));        
Leo Aso
  • 11,898
  • 3
  • 25
  • 46