(转)Arrays.sort()你应该知道的事

Arrays.sort(T[], Comparator < ? super T > c) 是用来对用户自定义的对象数组排序功能的。Java 官方文档简单描述了它的作用,但不足以让我们深刻理解。为了更深入地理解它,这篇文章将梳理相关的关键点。

1、简单实例:如何使用Arrays.sort()

通过阅读下面代码,你能快速正确了解这个方法的用途。Comparator(比较器)用于根据Dogs的size比较其大小,并作为sort方法的参数。


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();

    }

}

输出:


1

2

2 1 3

1 2 3

2、策略模式的使用

这是运用策略模式的一个很好的场景,为什么策略模式对于这种场景非常适用?简单来说,策略模式使不同的算法在运行时得以选择。在这个例子中,通过传递不同的Comparator,可以选择不同的算法。基于上例,现在假设你有一个Comparator,用weight来代替size来比较Dogs。你可以简单创建一个新的Comprator如下:


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();

    }

}

输出:


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仅仅是一个接口,任何实现了Comparator在运行时都可以被使用,这是策略模式的核心理念。

3、为什么使用“super”

很显然,如果”Comparator<T>c”作为参数,但是第二个参数是”Comparator< ? super T > c”,使用<? super T>意味着类型可以是T或者是它的超类。为什么允许超类型呢?答案是:这种方式允许所有子类使用同一个comparator。看看下面这个例子一目了然。


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();

    }

}

输出:


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

4、总结

总的来说,从Arrays.sort()中你应该了解到:

  1. generic(范型)——super
  2. 策略模式
  3. 归并排序——nlog(n)时间复杂度
  4. java.util.Collections.sort(List<T>list, Comparator<?super T> c)类似于Arrays.sort

参考:Arrays.sort(T[], java.util.Comparator)

原文链接: programcreek 翻译: ImportNew.com刘志军
译文链接: http://www.importnew.com/8952.html
转载请保留原文出处、译者和译文链接。]

时间: 2024-10-26 23:13:12

(转)Arrays.sort()你应该知道的事的相关文章

Ajax系列之一些你应该知道的事

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

StackExchange:Web开发中你需要知道的事

在StackExchange上有人问了这样一个问题:What should every programmer know about web development?(关于Web开发,什么是所有程序员需要知道的?)里面给出的答案非常不错,所以,我翻译转载过来. 顺便说一下,StackExchange真是非常好,大家可以对同一个答案做贡献和修订,看看这个问题的修订过程你就知道了——专业的问答网站应该怎么去做.这就是我在这篇文章中也说过真正的用户体验是什么样的. 好了,下面是正文(我对原文做了一些批注

学习IOS需要知道的事

什么是iOS iOS是一款由苹果公司开发的操作系统(OS是Operating System的简称),就像平时在电脑上用的Windows XP.Windows 7,都是操作系统 那什么是操作系统呢?操作系统其实是一种软件,是直接运行在硬件(电脑.手机等)上的最基本的系统软件,任何其他软件都必须在操作系统的支持下才能运行. 按照运行系统的设备进行分类,可分为:电脑操作系统.手机操作系统. iOS与Win7等操作系统的差异 XP.Win7是PC操作系统,也就是运行在电脑上的操作系统 iOS是手持设备操

关于爱情应该知道的事

夫妻同心 ,黄土变金.结婚没结婚的都看看吧!怎样相处才能让夫妻成就一辈子?一.男人的五大需求:1.被理解:2.被信任:3.被支持:4.被认同:5.被尊重.二.女人的三大要求:1.安全感:2.浪漫:3.被疼和被哄.三.夫妻之间离不开的三大问题:1.经济问题:2.性的问题:3.沟通的问题.四.夫妻之间的三多三少:1.多关心对方的变化:2.多发现对方的优点:3.多讲正面的话:4.少抱怨:5.少指责:6.少误会.五.夫妻四处:1.多想对方的好处:2.欣赏对方的长处:3.体谅对方的难处:4.包容对方的短处

Weex学习与实践(一):Weex,你需要知道的事

Weex学习与实践(一):Weex,你需要知道的事 http://coderyi.com/posts/weex1/ 1.命令行工具:weex-toolkit  https://github.com/weexteam/weex-toolkit 2.调试工具: weex-devtool  https://github.com/weexteam/weex-devtool

学习C语言之前你要知道的事

序: 为了不浪费大家的时间,大牛就别继续往下看了,因为此文通篇都是废话.但是如果你真的是一个纯正的菜鸟,如果你真的是一个刚摸电脑的新手,如果你真的刚学C语言甚至还不知道C语言是什么,那么就请抽5分钟时间看看吧,也许真的会有帮助的. 我非常清晰的记得我大学时的第一堂C语言课.那是我所有的大学课程中最爽一堂课,为什么爽?因为我热爱C语言?呵呵,那个时候我连C语言是个毛线都不知道,哪里来的热爱.我之所以爽,是因为终于有一门课,可以让我这个学渣可以和学霸平起平坐了,大家都不会,要挂科一起挂啊.从始至终,

文件名、、扩展名的截取你必须知道的事

js中substr,substring,indexOf,lastIndexOf等的用法 1.substrsubstr(start,length)表示从start位置开始,截取length长度的字符串. var src="images/off_1.png";alert(src.substr(7,3)); 弹出值为:off 2.substringsubstring(start,end)表示从start到end之间的字符串,包括start位置的字符但是不包括end位置的字符. var src

Android Notification自定义通知样式你要知道的事

本文将根据个人经验对Notification做个总结,以供参考! 什么是通知(Notification) 通知是一个可以在应用程序正常的用户界面之外显示给用户的消息. 通知发出时,它首先出现在状态栏的通知区域中,用户打开通知抽屉可查看通知详情.通知区域和通知抽屉都是用户可以随时查看的系统控制区域. 作为安卓用户界面的重要组成部分,通知有自己的设计指南.在Android 5.0(API level 21)中引入的 Material Design 的变化是特别重要的,更多信息请阅读 通知设计指南.

安全用网,你应该知道的事

1.换手机号前,谨防泄密 ①修改支付宝账号绑定 登陆支付宝账户—点击账户设置—基本信息—手机—解绑. ②解绑微信账户 登陆微信,选择"我"—设置—账号与安全—手机号码—选择右上角菜单—解绑 ③解绑银行卡 一般可通过网银专业版或者柜台解绑,同时更换u盾,网上银行,手机银行,短信通知等业务 ④更改其他账号登陆设置 更改微博等社交网站的绑定手机 更改淘宝等购物网站的绑定手机 更改邮箱上面的绑定手机 更改证劵,基金的各项关联号码 更改12306等各网站的常用手机号 2.旧手机不要随便丢弃 ①将