0
Set<String> premiumStrings = new HashSet<>();
Set<String> sortedSet = new TreeSet<>(Comparator.comparing(premiumStrings::contains).thenComparing(Comparator.naturalOrder()));

This doesn't work, because premiumStrings::contains can take any object and not just strings. One can replace it with (String s) -> premiumStrings.contains(s), but is there a way to restrict the parameter type while still using a method reference lambda?

(Specifically, the problem is The method thenComparing(Comparator<? super Object>) in the type Comparator<Object> is not applicable for the arguments (Comparator<Comparable<? super Comparable<? super T>>>).)

H.v.M.
  • 1,348
  • 3
  • 16
  • 42
  • 3
    Does this answer your question? https://stackoverflow.com/questions/24436871/very-confused-by-java-8-comparator-type-inference – Sweeper Jun 15 '22 at 15:29

2 Answers2

1

Help the compiler a bit with types:

Set<String> sortedSet = new TreeSet<>(
                Comparator.<String, Boolean>comparing(premiumStrings::contains).thenComparing(Comparator.naturalOrder()));
cyberbrain
  • 3,433
  • 1
  • 12
  • 22
  • If you change `o -> ...` to `premiumStrings::contains` then that's exactly what I'm looking for. :) – H.v.M. Jun 15 '22 at 15:48
  • Updated - the previous version was a leftover from my refactorings to find out what's going on, sorry ;) – cyberbrain Jun 15 '22 at 18:52
0

The compiler should infer the types of arguments passed to each method.

And when we have a chain of methods, the context doesn't provide enough information for that. And the argument of every method reference (or lambda expression) would be treated as being of type Object and not String.

To avoid that, we can provide the type explicitly as a parameter of a lambda expression:

Set<String> premiumStrings = new HashSet<>();
    
Comparator<String> comparator = 
    Comparator.comparing((String str) -> premiumStrings.contains(str))
        .thenComparing(Comparator.naturalOrder());
        
Set<String> sortedSet = new TreeSet<>(comparator);

Or by using so-called Type Witness: Comparator.<String>comparing().thenComparing().

For more information, see.

Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46