How to determine method signature when passing a function in Java - JUNIT with Hamcrest error

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?

+6
source share
1 answer

Make sure your project structure (for intellij IDE) is set to lambda expression. File> project structure> drop-down menu for how advanced the syntax can be.

0
source

Source: https://habr.com/ru/post/983421/


All Articles