is Comparator.comparing() used for converting a single argument lambda expression to a double argument?

Yes, you can sort of think of it like that.

When sorting things, you are supposed to specify "given two things a and b, which of them is greater, or are they equal?" using a Comparator<T>. The a and b is why it has 2 lambda parameters, and you return an integer indicating your answer to that question.

However, a much more convenient way to do this is to specify "given a thing x, what part of x do you want to sort by?". And that is what you can do with the keyExtractor argument of Comparator.comparing.

Compare:

/*
given two people, a and b, the comparison result between a and b is the 
comparison result between a's name and b's name
*/
Comparator<Person> personNameComparator = 
    (a, b) -> a.getName().compareTo(b.getName());

/*
given a person x, compare their name
*/
Comparator<Person> personNameComparator = 
    Comparator.comparing(x -> x.getName()); // or Person::getName

The latter is clearly much more concise and intuitive. We tend to think about what things to sort by, rather than how exactly to compare two things, and the exact number to return depending on the comparison result.

As for the declaration for comparing:

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

The <T, U extends Comparable<? super U>> part first declares two generic type parameters - T is what the comparator compares (Person in the above case), and U is the type that you are actually comparing (String in the above case), hence it extends Comparable.

keyExtractor is the parameter you pass in, such as x -> x.getName(), that should answer the question of "when given a T, what is a U that you want to compare by?".

If you are confused by the ? super and ? extends, read What is PECS?.

If you haven't realised already, the implementation of comparing basically boils down to:

return (a, b) -> keyExtractor.apply(a).compareTo(keyExtractor.apply(b));
Answer from Sweeper on Stack Overflow
Top answer
1 of 4
14

is Comparator.comparing() used for converting a single argument lambda expression to a double argument?

Yes, you can sort of think of it like that.

When sorting things, you are supposed to specify "given two things a and b, which of them is greater, or are they equal?" using a Comparator<T>. The a and b is why it has 2 lambda parameters, and you return an integer indicating your answer to that question.

However, a much more convenient way to do this is to specify "given a thing x, what part of x do you want to sort by?". And that is what you can do with the keyExtractor argument of Comparator.comparing.

Compare:

/*
given two people, a and b, the comparison result between a and b is the 
comparison result between a's name and b's name
*/
Comparator<Person> personNameComparator = 
    (a, b) -> a.getName().compareTo(b.getName());

/*
given a person x, compare their name
*/
Comparator<Person> personNameComparator = 
    Comparator.comparing(x -> x.getName()); // or Person::getName

The latter is clearly much more concise and intuitive. We tend to think about what things to sort by, rather than how exactly to compare two things, and the exact number to return depending on the comparison result.

As for the declaration for comparing:

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

The <T, U extends Comparable<? super U>> part first declares two generic type parameters - T is what the comparator compares (Person in the above case), and U is the type that you are actually comparing (String in the above case), hence it extends Comparable.

keyExtractor is the parameter you pass in, such as x -> x.getName(), that should answer the question of "when given a T, what is a U that you want to compare by?".

If you are confused by the ? super and ? extends, read What is PECS?.

If you haven't realised already, the implementation of comparing basically boils down to:

return (a, b) -> keyExtractor.apply(a).compareTo(keyExtractor.apply(b));
2 of 4
7

Comparator#compare(T o1, T o2) Compare two objects and returns an integer value based on this criteria:

  • A negative value if o1 < o2
  • A positive value if o1 > o2
  • Zero if they are equal.

Comparator.comparing(Function<? super T, ? extends U> key) returns a Comparator<T> that compares by that sort key.

The main difference is that compare method provides a single point of comparison, whereas comparing chained to other functions to provide multiple points of comparison.

Suppose you have a class Person

public class Person implements Comparable<Person> {
    private String firstName;
    private String lastName;
    private int age;
    // rest of class omitted
}

if you compare two Person instances p1 vs p2 using compare(p1, p2), the comparison will be executed and the two objects will be sorted based on some natural ordering prescribed by the class. In contrast, if you want to compare the same two instances using comparing(), the comparison will be executed based on whichever criteria you choose to compare based on some attribute of the class. For example: Comparator.comparing(Person::getFirstName).

Because comparing returns a Comparator rather than a value, as I stated before, you can chain multiple comparisons. For instance: Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName);

As for the meaning of the return type <T, U extends Comparable<? super U>> Comparator<T>, you can find the explanation here.

I want to add that, classes must be comparable in order for compare(T o1, T o2) to work. String objects are comparable because they implement this interface. That said, if a class is not Comparable, you can still use comparing method because as I stated, you get to choose which attribute of the class you would like to use for the comparison and those attributes are likely to be comparable (i.e. String in the case of person's name or age in the above example).

🌐
Blogger
javarevisited.blogspot.com › 2021 › 09 › comparator-comparing-thenComparing-example-java-.html
Java 8 Comparator comparing() and thenComparing ...
May 24, 2023 - 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.
🌐
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.

🌐
Medium
medium.com › @AlexanderObregon › javas-comparator-comparing-method-explained-342361288af6
Java’s Comparator.comparing() Method Explained | Medium
October 2, 2024 - Java’s Comparator.comparing() method is a powerful tool that simplifies custom sorting based on object properties. By allowing us to create comparators for sorting collections like lists, this method reduces the complexity of implementing ...
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › Comparator.html
Comparator (Java Platform SE 8 )
October 20, 2025 - Unlike Comparable, a comparator may optionally permit comparison of null arguments, while maintaining the requirements for an equivalence relation. This interface is a member of the Java Collections Framework.
🌐
Baeldung
baeldung.com › home › java › guide to java comparator.comparing()
Guide to Java Comparator.comparing() | Baeldung
January 8, 2024 - This article is a guide to several features introduced in Java 8 for the Comparator interface.
🌐
DigitalOcean
digitalocean.com › community › tutorials › comparable-and-comparator-in-java-example
Comparable and Comparator in Java Example | DigitalOcean
August 3, 2022 - Comparator interface compare(Object ... in such a way that it returns negative int if the first argument is less than the second one and returns zero if they are equal and positive int if the first argument is greater than the second one....
🌐
DZone
dzone.com › coding › java › java 8 comparator: how to sort a list
Java 8 Comparator: How to Sort a List
May 20, 2019 - Let’s suppose we have our Movie class and we want to sort our List by title. We can use Comparator.comparing() and pass a function that extracts the field to use for sorting – title, in this example.
Find elsewhere
🌐
Readthedocs
java-8-tips.readthedocs.io › en › stable › comparator.html
7. Comparator — Java 8 tips 1.0 documentation
Comparator contains two methods nullsFirst and nullsLast that takes a comparator as an argument and returns another null-friendly comparator by wrapping the given comparator. It will arrange null elements at the begining or end depending on the operation you called. For non-null elements it will sort them using the comparator passed initially.
🌐
Jenkov
jenkov.com › tutorials › java-collections › comparator.html
Java Comparator
October 4, 2020 - The Java Comparator interface, java.util.Comparator, represents a component that can compare two objects so they can be sorted using sorting functionality in Java. When sorting e.g a Java List you can pass a Java Comparator to the sorting method.
🌐
GeeksforGeeks
geeksforgeeks.org › java › java-comparator-interface
Java Comparator Interface - GeeksforGeeks
Student class includes name and age with getter methods. StudentComparator compares by name first, then by age if names are same. Collections.sort() uses this comparator to order students. Final list shows sorted order by both name and age fields. Java 8 introduced a more simple way to write ...
Published   1 month ago
🌐
freeCodeCamp
freecodecamp.org › news › comparable-vs-comparator-explained-in-java
Comparable vs Comparator Interfaces in Java – Which Should You Use and When?
July 23, 2024 - The Comparator interface in Java provides a way to define multiple ways of comparing and sorting objects. Unlike the Comparable interface, which allows only a single natural ordering, Comparator is designed to offer flexibility by allowing multiple ...
🌐
Medium
medium.com › @AlexanderObregon › javas-comparator-thencomparing-method-explained-988e8f926a64
Java’s Comparator.thenComparing() Explained | Medium
November 6, 2024 - thenComparing() allows you to create structured sorting logic with multiple sorting criteria, giving you control over both primary and secondary ordering. By understanding the order of criteria, managing null values, and using custom comparators, ...
🌐
GeeksforGeeks
geeksforgeeks.org › java › stream-sorted-comparator-comparator-method-java
Stream sorted (Comparator comparator) method in Java - GeeksforGeeks
December 26, 2025 - In Java, the Stream.sorted(Comparator comparator) method sorts the elements of a stream based on a provided Comparator and returns a new sorted stream.
🌐
Reddit
reddit.com › r/javahelp › when to use compareto() and compare()?
r/javahelp on Reddit: When to use compareTo() and compare()?
January 14, 2024 -

As far as I know, both are used when it isn't enoguh to compare if it's equal or not, but if it's mor or less than the other one.

But when do you use compareTo() from Comparable over compare() from Comparator? Like, for binary tree you use compare when you add the elements? but for Arrays.sort() you use compareTo(), but why? Like, what's really the difference? From what i've searched up, both compare in the same way but i might be wrong?

Top answer
1 of 2
5
An object implementing Comparator is an object that compares two objects. An object implementing Comparable is an object that can be compared to another object. Any Comparable type can be turned into a Comparator object by using a method reference, e.g. (Comparator) String::compareTo. Objects typically implement Comparable when there's some obvious way that they can be compared and sorted. You typically create Comparators when a type either: is not Comparable; or, does implement Comparable but the existing compareTo() method does not provide the ordering or comparison semantics you desire.
2 of 2
1
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
🌐
Coderanch
coderanch.com › t › 781949 › java › Comparator-lambda
Comparator with lambda (Features new in Java 8 forum at Coderanch)
May 30, 2024 - So, we get: and so 5 is considered to be less than 4, and , and so 4 is considered to be bigger than 5. will do the necessary comparisons in the way described, and so the result is List(5, 4), because as said, 5 is less than 4 according to c. There are three kinds of actuaries: those who can count, and those who can't. ... And welcome to the Ranch! There are three kinds of actuaries: those who can count, and those who can't. ... JavaRanch-FAQ HowToAskQuestionsOnJavaRanch UseCodeTags DontWriteLongLines ItDoesntWorkIsUseLess FormatCode JavaIndenter SSCCE API-17 JLS JavaLanguageSpecification MainIsAPain KeyboardUtility
🌐
Coderanch
coderanch.com › t › 639044 › java › Comparator-comparing-method
Comparator.comparing() method. (Features new in Java 8 forum at Coderanch)
September 4, 2014 - The println() prints: java.util.Comparator$$Lambda$2/1555009629@8efb846 and the sorting works correctly. You can't live with women. You can't live without women. Fuzzy Logic Example. ... I thought it lookedfamiliar. The answer to whether that method returns a Comparator is in the printout; you have got the class name before the @ sign (obviously that class doesn't override Object#toString), and you can check the details in the documentation.
🌐
GeeksforGeeks
geeksforgeeks.org › java › comparator-comparingdouble-method-in-java-with-examples
Comparator comparingDouble() method in Java with examples - GeeksforGeeks
July 11, 2025 - The comparingDouble(java.util.function.ToDoubleFunction) method of Comparator Interface in Java accepts a function as parameter that extracts an double sort key from a type T, and returns a Comparator that compares by that sort key.The returned ...