5.11 Self 9.2
Comparator and comparable
Comparable is a logic that define how to compare, use compareTo
public class T implements Comparable<T> {
@Override
public int compareTo(T obj);
}
Comparator is a method to make object comparable.
public int compare(Object obj1, Object obj2):
For example
This is a normal way to sort integer
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
//List is an interface that extends Collection interface
//You need a concrete class that implements List
public class main {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(45);
numbers.add(21);
numbers.add(67);
numbers.add(23);
System.out.println("Before sorting: " + numbers);
Collections.sort(numbers);
System.out.println("After sorting: " + numbers);
}
}
Now, we want to sort these numbers according to the last digit, then we have two ways
1. Using Comparator
-
The basic way
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; //List is an interface that extends Collection interface //You need a concrete class that implements List public class main { static class CompareByLastDigit implements Comparator<Integer> { @Override public int compare(Integer i, Integer j) { if (i % 10 < j % 10) return -1; else return 1; } } public static void main(String[] args) { Comparator<Integer> comparator = new CompareByLastDigit(); List<Integer> numbers = new ArrayList<>(); numbers.add(41); numbers.add(22); numbers.add(60); numbers.add(23); System.out.println("Before sorting: " + numbers); Collections.sort(numbers, comparator); System.out.println("After sorting: " + numbers); } }
-
Using anonymous class
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; //List is an interface that extends Collection interface //You need a concrete class that implements List public class main { public static void main(String[] args) { Comparator<Integer> comparator = new Comparator<Integer>() { public int compare(Integer i, Integer j) { if(i % 10 < j % 10) return -1; else return 1; } }; List<Integer> numbers = new ArrayList<>(); numbers.add(41); numbers.add(22); numbers.add(60); numbers.add(23); System.out.println("Before sorting: " + numbers); Collections.sort(numbers, comparator); System.out.println("After sorting: " + numbers); } }
-
Using lambda expression
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; //List is an interface that extends Collection interface //You need a concrete class that implements List public class main { public static void main(String[] args) { Comparator<Integer> comparator = (Integer i, Integer j) -> i % 10 < j % 10 ? -1 : 1; List<Integer> numbers = new ArrayList<>(); numbers.add(41); numbers.add(22); numbers.add(60); numbers.add(23); System.out.println("Before sorting: " + numbers); Collections.sort(numbers, comparator); System.out.println("After sorting: " + numbers); } }
2. Using Comparable
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
//List is an interface that extends Collection interface
//You need a concrete class that implements List
public class main {
static class LastDigitNumber implements Comparable<LastDigitNumber> {
private int value;
public LastDigitNumber(int value) {
this.value = value;
}
@Override
public int compareTo(LastDigitNumber other) {
return Integer.compare(this.value % 10, other.value % 10);
}
@Override
public String toString() {
return String.valueOf(value);
}
}
public static void main(String[] args) {
List<LastDigitNumber> numbers = new ArrayList<>();
numbers.add(new LastDigitNumber(41));
numbers.add(new LastDigitNumber(22));
numbers.add(new LastDigitNumber(60));
numbers.add(new LastDigitNumber(23));
System.out.println("Before sorting: " + numbers);
Collections.sort(numbers);
System.out.println("After sorting: " + numbers);
}
}
Now, we are given a more complex example
We have some students and want to sort students by age
-
Using comparable
import java.util.ArrayList; import java.util.Collections; import java.util.List; //List is an interface that extends Collection interface //You need a concrete class that implements List public class main { static class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Student other) { return Integer.compare(this.age, other.age); } @Override public String toString() { return name + "(" + age + ")"; } } public static void main(String[] args) { List<Student> students = new ArrayList<>(); students.add(new Student("Alice", 21)); students.add(new Student("Bob", 19)); students.add(new Student("Charlie", 22)); students.add(new Student("Dave", 20)); System.out.println("Before sorting: " + students); Collections.sort(students); System.out.println("After sorting: " + students); } }
-
Using Comparator
import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Comparator; //List is an interface that extends Collection interface //You need a concrete class that implements List public class main { static class Student { public String name; public int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return name + "(" + age + ")"; } } public static void main(String[] args) { List<Student> students = new ArrayList<>(); Comparator<Student> comparator = (Student i, Student j) -> i.age < j.age ? -1 : 1; students.add(new Student("Alice", 21)); students.add(new Student("Bob", 19)); students.add(new Student("Charlie", 22)); students.add(new Student("Dave", 20)); System.out.println("Before sorting: " + students); Collections.sort(students, comparator); System.out.println("After sorting: " + students); } }