ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Comparable接口实现(当需要对某个对象进行排序时)

2021-07-08 20:34:56  阅读:117  来源: 互联网

标签:sort Comparable return name int 接口 id 排序 public


Comparable接口实现(当需要对某个对象进行排序时)

如标题所说,当你需要对某个自定义类进行排序时,你就需要实现Comparable接口。
反过来说,当一个类实现了Comparable接口时,就表明它的实例具有内在的排序关系。

Java平台类库中所有的值类(Integer, Short....),以及所有的枚举类型都实现了Comparable接口。

接下来我们先看一下应该怎么实现这个接口,以及应该怎么使用它:

类对象(第一种实现方式)

public class DemoComparable implements Comparable<DemoComparable>{

    private int id;

    private String name;

    private int sort;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSort() {
        return sort;
    }

    public void setSort(int sort) {
        this.sort = sort;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DemoComparable that = (DemoComparable) o;
        return id == that.id &&
                sort == that.sort &&
                Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, sort);
    }

    @Override
    public String toString() {
        return "DemoComparable{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sort=" + sort +
                '}';
    }

    @Override
    public int compareTo(DemoComparable o){
        if (o == null){
            throw new NullPointerException();
        }
        // 初始化result对象
        int result = 0;
        // 比较sort属性
        result = Integer.compare(sort, o.getSort());
        // 如果相同则继续比较下一属性,不相等则返回比较结果
        if (result != 0){
            return result;
        }
        // 比较id属性
        result = Integer.compare(id, o.getId());
        // 如果相同则继续比较下一属性,不相等则返回比较结果
        if (result != 0){
            return result;
        }

        return result;
    }
}

数组排序

public class MainTest {

    public static void main(String[] args) {
        /**
         * 生成对象的随机数组
         */
        DemoComparable[] array = new DemoComparable[100];
       for (int i = 0; i < 100; i++){
           DemoComparable var = new DemoComparable();
           // 获取随机数
           Random random = new Random();
           int rd = random.nextInt();
           var.setId(rd);
           var.setName("name"+rd);
           var.setSort(rd);
           array[i] = var;
       }
       // 排序
        Arrays.sort(array);
       // 输出结果
       for (int i = 0; i < array.length; i++){
           System.out.println(array[i].toString());
       }
    }
}

list排序

public class MainTest {

    public static void main(String[] args) {
        /**
         * 生成对象的随机集合
         */
        List<DemoComparable> array = new ArrayList<>();
        for (int i = 0; i < 100; i++){
            DemoComparable var = new DemoComparable();
            // 获取随机数
            Random random = new Random();
            int rd = random.nextInt();
            var.setId(rd);
            var.setName("name"+rd);
            var.setSort(rd);
            array.add(var);
        }
        // 排序
        Collections.sort(array);
        // 输出结果
        for (int i = 0; i < array.size(); i++){
            System.out.println(array.get(i).toString());
        }
    }
}

当我们实现Comparable接口时要注意:

  1. 在compareTo方法中使用关系操作符 < 和 > 是非常繁琐的,并且容易出错,因此不建议使用。
  2. 如果一个类有多个属性需要进行排序,那么按照什么样的顺序来进行排序是非常关键的,我们需要从最关键的属性开始。
  3. compareTo方法的结果应该尽量与equals方法的结果保持一致,即当a.compareTo(b)等于0时,a和b的equals方法返回的结果应该是true。当然,如果他们不一致的话也不会产生灾难性的后果,但是如果在一个有序集合中包含了该类的元素,这个集合就可能无法遵守相应集合接口(Collection,Set,Map)的通用约定。因为这些接口的通用约定是按照equals方法来定义的,但有序集合使用了由compareTo方法而不是equals方法所施加的等同性测试。

接下来我们介绍一下对象类的第二种实现方式,性能损耗上要比第一种更大一些:

public class DemoComparable1 implements Comparable<DemoComparable1>{

    /**
     * 构建静态比较器,性能损耗相较于上一种方式大约10%
     */
    private static final Comparator<DemoComparable1> COMPARATOR =
            Comparator.comparingInt((DemoComparable1 dc) -> dc.id)
            .thenComparingInt(dc -> dc.sort);

    /**
     * 比较方法实现
     */
    @Override
    public int compareTo(DemoComparable1 o) {
        return COMPARATOR.compare(this, o);
    }

    private int id;

    private String name;

    private int sort;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSort() {
        return sort;
    }

    public void setSort(int sort) {
        this.sort = sort;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DemoComparable1 that = (DemoComparable1) o;
        return id == that.id &&
                sort == that.sort &&
                Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, sort);
    }

    @Override
    public String toString() {
        return "DemoComparable1{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sort=" + sort +
                '}';
    }
}

其排序方式与第一种实现方式是一样的。

后一种方式中,Comparable类具备全套的构造方法。对于基本类型long和double都有对应的comparingInt和thenComparingInt。int版本也可以用更狭义的整数型类型,如Short。Double版本也可以用float。这样便覆盖了所有Java数字型基本类型。

标签:sort,Comparable,return,name,int,接口,id,排序,public
来源: https://www.cnblogs.com/SweetCode/p/14988027.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有