Java arraylist sort comparator example

Sorting with Comparable and Comparator

Learn to sort a List of Objects by a field value. Note that if you have millions of records for sorting at a time then a database query is the best way. Otherwise, using either Comparable or Comparator interface is a very convenient approach.

In the examples given in this tutorial, we will be using the record type User. It has four fields: id , firstName , lastName and age . I have chosen these fields purposefully to show different usecases.

import java.io.Serializable; public record User(Long id, String firstName, String lastName, Integer age) implements Serializable < public User < if (age < 18) < throw new IllegalArgumentException("You cannot hire a minor person"); >> >

We will be using the given unsorted list and sorting it on different field values.

private static List getUnsortedUsers()

Moving on, we will be using the Comparable and Comparator interfaces for sorting on different field values.

2. Sorting with Comparable for Natural Ordering

2.1. Implementing Comparable Interface

Comparable interface provides a single method compareTo(T o) to implement by any class so that two objects of that class can be compared. This method is used for implementing the natural sorting behavior.

The User record after implementing the Comparable interface is as follows. The similar implementation can be done for class types as well. The default sorting has been done on the id field.

public record User(Long id, String firstName, String lastName, Integer age) implements Serializable, Comparable  < public User < if (age < 18) < throw new IllegalArgumentException("You cannot hire a minor person"); >> @Override public int compareTo(User o) < return this.id.intValue() - o.id.intValue(); >>

2.2. Collections.sort() Method

Читайте также:  Css div content auto height

We can pass the List of objects in the sort() method that will sort the objects in their natural ordering i.e. by id field.

Check out the output in the console.

[User[id=1, firstName=A, lastName=Q, age=24], User[id=2, firstName=C, lastName=O, age=27], User[id=3, firstName=D, lastName=N, age=29], User[id=4, firstName=B, lastName=P, age=22], User[id=5, firstName=E, lastName=M, age=25]] 

Java Stream API has sorted() method that can sort a stream of items in the natural order. Note that stream operations do not modify the original collections, so the objects in the list will be unchanged.

List sortedList = list.stream() .sorted() .collect(Collectors.toList());

3. Sorting with Comparator for Custom Ordering

3.1. Creating Comparator Instances

Let us assume that we want to sort the users list based on some other fields, for example, by firstName or age . We can modify the User record because it already implements the natural ordering by id field.

Here comes the Comparator interface to rescue. A Comparator can be used to define the custom ordering. To sort on different object fields, we can create multiple Comparator implementations.

For example, to sort the users list by firstName , we can create FirstNameSorter class that implements the Comparator.

import java.util.Comparator; public class FirstNameSorter implements Comparator  < @Override public int compare(User o1, User o2) < return o1.firstName().compareTo(o2.firstName()); >>

Note that we can use the lambda expression for creating the inline Comparator instances, for single-time uses.

Comparator firstNameSorter = (o1, o2) -> o1.firstName().compareTo(o2.firstName());

We can create group by sorting effect by combining multiple comparators using Comparator.thenComparing() method. For example, we can create a complex comparator fullNameSorter for sorting a list by first name and then by last name.

Comparator firstNameSorter = (o1, o2) -> o1.firstName().compareTo(o2.firstName()); Comparator lastNameSorter = (o1, o2) -> o1.lastName().compareTo(o2.lastName()); Comparator fullNameSorter = firstNameSorter.thenComparing(lastNameSorter);

One more type of Comparator is worth discussing that is used for reverse ordering. We can get this reverse comparator by calling reversed() method on any comparator instance.

Comparator reverseSorter = firstNameSorter.reversed();

Similar way, we can create as many comparators as needed in the applications.

To sort using Collection.sort() method, pass two method arguments. The first argument is the unsorted list and the second argument is the Comparator instance.

List list = getUnsortedUsers(); Comparator firstNameSorter = (o1, o2) -> o1.firstName().compareTo(o2.firstName()); Collections.sort(list, firstNameSorter);

To sort the stream items using comparator instance, we can pass the comparator as method argument to the sorted() method.

List list = getUnsortedUsers(); Comparator firstNameSorter = (o1, o2) -> o1.firstName().compareTo(o2.firstName()); List sortedList = list.stream() .sorted(firstNameSorter) .collect(Collectors.toList());

4. hashCode() and equals() Contract

If we have overridden equals() method in the User class, always remember to honor the contract between hashCode() and equals() methods.

If two objects are equal using equals() method then compareTo() method should return zero.

As a general practice, always use the same fields in both methods. If we are using id field in the equals() method then use the id field in compareTo() method also. An example implementation is given as follows:

import java.io.Serializable; import java.util.Objects; public record User(Long id, String firstName, String lastName, Integer age) implements Serializable, Comparable  < public User < if (age < 18) < throw new IllegalArgumentException("You cannot hire a minor person"); >> @Override public int compareTo(User o) < return this.id.intValue() - o.id.intValue(); >@Override public int hashCode() < return Objects.hash(id); >@Override public boolean equals(Object obj) < if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; return Objects.equals(id, other.id); >>

In this Java Comparable and Comparator tutorial, we learned to implement both interfaces in different ways for different usecases. We also saw the use of both interfaces in Java Stream API.

Finally, we understood how to correctly override hashCode() and equals() method on objects to keep sorting functioning properly.

Источник

Java sort ArrayList using Comparator example

Java sort ArrayList using comparator example shows how to sort an ArrayList using a custom comparator by object properties in ascending or descending order.

How to sort ArrayList using Comparator?

We are going to store the Student objects in the ArrayList as given below.

We want to sort the ArrayList by student’s total marks in ascending order. In order to sort the ArrayList by object properties, we will need to create a custom comparator that will compare objects based on their properties.

The class implementing the Comparator interface must implement the compare method which returns a positive integer, zero or negative integer values.

For our requirement, the compare method needs to return positive integer if object1’s total marks is greater than object2’s total marks. It should return 0 if both object’s marks are equal. And it should return negative integer is object1’s total marks are less than object2’s total marks as given below.

The ArrayList can be sorted by a custom comparator using the sort method of Collections class.

This method sorts the List or ArrayList by the specified custom comparator.

Here is the complete example.

How to sort ArrayList in descending order?

In the above example, we returned positive, zero and negative values for greater, equal and less object values respectively. In order to sort the list elements in descending order, we need to inverse the return values.

That is, we need to return a negative value if object1’s total marks property is greater than object2’s total marks, zero for equal, and positive value if object1’s total marks property is less than object2’s total marks as given below.

Источник

Java Collections sort()

Learn to use Collections.sort() method to sort a list of objects using some examples.

By default, the sort() method sorts a given list into ascending order (or natural order). We can use Collections.reverseOrder() method, which returns a Comparator, for reverse sorting.

1. Sorting in Natural Order and Reverse Order

Collections.sort(list); //Sorts in natural order Collections.sort(list, Collections.reverseOrder()); //Sorts in reverse order
  1. Above method sorts the specified list of items into their natural order.
  2. All items must implement the Comparable interface.
  3. All items must be mutually comparable and should not throw ClassCastException .
  4. This sort is guaranteed to be stable. It means that equal elements will not be reordered as a result of the sort.
  5. The specified list must be modifiable, but need not to be resizable.
  6. The sort() does not return any value.

1.1. Sorting an ArrayList of Strings

Java program to sort a list of strings lexicographically (in the dictionary order).

List names = Arrays.asList("Alex", "Charles", "Brian", "David"); //Prints - [Alex, Brian, Charles, David] Collections.sort(names); //Prints - [David, Charles, Brian, Alex] Collections.sort(names, Collections.reverseOrder()); 

1.2. Sorting ArrayList of Objects by Field

We may require to sort a list of custom objects which can have their own sorting logic. In this case, implement the Comparator interface in the custom class.

For example, the domain object Employee has default sorting on the name field. Checkout for comparison logic in compareTo() method.

public class Employee implements Comparable < private Integer id; private String name; private String email; private LocalDate dateOfBirth; //Getters and Setters @Override public int compareTo(Employee e) < return this.getName().compareTo(e.getName()); >>

Nest Java program sorts the list of Employee objects by their name;

ArrayList employees = methodReturnsUnsortedList(); //Narutal order sorting Collections.sort(employees); //Reverse sorting Collections.sort(employees, Collections.reverseOrder());

2. Custom Sorting using Comparators

The second parameter in sort() method takes an instance of Comparator .

We can implement any kind of comparison logic with the help of comparators and then we can use sort() method to sort the list based on the given custom logic.

Collections.sort(List, Comparator);

We can create a separate Comparator instances for each kind of sorting need, and then we can combine those instances to create group sorting effect.

For example, if we want to sort the Employee list on three fields – id, name, and age. In this case, we need to create 3 Comparator instances.

2.1. Creating Custom Comparator

This is general syntax to create a Comparator in Java. In this case, we are creating a Comparator which will sort the Employee list by id field.

Comparator compareById = new Comparator() < @Override public int compare(Employee o1, Employee o2) < return o1.getId().compareTo(o2.getId()); >>; Comparator compareByName = new Comparator() < @Override public int compare(Employee o1, Employee o2) < return o1.getName().compareTo(o2.getName()); >>;

We can use lambda expression for further shortening the syntax.

//Id Comparator Comparator compareById = (Employee o1, Employee o2) -> o1.getId().compareTo( o2.getId() ); //Name Comparator Comparator compareByName = (Employee o1, Employee o2) -> o1.getName().compareTo( o2.getName() );

2.2. Using Comparator for Sorting

ArrayList employees = getUnsortedEmployeeList(); Comparator compareById = (Employee o1, Employee o2) -> o1.getId().compareTo( o2.getId() ); Collections.sort(employees, compareById); Collections.sort(employees, compareById.reversed());

In the above code examples, we learned to sort an ArrayList in default order or reverse order.

We also learned to use the Comparators for implementing the custom sorting logic.

Источник

Оцените статью