The problem is, that Java can not deduce the generic types for some complex expressions. The first statement works, whereas the second statement leads to a compile-time error:

Comparator<String> comparator = Comparator.comparing(String::toLowerCase);
Comparator<String> comparator = Comparator.comparing(String::toLowerCase).reversed();

There are several ways to solve the problem. Here are three of them:

Store the intermediate Comparator in a variable:

Comparator<String> comparator = Comparator.comparing(String::toLowerCase);
System.out.println(
            Arrays.stream(stringsArray)
            .sorted(comparator.reversed())
            .collect(Collectors.toList()));

Use String.CASE_INSENSITIVE_ORDER:

System.out.println(
            Arrays.stream(stringsArray)
            .sorted(String.CASE_INSENSITIVE_ORDER.reversed())
            .collect(Collectors.toList()));

Add explicit type parameters:

System.out.println(
            Arrays.stream(stringsArray)
            .sorted(Comparator.<String,String>comparing(String::toLowerCase).reversed())
            .collect(Collectors.toList()));
Answer from nosid on Stack Overflow
🌐
Baeldung
baeldung.com › home › java › guide to java comparator.comparing()
Guide to Java Comparator.comparing() | Baeldung
January 8, 2024 - For the examples in this tutorial, let’s create an Employee bean and use its fields for comparing and sorting purposes: public class Employee { String name; int age; double salary; long mobile; // constructors, getters & setters }
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › Comparator.html
Comparator (Java Platform SE 8 )
October 20, 2025 - Comparator<String> cmp = Comparator.comparingInt(String::length) .thenComparing(String.CASE_INSENSITIVE_ORDER);
🌐
Medium
medium.com › @AlexanderObregon › javas-comparator-comparing-method-explained-342361288af6
Java’s Comparator.comparing() Method Explained | Medium
October 2, 2024 - To illustrate the power of Comparator.comparing(), we’ll work with a Product class that has three main attributes: a product name, price, and a manufacture date. Here’s how the class is structured: import java.time.LocalDate; public class Product { private String name; private double price; private LocalDate manufactureDate; public Product(String name, double price, LocalDate manufactureDate) { this.name = name; this.price = price; this.manufactureDate = manufactureDate; } public String getName() { return name; } public double getPrice() { return price; } public LocalDate getManufactureDate() { return manufactureDate; } @Override public String toString() { return "Product{name='" + name + "', price=" + price + ", manufactureDate=" + manufactureDate + '}'; } }
🌐
W3Schools
w3schools.com › java › ref_string_compareto.asp
Java String compareTo() Method
A value less than 0 is returned if the string is less than the other string (less characters) and a value greater than 0 if the string is greater than the other string (more characters).
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › util › Comparator.html
Comparator (Java SE 17 & JDK 17)
January 20, 2026 - Comparator<String> cmp = Comparator.comparingInt(String::length) .thenComparing(String.CASE_INSENSITIVE_ORDER);
🌐
Reddit
reddit.com › r/learnjava › can't understand comparator.comparing(....)
r/learnjava on Reddit: Can't understand Comparator.comparing(....)
December 9, 2020 -

(The answer to the question is at the end of this post)

Hey guys,

so here's a quote block on the method from the API:

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

Accepts a function that extracts a Comparable sort key from a type T, and returns a Comparator<T> that compares by that sort key.

The returned comparator is serializable if the specified function is also serializable.

API Note: For example, to obtain a Comparator that compares Person objects by their last name,

Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);

To verify what the API said: I created a simple Person class

class Person
{

private String lastName;
public Person(String lastName)
{
  this.lastName=lastName;
}

public String getLastName()
{
 return lastName;
}

}

Then as expected this works:

Comparator<Person> byLastName = Comparator.comparing(Person::getLastName);

---------------------------------------

Q1: But this doesn't work: Comparator<Person> byLastName = Comparator.comparing(person->person.getLastName()); Eclipse doesn't even pick up the method getLastTime(), only Object's methods are present.

Q2: Then I also wondered why does the method done up by the API work? As seen by the method signature <T,U extends Comparable<? super U>>, T is input parameter thus refers to Person type and U is the output parameter thus refers to String type.

However, Person is not a subtype of Comparable<? super String>. Hence, the one in the API shouldn't work too.

My guess:My understanding of the Function<? super T,? extends U> keyExtractor is probably wrong.

-------------------------------------

Anyhow, can some kind soul help out?

Edit:Spelling error

Edit 2: Big thanks to u/knoam (sort of a TLDR for the thread)Answer for Q1: Eclipse is buggy i guess, NetBeans works.Answer for Q2: <T,U extends Comparable <? super U> > made me think that both T and U should be subtypes of Comparable. It's only U.

Find elsewhere
🌐
Readthedocs
java8tips.readthedocs.io › en › stable › comparator.html
7. Comparator — Java 8 tips 1.0 documentation
To compare two elements of type T, it first applies the key extracting function to both the elements and then performs the sorting operation on the resulted keys. // Sorting words based on word lengths Function<String, Integer> keyExtractor = str -> str.length(); Stream.of("grapes", "milk", "pineapple", "water-melon") .sorted(Comparator.comparing(keyExtractor)) .forEach(System.out::println);
🌐
Oracle
docs.oracle.com › javase › 10 › docs › api › java › util › Comparator.html
Comparator (Java SE 10 & JDK 10 )
Comparator<String> cmp = Comparator.comparingInt(String::length) .thenComparing(String.CASE_INSENSITIVE_ORDER);
🌐
Java67
java67.com › 2016 › 10 › how-to-compare-string-by-their-length-in-java8.html
How to Compare and Sort String by their length in Java? Example | Java67
Don't worry, It's easy to compare multiple String by their length, all you need to do is write a Comparator implementation which calculates their length using the length() method and compares them.
🌐
Coderanch
coderanch.com › t › 661751 › java › Sorting-Strings-comparator
Sorting Strings with comparator (Java in General forum at Coderanch)
I prefer to never use subtraction for comparison unless I am 100% sure that overflow will not occur. That's most likely the cause for string lengths (since both are positive), but still... An example where it can go wrong is comparing Integer.MIN_VALUE with Integer.MAX_VALUE.
🌐
Blogger
javarevisited.blogspot.com › 2021 › 09 › comparator-comparing-thenComparing-example-java-.html
Java 8 Comparator comparing() and thenComparing() Example - Tutorial
These methods accept a key extractor function and return a Comparator that can compare to that key. The key must be Comparable though like String, Integer, or any Java class which implements java.lang.Comparable interface, I mean the key must implement Comparable interface.
🌐
Readthedocs
java-8-tips.readthedocs.io › en › stable › comparator.html
7. Comparator — Java 8 tips 1.0 documentation
To compare two elements of type T, it first applies the key extracting function to both the elements and then performs the sorting operation on the resulted keys. // Sorting words based on word lengths Function<String, Integer> keyExtractor = str -> str.length(); Stream.of("grapes", "milk", "pineapple", "water-melon") .sorted(Comparator.comparing(keyExtractor)) .forEach(System.out::println);
🌐
Sentry
sentry.io › sentry answers › java › how to compare strings in java
How to compare strings in Java | Sentry
If you want to find out if a String is “bigger” or “smaller” than another string (that is, whether it comes before or after alphabetically), use String.compareTo().
🌐
Baeldung
baeldung.com › home › java › java string › comparing strings in java
Comparing Strings in Java | Baeldung
June 19, 2024 - The method returns true if two Strings are equal by first comparing them using their address i.e “==”. Consequently, if both arguments are null, it returns true and if exactly one argument is null, it returns false.
🌐
HappyCoders.eu
happycoders.eu › java › comparator-comparable-compareto
compareTo, Comparable, Comparator - Comparing Objects in Java
June 12, 2025 - private static final StringLengthComparator STRING_LENGTH_COMPARATOR = new StringLengthComparator();Code language: Java (java)
🌐
Text Compare
text-compare.com
Text Compare! - Find differences between two text files
Text Compare! is an online diff tool that can find the difference between two text documents. Just paste and compare.
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-comparator-interface
Java Comparator Interface - GeeksforGeeks
The compare() method compares two elements and returns: -1 -> if the first element should come before the second ... import java.util.*; // Define the Student class class Student{ String name; Integer age; Student(String name, Integer age) { ...
Published   April 20, 2016