6

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?

Martin
  • 3,018
  • 1
  • 26
  • 45
  • 1
    What is the warning? – Martijn Burger Mar 06 '15 at 11:57
  • Comparable is a raw type. References to generic type Comparable should be parameterized. I edited the question to be more specific, however the code can directly be pasted in a java8 IDE. – Martin Mar 06 '15 at 11:59
  • I get no warning at all with both versions – Javi Mollá Mar 06 '15 at 12:23
  • @JavierMollá, what IDE are you using? I get the warning with Eclipse Luna... – Martin Mar 06 '15 at 12:31
  • I'm also on Eclipse Luna, Java 8, Mac OS 10.10.2 – Javi Mollá Mar 06 '15 at 12:34
  • Strange, I am on Windows 8, obviously Java 8 is present... :) I'm updating Eclipse, will see if that makes it better. It's just strange as the code seems to be OK, and you are kind of confirming it... Java is 8u31, I'm downloading 8u40 to see if that makes any difference... – Martin Mar 06 '15 at 12:36
  • I have updated to newest Luna version and to Java 8u40, problem still present. I just don't get it... Any thoughts? – Martin Mar 06 '15 at 12:50
  • I just rewrote the question as I was able to further isolate the issue. However, the behaviour it is causing right now is not what I am expecting... – Martin Mar 06 '15 at 19:50
  • Do you get this problem using just javac? It is worth verifying whether the problem is just in eclipse's built-in compiler. – bacar Mar 07 '15 at 09:48
  • Well, haven't tested just with javac. Yesterday I had a similar problem when passing a Type with generics to a Mockito method. Parameters looked OK, but compiling failed in Maven and Idea, but worked in Eclipse... We had to use a similar workaround (expressing in an equivalent way) to get it working. – Martin Mar 11 '15 at 10:20

1 Answers1

0

Ensure your project structure (For intellij's IDE) is set to allow lambda expressions. File > project structure > drop down menu for how advanced the syntax can be.

Jahhein
  • 140
  • 11