• Java如何设计自定义排序器


    在使用Java无序集合时,经常需要对集合进行排序,此时需要我们自己去实现排序逻辑。接下来就以TreeSet为例来看看如何对集合进行排序。

    TreeSet对元素排序有两种方式:

    • 第一种:复写Comparable接口的compareTo方法。
    • 第二种:采用自定义Comparator比较器

    场景:对象Person包含姓名name和年龄age两个属性,按照年龄进行升序排序,如果年龄一致,则按照姓名升序排序。

    一、复写Comparable接口的compareTo方法

    让元素自身具备比较功能,元素就需要实现comparable接口,覆盖compareTo方法。

    代码如下:

    class Person implements Comparable{
    
        private String name;
        private int age;
    
        // 重写toString()方法,输出对象时输出格式为:name:age
        @Override
        public String toString() {
            return name+ ":" + age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        @Override
        public int compareTo(Object o) {
            Person p = (Person) o;
    
            // 根据年龄升序排序
          int temp = this.age - p.age;
          return temp == 0 ? this.name.compareTo(p.name):temp;
        }
    }

    测试:

    public class TreeSetDemo {
        public static void main(String[] args) {
            TreeSet<Person> ts = new TreeSet();
            ts.add(new Person("zhangsan", 20));
            ts.add(new Person("lisi", 20));
            ts.add(new Person("wangwu", 21));
            ts.add(new Person("zhouqi", 29));
            ts.add(new Person("zhaoliu", 28));
    
            for (Person person : ts) {
                System.out.println(person);
            }
        }
    }

    结果输出:

    lisi:20
    zhangsan:20
    wangwu:21
    zhaoliu:28
    zhouqi:29

    但是如果不要按照对象中具备的自然顺序进行排序,即对象中不具备自然顺序该如何处理呢?就需要采用下面的第二种方式。

     二、采用自定义Comparator比较器

    让集合自身具备比较功能,即在集合对象创建时,由此想到TreeSet的构造方法: new TreeSet(Comparator<? super E> comparator)。为此需要定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeSet集合的构造函数。

    代码如下:

    PersonNoComparator类不用复写Comparable接口的compareTo方法。

    class PersonNoComparator {
    
        private String name;
        private int age;
    
        @Override
        public String toString() {
            return name+":" + age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
        public PersonNoComparator(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    }

    设计自定义排序器,并复写compare方法。

    class ComparatorByAge implements Comparator {
    
        // 根据年龄升序排序
        @Override
        public int compare(Object o1, Object o2) {
            Person p1 = (Person) o1;
            Person p2 = (Person) o2;
    
            int tmp = p1.getAge() - p2.getAge();
            return tmp == 0 ? p1.getName().compareTo(p2.getName()) : tmp;
        }
    }

    测试:

    与第一种方式测试不同的地方是,在构造TreeSet方法时直接按照ComparatorByAge排序器排序。

    public class TreeSetDemo {
        public static void main(String[] args) {
            ts = new TreeSet(new ComparatorByAge());
            ts.add(new Person("zhangsan", 20));
            ts.add(new Person("lisi", 20));
            ts.add(new Person("wangwu", 21));
            ts.add(new Person("zhouqi", 29));
            ts.add(new Person("zhaoliu", 28));
    
            for (Person person : ts) {
                System.out.println(person);
            }
        }
    }

    结果输出:

    lisi:20
    zhangsan:20
    wangwu:21
    zhaoliu:28
    zhouqi:29
    可以发现,两种方式实现的排序结果是一致的。
     
    【参考资料】
  • 相关阅读:
    彻底卸载MySql
    MySql和SQL Server数据类型 对比
    easyui combobox 中实现 checkbox
    浅谈研发项目经理
    软件公司项目经理岗位职责
    input text 的事件及方法
    c#解析HTML
    SQL SERVER 数据库查询表和字段信息语句
    Silverlight动态载入调用XAML资源
    几种设计模式简介(转载)
  • 原文地址:https://www.cnblogs.com/lemonu/p/12975418.html
Copyright © 2020-2023  润新知