Java provides two methods for sorting elements in a collection or array, one is to implement the Comparable interface, and the other is to implement the Comparator interface.

Interface package method
Comparable<T> java.lang public int compareTo(T o);
Comparator<T> java.util int compare(T o1, T o2);

Comparable Interface

For example, Item implements Comparable and compare their implementation class’s price.

The compareTo method used to compare this object with specific incoming object o.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Item implements Comparable<Item> {
private String name;

private Double price;

public Double getPrice() {
return price;
}

public String getName() {
return name;
}

@Override
public int compareTo(Item o) {
return this.getPrice().compareTo(o.getPrice());
}
}

compareTo method’s detail info

  • param: o the object to be compared.
  • return: a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
  • throws: NullPointerException if the specified object is null
  • throws: ClassCastException if the specified object’s type prevents it from being compared to this object.

It is strongly recommended, but not strictly required that
(x.compareTo(y)==0) == (x.equals(y)). Generally speaking, any
class that implements the Comparable interface and violates
this condition should clearly indicate this fact. The recommended language is “Note: this class has a natural ordering that is inconsistent with equals.”

When you want to sort a list of Item, you need just one line. Because Collections will automatedly sort as the rule of the compareTo method.

1
Collections.sort(items);

Extra Tips

If your comparing property is not an object, just a basic data type, we can not use thecompareTo method to compare two data. Using mathematics symbol - will work.

Comparator Interface

For example, customize a class to implements a Comparator and put this comparator in a sort method. Provided 2 methods to implement Comparator. One is to define a new class, the other is to create an anonymous inner class.

There is only one method that must have to implement - compare. This method is used to compare to Object o1, o2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class Item {
private String name;

private Double price;

public Item() {

}

public Item(Double price) {
this.price = price;
}

public Double getPrice() {
return price;
}

public String getName() {
return name;
}

/**
* custom comparator class
*/
static class MyComparator implements Comparator<Item>{
@Override
public int compare(Item o1, Item o2) {
return o1.getPrice().compareTo(o2.getPrice());
}
}

public static void main(String[] args) {
List<Item> items = new ArrayList<>();

items.add(new Item(2.0));
items.add(new Item(1.0));
items.add(new Item(3.0));
// method 1
Collections.sort(items, new MyComparator());
// method 2
Collections.sort(items, new Comparator<Item>() {
@Override
public int compare(Item o1, Item o2) {
return o1.getPrice() > o2.getPrice() ? 1 : o1.getPrice().equals(o2.getPrice()) ? 0 : -1;
}
});

System.out.println(JsonUtils.toJson(items));
}
}

the method compare‘s detail info

  • param: o1 the first object to be compared.
  • param: o2 the second object to be compared.
  • return: a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
  • throws: NullPointerException if an argument is null and this comparator does not permit null arguments.
  • throws: ClassCastException if the arguments’ types prevent them from being compared by this comparator.

Arrays & Collections sort

Method Comparisons
Arrays.sort(int[].., fromIndex, endIndex) int[], double[], byte[]…
Arrays.sort(T[], Comparator<? super T> c) Integer[], Double[], Byte[]…
Collections.sort(List<T>, Comparator<? super T> c) List<Integer>, List<Double>, List<Byte>…

Sort method’s rule

o1 is the left number, o2 is the next right number

  • when comparator return <= 0, o1, o2 object don’t exchange
  • when comparator return > 1, o1, o2 object exchange

Basic Data Type Code Example

Java API -Arrays.sort() provide sort mthod for basic data type such as int[], double[], byte[]... in an increasing order and this is the only one sort methode provide for basic data type .If you want to change the original order, you should use wrapper class.

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {

int[] a = {4,3,2,1};
Arrays.sort(a, 0, 2);
for(int i = 0; i < a.length; i ++) {
System.out.print(a[i] + " ");
}
// wrapper class
Integer[] b = {4,3,2,1};
Arrays.sort(b, Comparator.reverseOrder());
}

Wrapper Class Code Example

We can customize a comparator class to implement Comparator Interface and put it in sort method, but we have a more concise method to achieve it by using Lambda Expressions or Comparator.comparingDouble(), Comparator.comparing() and so on.

The following code example shows wrapper data type‘s natural and reverse sort method, you just need to pick your favorite one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {

// for natural order - small to big
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
// method 1
Collections.sort(list);

// for reverse order
// method 1. Use Lambda Expressions
Collections.sort(list, (a, b) -> Integer.compare(b, a));
// method 2. Use Comparator.comparing
Collections.sort(list, Comparator.comparing((a) -> -a));
// method 3. user reverse
Collections.sort(list, Comparator.reverseOrder());

// method 4. Use Comparator.comparingInt
Collections.sort(list, Comparator.comparingInt(Integer::intValue).reversed());

System.out.println(JsonUtils.toJson(list));
}

Object Code Example

The following code example shows complex data type‘s natural and reverse sort methods, you just need to pick you favorite one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void main(String[] args) {
List<Item> items = new ArrayList<>();
items.add(new Item(2.0));
items.add(new Item(1.0));
items.add(new Item(3.0));

// for items' natural order
// methode 1. Lambda Expressions
Collections.sort(items, (a, b) -> Double.compare(a.getPrice(), b.getPrice()));
// methode 2. Comparator.comparing
Collections.sort(items, Comparator.comparing((a) -> a.getPrice()));
// method 3. Comparator.comparingDouble
Collections.sort(items, Comparator.comparingDouble(Item::getPrice));

// for items' reverse order
// method 1. Lambda Expressions
Collections.sort(items, (a, b) -> Double.compare(b.getPrice(), a.getPrice()));
// method 2. Comparator.comparing
Collections.sort(items, Comparator.comparing((a) -> -a.getPrice()));
// method 3. Comparator.comparingDouble
Collections.sort(items, Comparator.comparingDouble(Item::getPrice).reversed());

System.out.println(JsonUtils.toJson(items));
}

Author’s Message

Recently I practiced algorithms on LeetCode. Under some conditions, I have to sort Array or List. I was confused by the different kinds of comparison methods. So I sorted out the above knowledge points.

https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html

https://www.baeldung.com/java-8-comparator-comparing