Arrays.sort(T[], Comparator<? super T> c) 是一个用于用户自定义排序对象的方法,在离线的JavaDoc中简单地描述了他怎么工作,但是没有更深入的解释,在这篇文章中,我们将讨论深入了解这个方法的关键信息。
通过读下面的例子,你将快速地知道如何正确的使用这个方法,一个Comparator被定义比较狗的尺寸,Comparator被用作排序方法的参数。
import java.util.Arrays; import java.util.Comparator; class Dog{ int size; public Dog(int s){ size = s; } } class DogSizeComparator implements Comparator{ @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(); } }
输出:
2 1 3 1 2 3
这是一个完美的策略模式例子,这里值得注意为什么 策略模式有这个场景中是好的。简单来说,策略模式允许在运行时选择不同的算法,在这个用例中,通过解析不同的Comparator能选中不同的算法。基于上面的例子,假设你可以有其他的Comparator,能比较够的重量,你可以简单的创建一个新的Comparator,如下:
class Dog{ int size; int weight; public Dog(int s, int w){ size = s; weight = w; } } class DogSizeComparator implements Comparator{ @Override public int compare(Dog o1, Dog o2) { return o1.size - o2.size; } } class DogWeightComparator implements Comparator{ @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(); } }
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只是一个接口,任何Comparator实现了这个接口都能在运行时中使用,这就是策略设计模式的关键意图。
这十分简单,如果Comparator < T > c是参数,但是第二个参数Comparator< ? super T > c”. < ? super T >意味着类型可能是T或者他的超类,为什么允许超类?答案是:这样允许同样的比较器对应服务所有的之类,下面是一个十分明显的例子。
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{ @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(); } }
size=2 size=1 size=3 size=1 size=2 size=3 size=2 size=1 size=3 size=1 size=2 size=3
总的来说,Array.sort()表达的
1、泛型 - super
2、策略模式
3、归并排序 -nlog(n)的时间复杂度
4.Java.util.Collections#sort(List < T > list, Comparator < ? super T > c) 有相似的想法。