• java对象比较排序


    参考:改善java代码的151个建议-73建议:使用Compatator排序

      在项目开发中,我们经常要对一组数据排序,或者升序或者降序,在java中排序有多种方式,最土的方法就是自己写排序算法,比如冒泡排序,快速排序,二叉树排序等,但一般不要自己写,jdk已经为我们提供了很多的 排序算法,我们采用拿来主义就成了。

    在java中,要给数据排序,有两种实现方式,分别实现两个接口:

    1. 一种是实现Comparable接口
    2. 另一种是实现Comparator接口

      在JDK类库中,有一部分类实现了Comparable接口,如Integer Double和String等。 
     Comparable接口有一个comparTo(Object o)方法,它返回整数类型。对于表达式x.compareTo(y),如果返回值为0,则表示x和y相等,如果返回值大于0,则表示x大于y,如果返回值小于0,则表示x小于y.

        查看Comparable接口源码

    public interface Comparable<T> {
        public int compareTo(T o);
    }

     举个例子:

          给公司职员排序,按照工号排序,先定义一个职员类

    编写Employee类实现Comparable接口

    package hello;
    
    import org.apache.commons.lang3.builder.CompareToBuilder;
    import org.apache.commons.lang3.builder.ToStringBuilder;
    
    
    public class Employee implements Comparable<Employee>{
        //id是根据进入公司的先后顺序编码的
        private int id;
        //姓名
        private String name;
        //职位
        private Position position;
        public Employee(int id, String name, Position position) {
            super();
            this.id = id;
            this.name = name;
            this.position = position;
        }
        //按照id号排序,也就是资历的深浅排序
        @Override
        public int compareTo(Employee o) {
            // TODO Auto-generated method stub
            return new CompareToBuilder().append(id, o.id).toComparison();
        }
        @Override
        public String toString(){
             return ToStringBuilder.reflectionToString(this);
        }
        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 Position getPosition() {
            return position;
        }
    
        public void setPosition(Position position) {
            this.position = position;
        }
    
    }

         这是一个简单的javabean,描述的是一个员工的基本信息,其中id是员工编号,按照进入公司的先后顺序编码,position是岗位描述,表示是经理还是普通职员,这是一个枚举类型:

    public enum Position {
      Boss, Manager,staff
    }

       职位有三个级别:

      Boss(老板), Manager(经理), Staff(职员)

    • 按id排序

    Employee类的compareTo()方法,是Comparable接口必须要实现的方法,使用apach的工具类来实现,表明是按照id的自然序列排序的(升序)。一切准备完毕,我们看看如何排序:

    package hello;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class HelloWord {
    
        public static void main(String[] args) {
            List<Employee> list = new ArrayList<Employee>(5);
            // 一个老板
            list.add(new Employee(1001, "张三", Position.Boss));
            // 两个经理
            list.add(new Employee(1006, "赵四", Position.Manager));
            list.add(new Employee(1003, "王五", Position.Manager));
            // 两个职员
            list.add(new Employee(10002, "李六", Position.staff));
            list.add(new Employee(1005, "马牛", Position.staff));
            // 按照id排序,也就是按照资历深浅排序
            Collections.sort(list);
            for (Employee e : list) {
                System.out.println(e);
            }
        }
    }

    【运行结果】:

    hello.Employee@46244bb9[id=1001,name=张三,position=Boss]
    hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
    hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
    hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
    hello.Employee@6909037d[id=10002,name=李六,position=staff]

    是按照id升序排列的,结果正确。

    • 按职位排序

    本着“领导为先”的理念,按职位从高到低排序,先是老板,然后是经理,最后是普通职员,Employee已经是一个稳定类,为了一个排序功能修改它,影响按照id排序,不是一个好办法。

    Collections.sort()方法有一个重载方法sort(List<T> list, Comparator<? super T> c),有一个Comparator接口参数,我们实现这个接口:

    //职位排序器
    class PositionComparator implements Comparator<Employee>{
        @Override
        public int compare(Employee o1, Employee o2) {
            //按照职位降序排列
            return o1.getPosition().compareTo(o2.getPosition());
        }

    创建了一个职位排序法,按职位高低排序,测试一下:

            Collections.sort(list, new PositionComparator());
            for (Employee e : list) {
                System.out.println(e);
            }

    【运行结果】:

    hello.Employee@46244bb9[id=1001,name=张三,position=Boss]
    hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
    hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
    hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
    hello.Employee@6909037d[id=10002,name=李六,position=staff]

     按照职位排序,结果正确。

    • 按照职位从低到高排序

     为了照顾员工,需要按职位由低到高排序

    两个办法:

    1. Collections.reverse(List<?> list)方法实现倒序排列
    2. Collections.sort(List<?> list,Collections.reverseOrder(new PositionComparator())也可以

    用这两个方法来测试:

            Collections.reverse(list);
            for (Employee e : list) {
                System.out.println(e);
            }
    
            System.out.println("----");
            Collections.sort(list,
                    Collections.reverseOrder(new PositionComparator()));
            for (Employee e : list) {
                System.out.println(e);
            }

    【运行结果】:

    hello.Employee@6909037d[id=10002,name=李六,position=staff]
    hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
    hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
    hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
    hello.Employee@46244bb9[id=1001,name=张三,position=Boss]
    ----
    hello.Employee@6909037d[id=10002,name=李六,position=staff]
    hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
    hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
    hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
    hello.Employee@46244bb9[id=1001,name=张三,position=Boss]

    按照职位由地到高排序,结果正确

    •  先按职位排序,职位 相同按id排序

    在compareTo或compare方法中先判断职位是否相等,职位相等再根据工号排序

    修改Employee类的compareTo()方法为

        @Override
        public int compareTo(Employee o) {
            return new CompareToBuilder()
                .append(position, o.position)    //按照职位排序
                .append(o.id,id).toComparison(); //工号排序
        }

    排序代码:

            Collections.sort(list);
            for (Employee e : list) {
                System.out.println(e);
            }

    【运行结果】:

    hello.Employee@4d871a69[id=1001,name=张三,position=Boss]
    hello.Employee@631803fb[id=1006,name=赵四,position=Manager]
    hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
    hello.Employee@655538e5[id=1005,name=马牛,position=staff]
    hello.Employee@20e0b1d6[id=1002,name=李六,position=staff]

    总结:

    1.  实现了Comparable接口类表明自身可比较,有了比较才能进行排序;
    2. Comparator接口是一个工具类接口,用作比较,与原类的逻辑没有关系;
  • 相关阅读:
    第二次
    第一次
    win下less自动编译脚本
    厦门攻略游记
    npm常用命令
    青岛旅行规划及玩后感
    kissynode run on windows解决方案,contextify nodejs windows solution
    win nodejs下 findit只返回第一个文件问题
    jetty自动添加path的问题
    微博输入框统计
  • 原文地址:https://www.cnblogs.com/xiaobijia/p/5606197.html
Copyright © 2020-2023  润新知