Comparator comparing java
Comparable и Comparator
Два новых интерфейса java.lang.Comparable и java.util.Comparator были добавлены в версии Java 5. Использование данных интерфейcов в своих приложениях позволяет упорядочивать (сортировать) данные.
Интерфейс Comparable
В интерфейсе Comparable объявлен только один метод compareTo (Object obj), предназначенный для упорядочивания объектов класса. Данный метод удобно использовать для сортировки списков или массивов объектов.
Метод compareTo (Object obj) сравнивает вызываемый объект с obj. В отличие от метода equals, который возвращает true или false, compareTo возвращает:
- 0, если значения равны;
- Отрицательное значение (обычно -1), если вызываемый объект меньше obj;
- Положительное значение (обычно +1), если вызываемый объект больше obj.
Если типы объектов не совместимы при сравнении, то compareTo (Object obj) может вызвать исключение ClassCastException. Необходимо помнить, что аргумент метода compareTo имеет тип сравниваемого объекта класса.
Обычные классы Byte, Short, Integer, Long, Double, Float, Character, String уже реализуют интерфейс Comparable.
Пример реализации интерфейса Comparable
Результат выполнения программы:
В примере значения сортируются сначала по полю str (по алфавиту), а затем по num в методе compareTo. Это хорошо видно по двум строкам с одинаковыми значения str и различными num. Чтобы изменить порядок сортировки значения str (в обратном порядке), необходимо внести небольшие изменения в метод compareTo.
Интерфейс Comparator : compare, compareTo
В интерфейсе Comparator объявлен метод compare (Object obj1, Object obj2), который позволяет сравнивать между собой два объекта. На выходе метод возвращает значение 0, если объекты равны, положительное значение или отрицательное значение, если объекты не тождественны.
Метод может вызвать исключение ClassCastException, если типы объектов не совместимы при сравнении. Простой пример реализации интерфейса Comparator:
Результат выполнения программы:
Усложним пример, и реализуем несколько видов сортировки. Для этого создадим класс Product с полями name, price и quantity.
Создадим два класса (SortedByName, SortedByPrice), реализующих интерфейс Comparator для сортировки объектов по названию и по цене :
Пример использования Arrays.sort :
Результат выполнения программы:
Для сортировки объектов были реализованы два независимых компаратора по наименованию и по цене (SortedByName и SortedByPrice). Сортировка выполняется с помощью класса Arrays, у которого есть метод sort. Данный метод в качестве второго аргумента принимает тип компаратора.
Можно использовать также метод sort класса Collections, который в качестве первого входного аргумента принимает список объектов:
Отличие интерфейсов Comparator и Comparable
Интерфейс Comparable используется только для сравнения объектов класса, в котором данный интерфейс реализован. Т.е. interface Comparable определяет логику сравнения объекта определенного ссылочного типа внутри своей реализации (по правилам разработчика).
Comparator представляет отдельную реализацию и ее можно использовать многократно и с различными классами. Т.е. interface Comparator позволяет создавать объекты, которые будут управлять процессом сравнения (например при сортировках).
Comparator comparingInt () в Java с примерами
Метод comparingInt ( java.util.function.ToIntFunction ) принимает функцию в качестве параметра, которая извлекает ключ сортировки int из типа T, и возвращает компаратор, который сравнивает по этому ключу сортировки. Возвращенный компаратор сериализуем, если указанная функция также сериализации.
Синтаксис:
Параметры: Этот метод принимает единственный параметр keyExtractor, который является функцией, используемой для извлечения целочисленного ключа сортировки.
Возвращаемое значение: этот метод возвращает компаратор, который сравнивает извлеченный ключ
Исключение: этот метод генерирует исключение NullPointerException, если аргумент равен нулю.
Ниже программы иллюстрируют метод comparingInt (java.util.function.ToIntFunction):
Программа 1:
// Java-программа для демонстрации
// Comparator.comparingInt (java.util.function.ToIntFunction) метод
public class GFG <
public static void main(String[] args)
// создаем несколько пользовательских объектов
User u1 = new User( «Aaman» , 25 );
User u2 = new User( «Joyita» , 22 );
User u3 = new User( «Suvam» , 28 );
User u4 = new User( «mahafuj» , 25 );
= Arrays.asList(u2, u1, u4, u3);
System.out.println( «Before Sort:» );
-> System.out.println( «User age «
-> System.out.println( «User age «
class User implements Comparable <
public String name;
public User(String name, int age)
this .name = name;
public int compareTo(User u1)
public String getName()
public void setName(String name)
this .name = name;
public int getAge()
public void setAge( int age)
public String toString()
return «User [name=» + name
Вывод, напечатанный на консоли IDE, показан ниже.
Выход:
Программа 2:
// Java-программа для демонстрации
// Comparator.comparingInt (java.util.function.ToIntFunction) метод
public class GFG <
public static void main(String[] args)
List list = Arrays.asList(
new Order( «A382y482y48» , 320 ),
new Order( «Vvekhfbkje2» , 242 ),
new Order( «efkhfbekjfbe» , 1345 ),
new Order( «bhdhdfaddvad» , 230 ),
new Order( «abkasbcjabjc» , 100 ));
System.out.println( «Before Sort:» );
System.out.println( «nAfter Sort:» );
class Order implements Comparable <
public String orderNo;
public int value;
public int compareTo(Order o1)
public Order(String orderNo, int value)
this .orderNo = orderNo;
this .value = value;
public String toString()
return «Order [orderNo=» + orderNo
public String getOrderNo()
public void setOrderNo(String orderNo)
this .orderNo = orderNo;
public int getValue()
public void setValue( int value)
this .value = value;
Вывод на консоль показан ниже.
Выход:
Comparable и Comparator
Два новых интерфейса java.lang.Comparable и java.util.Comparator были добавлены в версии Java 5. Использование данных интерфейcов в своих приложениях позволяет упорядочивать (сортировать) данные.
Интерфейс Comparable
В интерфейсе Comparable объявлен только один метод compareTo (Object obj), предназначенный для упорядочивания объектов класса. Данный метод удобно использовать для сортировки списков или массивов объектов.
Метод compareTo (Object obj) сравнивает вызываемый объект с obj. В отличие от метода equals, который возвращает true или false, compareTo возвращает:
- 0, если значения равны;
- Отрицательное значение (обычно -1), если вызываемый объект меньше obj;
- Положительное значение (обычно +1), если вызываемый объект больше obj.
Если типы объектов не совместимы при сравнении, то compareTo (Object obj) может вызвать исключение ClassCastException. Необходимо помнить, что аргумент метода compareTo имеет тип сравниваемого объекта класса.
Обычные классы Byte, Short, Integer, Long, Double, Float, Character, String уже реализуют интерфейс Comparable.
Пример реализации интерфейса Comparable
Результат выполнения программы:
В примере значения сортируются сначала по полю str (по алфавиту), а затем по num в методе compareTo. Это хорошо видно по двум строкам с одинаковыми значения str и различными num. Чтобы изменить порядок сортировки значения str (в обратном порядке), необходимо внести небольшие изменения в метод compareTo.
Интерфейс Comparator : compare, compareTo
В интерфейсе Comparator объявлен метод compare (Object obj1, Object obj2), который позволяет сравнивать между собой два объекта. На выходе метод возвращает значение 0, если объекты равны, положительное значение или отрицательное значение, если объекты не тождественны.
Метод может вызвать исключение ClassCastException, если типы объектов не совместимы при сравнении. Простой пример реализации интерфейса Comparator:
Результат выполнения программы:
Усложним пример, и реализуем несколько видов сортировки. Для этого создадим класс Product с полями name, price и quantity.
Создадим два класса (SortedByName, SortedByPrice), реализующих интерфейс Comparator для сортировки объектов по названию и по цене :
Пример использования Arrays.sort :
Результат выполнения программы:
Для сортировки объектов были реализованы два независимых компаратора по наименованию и по цене (SortedByName и SortedByPrice). Сортировка выполняется с помощью класса Arrays, у которого есть метод sort. Данный метод в качестве второго аргумента принимает тип компаратора.
Можно использовать также метод sort класса Collections, который в качестве первого входного аргумента принимает список объектов:
Отличие интерфейсов Comparator и Comparable
Интерфейс Comparable используется только для сравнения объектов класса, в котором данный интерфейс реализован. Т.е. interface Comparable определяет логику сравнения объекта определенного ссылочного типа внутри своей реализации (по правилам разработчика).
Comparator представляет отдельную реализацию и ее можно использовать многократно и с различными классами. Т.е. interface Comparator позволяет создавать объекты, которые будут управлять процессом сравнения (например при сортировках).
Java Comparable and Comparator
Java Comparable and Comparator tutorial shows how to compare objects in Java with Comparable and Comparator interfaces. Comparing two objects is essential when doing sorting.
When working with custom Java objects to perform comparisons, we can use Comparable or Comparator interfaces.
Java Comparable
The Comparable interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class’s natural ordering. The class’s compareTo() method has to be implemented to provide the natural comparison.
Java Comparator
The Comparator interface imposes a total ordering on some collection of objects. Comparators can be passed to a sort method (such as Collections.sort() or Arrays.sort() ) to allow precise control over the sort order. Comparators can also be used to control the order of certain data structures (such as sorted sets or sorted maps), or to provide an ordering for collections of objects that don’t have a natural ordering.
Comparable vs Comparator
The following two lists summarize the differences between the two interfaces.
Java Comparable
- must define o1.compareTo(o2)
- used to implement natural ordering of objects
- we must modify the class whose instances we want to sort
- it’s in the same class
- only one implementation
- implemented frequently in the API by: String, Wrapper classes, Date, Calendar
Java Comparator
- must define compare(o1, o2)
- multiple ways of comparing two instances of a type — e.g. compare people by age, name
- we can provide comparators for classes that we do not control
- we can have multiple implementations of comparators
- meant to be implemented to sort instances of third-party classes
Java built-in Comparator example
Java language offers some built-int Comparators.
In the example, we sort an array of words in ascending and descending orders.
The Comparator.naturalOrder() returns a built-in natural order Comparator .
The Comparator.reverseOrder() returns a comparator that imposes the reverse of the natural ordering.
Comparator.comparingInt
The Comparator.comparingInt() method extracts the int sort key from the provided type and compares by that key.
In the example, we compare Person objects by their age utilizing Comparator.comparingInt() method.
The objects are sorted by age.
Multiple Comparators
With Comparator.thenComparing() method, we can use multiple comparators when sorting objects.
We have a list of Person objects. We compare the objects by their name, then by their city and finally by their age.
The Comparator.thenComparing() method allows us to apply multiply comparators to the sorting operation.
This is the output.
Java custom Comparator
In the next example, we create a custom Comparator .
We have a list of words. This time we compare the words by their length.
This custom comparator is used to sort the words by their size in ascending order.
In the second case, the words are sorted in descending order.
This is the output.
Java custom Comparator II
In the following example, we create two custom comparators.
We have an array of Car objects. We create two custom comparators to compare the objects by their name and by their price.
The custom CompareByPrice comparator implements the Comparator interface; forcing us to implement the compare() method. Our implementation compares the car objects by their price.
In the second case, we are comparing car objects by their name.
This is the outplut.
Java Comparable example
In the following example, we compare objects with Comparable .
We have a list of Card objects. Each card has a value and belongs to a suit. We implement to Comparable interface to provide some natural ordering to the objects of Card class.
We implement the compareTo() method. We compare the cards first by their value and then by their suit.
This is the output.
In this tutorial, we have shown how to compare objects in Java using Comparable and Comparator . You might also be interested in the related tutorials: Java tutorial, Reading text files in Java, and Filtering a list in Java.
Comparable and Comparator in Java
Comparable is an interface providing the default / natural ordering to the implemented objects in an array or collection (List, Set and Map)
Comparator are comparison functional interfaces passed to sort methods and constructors such as sort(Comparator) of a List instance, Arrays.sort(Comparator) , SortedSet and SortedMap constructors to
Control over the sorting order of Comparable objects with Comparator.naturalOrder() and Comparator.reverseOrder()
Provide the custom sorting order of objects with Comparator.comparing(keyExtractor, keyComparator) methods
Comparator can also be used to implement the Comparable contract. This is the recommended way since Java 8+, especially when you’d like to compare multiple object fields
Both Comparable and Comparator are members of the Java Collections Framework
Let’s walk through this tutorial to explore them in more details
Implement Comparable to provide the default ordering
By implementing Comparable , you can provide the default ordering to the objects in an array or collection
The following example passes Comparator.naturalOrder() to the sort method of an ArrayList instance to use the default / natural sort logic defined by the Comparable implementation of the underlying objects, ComparableBook
The ComparableBook class is defined as below
Object implements Comparable need define the int compareTo(Object) contract method. String and primitive wrapper classes such as Integer, Long, Float, Double and BigInteger are already implemented compareTo method of Comparable so you can reuse them in your definition
In the above compareTo implementation example, title is used as the sort key, compareTo of String is reused to sort the keys in alphabetical/ascending order
Sort keys can also be ordered in descending by switching between the caller and the parameter of compareTo as the following implementation
If you’d like to compare multiple fields when implementing compareTo , check out the latter part of this tutorial
Use Comparator to provide the ordering of non- Comparable objects
Without the Comparable implementation, you have to specify explicitly the sorting key function by using Comparator functional interface, every time you sort the objects under an array or collection
The following example uses Comparator.comparing(keyExtractor, keyComparator) to provide the ordering. keyExtractor is a function used to extract the sort key. keyComparator is an optional Comparator, the default is Comparator.naturalOrder, used to compare the sort key
Book is defined as the following
Use Comparator to override the default ordering of Comparable
- You can reverse the default sorting direction of Comparable objects by using Comparator.reverseOrder()
- Override the sorting key of Comparable objects with Comparator.comparing(keyExtractor, keyComparator)
Use Comparator to implement compareTo of Comparable and compare multiple fields
- You can use Comparator.comparing to implement the compareTo contract of Comparable interface. The above definition inside ComparableBook can be rewritten like this
- It’s especially useful when you’d like to compare multiple fields, you can attach multiple thenComparing into the chain after the first comparing
- The multiple multiple fields comparing chain also works well when providing the inline Comparator to the sort methods of a List instance or SortedSet and SortedMap constructors
- You can sort the field in descending order by adding Comparator.reverseOrder() as a second argument on each comparing method
- The reversed() method has the same above effect but it is only useful when comparing one field
Conclusion
In this tutorial, we learned the difference between Comparable and Comparator and when to use them
In short, Comparable and Comparator provide the default and custom sorting logic, respectively, to the underlying objects in an array or collection