在Arrays工具类中, sort函数 可以对普通数组进行排序,如以下代码所示:
int[] hello = {18888,8888,5888,13888}; Arrays.sort(hello); System.out.println(Arrays.toString(hello));//[5888, 8888, 13888, 18888] String[] heroName = {"成吉思汗","狄仁杰","孙尚香","虞姬"}; Arrays.sort(heroName); System.out.println(Arrays.toString(heroName));//[孙尚香, 成吉思汗, 狄仁杰, 虞姬]
上面的代码分别对 int类型的数组 和 String类型的数组 进行了排序,对这个排序的算法感兴趣的同学可以看 这里 , 那么我们自定义的对象数组能不能也用此方法进行排序呢?
首先我们可以新建一个类Hero1,给它定义两个属性:name和price,分别对应王者荣耀中英雄的名字和价格。然后在main函数中定义一个Hero1类型的对象数组heros1,接着调用 Arrays.sort(Object[] o) 方法。
public class Hero1{ private String name; private int price; //省略set,get方法和构造函数 }
Hero1[] heros1 = { new Hero1("成吉思汗",18888),new Hero1("狄仁杰",8888), new Hero1("孙尚香",5888),new Hero1("虞姬",13888) }; Arrays.sort(heros1);//程序运行到这里抛出java.lang.ClassCastException异常 System.out.println(Arrays.toString(heros1));
通过运行程序,我们可以很快发现程序抛出了 java.lang.ClassCastException 异常
那么为什么我们自定义的对象数组不能用sort方法排序呢?通过查看源码和所抛出的异常,可以发现所有使用 sort ( Object [] a)方法进行排序的对象都必须实现Comparable
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {}
在Hero1类中实现Comparable接口,然后重写它唯一的compareTo方法。
public class Hero1 implements Comparable<Hero1>{ private String name; private int price; //省略set,get方法和构造函数 @Override public int compareTo(Hero1 o) { //这里如果不处理系统会抛出空指针异常 if(o == null) { throw new RuntimeException("对象为空!"); } if(this.price > o.price) { return 1; }else if(this.price < o.price) { return -1; } return 0; } }
Hero1类实现Comparable接口后排序正常实现。
Hero1[] heros1 = { new Hero1("成吉思汗",18888),new Hero1("狄仁杰",8888), new Hero1("孙尚香",5888),new Hero1("虞姬",13888) }; Arrays.sort(heros1); System.out.println(Arrays.toString(heros1));//[Hero1 [name=孙尚香, price=5888], Hero1 [name=狄仁杰, price=8888], Hero1 [name=虞姬, price=13888], Hero1 [name=成吉思汗, price=18888]]
Comparable接口要求自定义类主动去实现,但按照面向对象原则, 代码需要对修改关闭,对扩展开发 ,那么在不破坏自定义类结构的前提下,我们是否有方法对类进行排序呢?
答案是肯定的,我们可以新建一个自定义的排序类,这个类实现Comparator接口,然后通过调用Arrays. sort (T[] a, Comparator <? super T> c)方法进行排序。
新建一个Hero2类,属性和Hero1一模一样,但Hero2类没有实现Comparable接口。
public class Hero2{ private String name; private int price; //省略构造函数及set,get方法 }
接着新建一个自定义的排序类,这个类需要实现 Comparator 接口,然后在里面重写compare方法,逻辑和之前一样,但这个函数的入参为两个对象,同样是第一个对象大则返回1,第二个对象大则返回-1,相等返回0。
public class CustomComparator implements Comparator<Hero2>{ @Override public int compare(Hero2 o1, Hero2 o2) { if(o1 == null || o2 == null) { throw new RuntimeException("对象为空!"); } if(o1.getPrice() > o2.getPrice()) { return 1; }else if(o1.getPrice() < o2.getPrice()) { return -1; } return 0; } }
建好自定义的排序类后便可调用Arrays. sort (T[] a, Comparator <? super T> c)方法进行排序。
Hero2[] heros2 = { new Hero2("成吉思汗",18888),new Hero2("狄仁杰",8888), new Hero2("孙尚香",5888),new Hero2("虞姬",13888) }; Arrays.sort(heros2, new CustomComparator()); System.out.println(Arrays.toString(heros2));//[Hero1 [name=孙尚香, price=5888], Hero1 [name=狄仁杰, price=8888], Hero1 [name=虞姬, price=13888], Hero1 [name=成吉思汗, price=18888]]
对象数组排序的讲解就到这了,欢迎大家访问我的专题 编程-Java基础 ,尽管目前文章还比较少,但我会慢慢更新下去的。
Previous
Welcome!