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);
🌐
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)
🌐
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.
🌐
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.
🌐
Diffchecker
diffchecker.com
Compare text and find differences online or offline - Diffchecker
Compare text, files, and code (e.g. json, xml) to find differences with Diffchecker online for free! Use our desktop app for private, offline diffs.
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › api › system.string.compare
String.Compare Method (System) | Microsoft Learn
Compares substrings of two specified String objects using the specified rules, and returns an integer that indicates their relative position in the sort order. public: static int Compare(System::String ^ strA, int indexA, System::String ^ strB, ...