Pages

Tuesday, December 7, 2021

Java 8 Comparator Comparing Reverse Order

 

1. Overview

In this tutorial, We'll learn how to use a comparator to sort the collection in reverse order.

In Java 8, Comparator interface is added with the reverse() method to reverse the collection using the existing comparator instead of creating another custom comparator.

First, let us learn how to reverse the comparator for comparing the objects from the collection before java 8 and next using Java 8 Comparator new methods.


Java 8 Comparator Comparing Reverse Order



2. Before java 8


In the older version of JDK 1.8, we can not reverse the comparator operations using any built-in API methods but we can reverse the list of objects using reverse() method from the Collections.

This does not use the comparator interface as underlying logic. It just uses the ListIterator to reverse the list.

Example 1
package com.javaprogramto.java8.comparator.reverse;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ComparatorReverse {

	public static void main(String[] args) {

		List<String> list = Arrays.asList("1", "3", "2");

		System.out.println("Original list - " + list);
		Collections.reverse(list);
		System.out.println("Reversed list - " + list);

	}
}

Output
Original list - [1, 3, 2]
Reversed list - [2, 3, 1]


3. Using Java 8 Comparator.reverseOrder()


Comparator interface has the method that is reverseOrder() from java 8.

Comparator.reverseOrder() method is used to get the comparator that imposes the reverse of the natural ordering.

reverseOrder() method internally creates the instance of the ReverseComparator static inner class which makes the call to the Comparator.naturalOrder() method.


Example 2
package com.javaprogramto.java8.comparator.reverse;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ComparatorReverse2 {

	public static void main(String[] args) {

		List<String> list = Arrays.asList("1", "3", "2");

		System.out.println("Original list - " + list);

		List<String> sortedList = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

		System.out.println("Sorted list - " + sortedList);

	}
}

Output
Original list - [1, 3, 2]
Sorted list - [3, 2, 1]

In the above code, we did not create any comparator to sort the strings in descending order. We have used the Comparator.reverseOrder() method to create the default comparator for the reverse order.

Example 3

What happens if the reverseOrder() method is called twice? (calling reverseOrder() on the result of first call to reverseOrder()).

Look at the below example, you will get a clear idea of what trying to do.

public class ComparatorReverse3 {

	public static void main(String[] args) {

		List<String> list = Arrays.asList("1", "3", "2");

		System.out.println("Original list - " + list);

		List<String> result1 = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
		System.out.println("result 1 " + result1);

		List<String> result2 = result1.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
		System.out.println("result 2 - " + result2);

	}
}


Output
Original list - [1, 3, 2]
result 1 [3, 2, 1]
result 2 - [3, 2, 1]

From the result, we can understand that multiple calls to the reverseOrder() method do not change the output. It produces the same output always.


4. Java 8 Comparator.reverseOrder() with Custom Objects


Example 4
package com.javaprogramto.java8.comparator.reverse;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ComparatorReverse6 {

	public static void main(String[] args) {

		List<Teacher2> Teacher2s = new ArrayList<>();

		Teacher2s.add(new Teacher2("Rajesh", "Science", 10));
		Teacher2s.add(new Teacher2("Mahesh", "Mathematics", 5));
		Teacher2s.add(new Teacher2("Suresh", "English", 10));
		Teacher2s.add(new Teacher2("Rakesh", "Science", 3));
		Teacher2s.add(new Teacher2("Ramesh", "Mathematics", 8));

		System.out.println("Original Teacher2s list - ");
		Teacher2s.forEach(t -> System.out.println(t.getSubject()));

		List<Teacher2> sortBynameList = Teacher2s.stream().sorted()
				.collect(Collectors.toList());

		System.out.println("\nSorted by subject ascending order");
		sortBynameList.forEach(t -> System.out.println(t.getSubject()));

		sortBynameList = Teacher2s.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

		System.out.println("\nSorted by subject descending order ");
		sortBynameList.forEach(t -> System.out.println(t.getSubject()));
	}
}


package com.javaprogramto.java8.comparator.reverse;

public class Teacher2 implements Comparable<Teacher2>{

	String name;
	String subject;
	int experience;

	public Teacher2(String name, String subject, int experience) {
		super();
		this.name = name;
		this.subject = subject;
		this.experience = experience;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public int getExperience() {
		return experience;
	}

	public void setExperience(int experience) {
		this.experience = experience;
	}

	@Override
	public int compareTo(Teacher2 o) {
		return this.getSubject().compareTo(o.getSubject());
	}
}

Output
Original Teacher2s list - 
Science
Mathematics
English
Science
Mathematics

Sorted by subject ascending order
English
Mathematics
Mathematics
Science
Science

Sorted by subject descending order 
Science
Science
Mathematics
Mathematics
English


5. Using java 8 Comparator.reverse()


Comparator.reverse() method is used to reverse the existing comparator sorting behaviour.

This reverse() method must be used on comparator instances only.

Example 5
package com.javaprogramto.java8.comparator.reverse;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ComparatorReverse4 {

	public static void main(String[] args) {

		List<String> list = Arrays.asList("100", "3", "20");

		System.out.println("Original list - " + list);

		Comparator<String> sortByLength = Comparator.comparing(String::length);

		List<String> sortedList = list.stream().sorted(sortByLength).collect(Collectors.toList());

		System.out.println("Sorted by length ascending order - " + sortedList);

		Comparator<String> sortByLengthReverse = sortByLength.reversed();

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

		System.out.println("Sorted by length descending order - " + sortedList);
	}
}


Output
Original list - [100, 3, 20]
Sorted by length ascending order - [3, 20, 100]
Sorted by length descending order - [100, 20, 3]


6. Java 8 Comparator reverse() With Custom Objects


The comparator can be created with the help of lambda expressions. Look at the simple examples of how to create the comparator with Lambda?

In this section, we will learn how to use reverse() method on custom objects to reverse the existing sorting logic. This will help to reduce the rewriting of the same code.

Example 6
package com.javaprogramto.java8.comparator.reverse;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ComparatorReverse5 {

	public static void main(String[] args) {

		List<Teacher> teachers = new ArrayList<>();

		teachers.add(new Teacher("Rajesh", "Science", 10));
		teachers.add(new Teacher("Mahesh", "Mathematics", 5));
		teachers.add(new Teacher("Suresh", "English", 10));
		teachers.add(new Teacher("Rakesh", "Science", 3));
		teachers.add(new Teacher("Ramesh", "Mathematics", 8));

		System.out.println("Original teachers list - ");
		teachers.forEach(t -> System.out.println(t.getName()));

		Comparator<Teacher> sortByName = (t1, t2) -> t1.getName().compareTo(t2.getName());

		List<Teacher> sortBynameList = teachers.stream().sorted(sortByName).collect(Collectors.toList());

		System.out.println("\nSorted by name ascending order");
		sortBynameList.forEach(t -> System.out.println(t.getName()));

		Comparator<Teacher> sortByNameReverse = sortByName.reversed();

		sortBynameList = teachers.stream().sorted(sortByNameReverse).collect(Collectors.toList());

		System.out.println("Sorted by name descending order ");
		sortBynameList.forEach(t -> System.out.println(t.getName()));
	}
}

Output
Original teachers list - 
Rajesh
Mahesh
Suresh
Rakesh
Ramesh

Sorted by name ascending order
Mahesh
Rajesh
Rakesh
Ramesh
Suresh

Sorted by name descending order 
Suresh
Ramesh
Rakesh
Rajesh
Mahesh


7. Conclusion


In this article, we have seen how to use the Comparator reverseOrder() and reverse() method in java 8 with examples.

Use Comparator reverseOrder() method when working with the collection of wrapper class objects because these are implemented by the Comparable interface. And also reverseOrder() method is used to List of custom objects which implements the Comparable interfaces.

If user-defined classes are not implemented in any Comparator or Comparable interface then better to custom comparators with Comparator.reveres() method which is specific to the use case.







No comments:

Post a Comment

Please do not add any spam links in the comments section.