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 doing:
Person result = findMax(people, person -> person.getAge());
Or:
Person result = findMax(people, person -> person.getName());
This works as long as the property of Person is a Comparable, which applies for Integer and String in this case. However, this schema generates Warnings, which is a smell for bad code:
Comparable is a raw type. References to generic type Comparable should be parameterized
However, I cannot fix the Comparator to anything, as it depends on the Function I am passing as a parameter...
I tried modifying the method like this:
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 that function with JUnit and Hamcrest:
This line compiles (with the old JUnit Assert pattern):
assertEquals(silvester, findMax(input, person -> person.getName()));
However, this one does not compile (Type mismatch: cannot convert from Integer to Comparable>):
assertThat(findMax(input, person -> person.getAge()), equalTo(arnold));
But, if I extract the first parameter of the assertion, it builds well:
Person result = findMax(input, person -> person.getAge());
assertThat(result, equalTo(arnold));
This notation also builds well:
assertThat(findMax(input, Person::getAge), equalTo(arnold));
Is this a bug in Hamcrest, Java8 or Eclipse? Or am I missing something?