美文网首页码农的世界程序员
对象数组如何排序-Comparable接口详解

对象数组如何排序-Comparable接口详解

作者: 码农先生 | 来源:发表于2019-03-02 15:44 被阅读10次

    1 普通数组使用Arrays.sort方法排序

    在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<T>接口。我们通过查看String的源码也可以观察到String类也实现了Comparable<T>接口。

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {}
    

    2 自定义对象排序通过实现Comparable接口进行排序

    在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]]
    

    3 自定义类不实现Comparable接口也有办法进行排序

    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基础,尽管目前文章还比较少,但我会慢慢更新下去的。

    相关文章

      网友评论

        本文标题:对象数组如何排序-Comparable接口详解

        本文链接:https://www.haomeiwen.com/subject/kjveuqtx.html