I have the following function:
private Person findMax(List<Person> persons, Function<Person, ? extends Comparable> compare) { return persons.stream().max(Comparator.comparing(compare)).get(); }
I can call it:
Person result = findMax(people, person -> person.getAge());
Or:
Person result = findMax(people, person -> person.getName());
This works as long as the Person property is Comparable, which is used for Integer and String in this case. However, this circuit generates warnings that smell like bad code:
Comparable is a raw type. References to the generic type Comparable should be parameterized
However, I cannot fix Comparator in anything, since it depends on the function that I pass as a parameter ...
I tried modifying the method as follows:
private <T extends Comparable<T>> Person findMax(List<Person> persons, Function<Person, T> compare) { return persons.stream().max(Comparator.comparing(compare)).get(); }
Now when I try to test this function with JUnit and Hamcrest:
This line compiles (with the old JUnit Assert template):
assertEquals(silvester, findMax(input, person -> person.getName()));
However, this one does not compile (Type mismatch: cannot be converted from Integer to Comparable>):
assertThat(findMax(input, person -> person.getAge()), equalTo(arnold));
But, if I extract the first parameter of the statement, it builds well:
Person result = findMax(input, person -> person.getAge()); assertThat(result, equalTo(arnold));
This notation is also well built:
assertThat(findMax(input, Person::getAge), equalTo(arnold));
Is this a bug in Hamcrest, Java8 or Eclipse? Or am I missing something?