Deep understanding of Arrays.sort()

when I meet this program-Largest Number-Leetcoode.I have no idea how to deal with it.So I know this method-Arrays.sort(T[],comparetor < ? super T> c).

Arrays.sort(T[], Comparator < ? super T > c) is a method for sorting user-defined object array. The official Java Doc briefly describe what it does, but not much for deep understanding. In this post, I will walk though the key information for deeper understanding of this method.

There are some examples to show this method how to work.

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
import java.util.Arrays;
import java.util.Comparator;

class Dog{
int size;
public Dog(int s){
size = s;
}
}

class DogSizeComparator implements Comparator<Dog>{

@Override
public int compare(Dog o1, Dog o2) {
return o1.size - o2.size;
}
}

public class ArraySort {

public static void main(String[] args) {
Dog d1 = new Dog(2);
Dog d2 = new Dog(1);
Dog d3 = new Dog(3);

Dog[] dogArray = {d1, d2, d3};
printDogs(dogArray);

Arrays.sort(dogArray, new DogSizeComparator());
printDogs(dogArray);
}

public static void printDogs(Dog[] dogs){
for(Dog d: dogs)
System.out.print(d.size + " " );

System.out.println();
}
}

Output

1
2
2 1 3
1 2 3

The Strategy Pattern Used in Arrays.sort()

In brief,Strategy pattern enables different algorithms get selected at runtime.In this case,by passing diffrent Compartor,different algorithms can get selected.Based on example above and now assuming you have another Comparator which compares Dogs by weight instead of by size,you can simply create a new Comparator like this following.

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
class Dog{
int size;
int weight;

public Dog(int s, int w){
size = s;
weight = w;
}
}

class DogSizeComparator implements Comparator<Dog>{

@Override
public int compare(Dog o1, Dog o2) {
return o1.size - o2.size;
}
}

class DogWeightComparator implements Comparator<Dog>{

@Override
public int compare(Dog o1, Dog o2) {
return o1.weight - o2.weight;
}
}

public class ArraySort {

public static void main(String[] args) {
Dog d1 = new Dog(2, 50);
Dog d2 = new Dog(1, 30);
Dog d3 = new Dog(3, 40);

Dog[] dogArray = {d1, d2, d3};
printDogs(dogArray);

Arrays.sort(dogArray, new DogSizeComparator());
printDogs(dogArray);

Arrays.sort(dogArray, new DogWeightComparator());
printDogs(dogArray);
}

public static void printDogs(Dog[] dogs){
for(Dog d: dogs)
System.out.print("size="+d.size + " weight=" + d.weight + " ");

System.out.println();
}
}

Output:

1
2
3
size=2 weight=50 size=1 weight=30 size=3 weight=40 
size=1 weight=30 size=2 weight=50 size=3 weight=40
size=1 weight=30 size=3 weight=40 size=2 weight=50

Comparator is just an interface. Any Comparator that implements this interface can be used during run-time. This is the key idea of Strategy design pattern.

Why Use “super”?

It is straightforward if “Comparator < T > c” is the parameter, but the second parameter is “Comparator< ? super T > c”. < ? super T > means the type can be T or its super types. Why it allows super types? The answer is: This approach allows using same comparator for all sub classes. This is almost obvious in the following example.

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
51
52
53
54
55
56
57
58
59
60
61
import java.util.Arrays;
import java.util.Comparator;

class Animal{
int size;
}

class Dog extends Animal{
public Dog(int s){
size = s;
}
}

class Cat extends Animal{
public Cat(int s){
size = s;
}
}

class AnimalSizeComparator implements Comparator<Animal>{

@Override
public int compare(Animal o1, Animal o2) {
return o1.size - o2.size;
}
//in this way, all sub classes of Animal can use this comparator.
}

public class ArraySort {

public static void main(String[] args) {
Dog d1 = new Dog(2);
Dog d2 = new Dog(1);
Dog d3 = new Dog(3);

Dog[] dogArray = {d1, d2, d3};
printDogs(dogArray);

Arrays.sort(dogArray, new AnimalSizeComparator());
printDogs(dogArray);

System.out.println();

//when you have an array of Cat, same Comparator can be used.
Cat c1 = new Cat(2);
Cat c2 = new Cat(1);
Cat c3 = new Cat(3);

Cat[] catArray = {c1, c2, c3};
printDogs(catArray);

Arrays.sort(catArray, new AnimalSizeComparator());
printDogs(catArray);
}

public static void printDogs(Animal[] animals){
for(Animal a: animals)
System.out.print("size="+a.size + " ");
System.out.println();
}
}

Output:

1
2
3
4
5
size=2 size=1 size=3 
size=1 size=2 size=3

size=2 size=1 size=3
size=1 size=2 size=3

Reference

Deep Understanding of Arrays.sort()