• Java-对象排序


    在业务逻辑中,我们经常需要对list进行排序,就像下面这样:

    Collections.sort(l);

    如果l中的元素是String类型,你会发现sort方法将使用字母顺序排序。如果l中的元素是Date类型,sort方法将使用日历顺序排序。这是因为String和Date都实现了Comparable接口,也就是说,如果你想对某种对象进行排序,那么它必须实现Comparable接口。在Java语言中,实现该接口的类罗列如下:

    Classes Implementing Comparable
    ClassNatural Ordering
    Byte Signed numerical
    Character Unsigned numerical
    Long Signed numerical
    Integer Signed numerical
    Short Signed numerical
    Double Signed numerical
    Float Signed numerical
    BigInteger Signed numerical
    BigDecimal Signed numerical
    Boolean Boolean.FALSE < Boolean.TRUE
    File System-dependent lexicographic on path name
    String Lexicographic
    Date Chronological
    CollationKey Locale-specific lexicographic

    如果某个类是别人写的,它确实没有实现该接口,那就对排序问题无能为力了么?不是的,sort还有另一种形式:

    Collections.sort(list, comparator)
    只有这两种方法。如果以上两种方法你都没有做,那么sort方法将抛出异常。 
    Comparable接口
    Comparable接口形式如下:
    public interface Comparable<T> {
        public int compareTo(T o);
    }
    是的,它只有一个方法。你必须在该方法中定义对象是如何比较的。下面是一个demo:
    SortDemo.java
    package Colloections;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class SortDemo {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            new SortDemo().sort();
        }   private void sort(){
            Person p1 = new Person("bob", 5);
            Person p2 = new Person("albert", 8);
            Person p3 = new Person("bob", 13);
            
            List<Person> list = new ArrayList<Person>();
            list.add(p1);
            list.add(p2);
            list.add(p3);
            System.out.printf("排序前:%n");
            for (Person person : list) {
                System.out.printf(person.toString());
            }
            
            Collections.sort(list);
            System.out.printf("排序后:%n");
            for (Person person : list) {
                System.out.printf(person.toString());
            }
        }
    }
    
    
    class Person implements Comparable<Person>{
    
        public String name;
        public int age;
        
        public Person(String n, int a){
            name = n;
            age = a;
        }
        
        public  String toString() {
            return String.format("Name is %s, Age is %d%n", name, age);
        }
        
        @Override
        public int compareTo(Person o) {
            // TODO Auto-generated method stub
            //排序优先级为:姓名/年龄
            int nameComp = this.name.compareTo(o.name);
            return (nameComp != 0 ? nameComp : (this.age - o.age));
        }
    }

    程序输出如下:

    排序前:
    Name is bob, Age is 5
    Name is albert, Age is 8
    Name is bob, Age is 13
    排序后:
    Name is albert, Age is 8
    Name is bob, Age is 5
    Name is bob, Age is 13

    Comparator

    Comparator接口提供一个独立的排序功能,这有两个用处:1.你不想使用某个类自带的compareTo逻辑进行排序;2.某个类并没有继承Comparable接口。可见,Comparator接口使得排序更加灵活。它的形式如下所示:
    public interface Comparator<T> {
        int compare(T o1, T o2);
    }

    是的,一个方法就够了。当o1比o2小于,等于,大于时,compare方法将返回一个负数,零或者正数。使用demo如下:

    SortDemo.java

    package Colloections;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class SortDemo {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //new SortDemo().sort();
            new SortDemo().sortByComparatpr();
        }
        
        private void sortByComparatpr(){
            Person p1 = new Person("bob", 5);
            Person p2 = new Person("albert", 8);
            Person p3 = new Person("bob", 13);
            
            List<Person> list = new ArrayList<Person>();
            list.add(p1);
            list.add(p2);
            list.add(p3);
            System.out.printf("排序前:%n");
            for (Person person : list) {
                System.out.printf(person.toString());
            }
            
            PersonComparator comparator = new PersonComparator();
            Collections.sort(list, comparator);
            System.out.printf("排序后:%n");
            for (Person person : list) {
                System.out.printf(person.toString());
            }
        }
        
        private void sort(){
            Person p1 = new Person("bob", 5);
            Person p2 = new Person("albert", 8);
            Person p3 = new Person("bob", 13);
            
            List<Person> list = new ArrayList<Person>();
            list.add(p1);
            list.add(p2);
            list.add(p3);
            System.out.printf("排序前:%n");
            for (Person person : list) {
                System.out.printf(person.toString());
            }
            
            Collections.sort(list);
            System.out.printf("排序后:%n");
            for (Person person : list) {
                System.out.printf(person.toString());
            }
        }
    }
    
    
    class Person implements Comparable<Person>{
    
        public String name;
        public int age;
        
        public Person(String n, int a){
            name = n;
            age = a;
        }
        
        public  String toString() {
            return String.format("Name is %s, Age is %d%n", name, age);
        }
        
        @Override
        public int compareTo(Person o) {
            // TODO Auto-generated method stub
            //排序优先级为:姓名/年龄
            int nameComp = this.name.compareTo(o.name);
            return (nameComp != 0 ? nameComp : (this.age - o.age));
        }
    }
    
    
    
    class PersonComparator implements Comparator<Person>{
    
        @Override
        public int compare(Person o1, Person o2) {
            // TODO Auto-generated method stub
            
            return o2.compareTo(o1);
        }
    }

    程序输出如下:

    排序前:
    Name is bob, Age is 5
    Name is albert, Age is 8
    Name is bob, Age is 13
    排序后:
    Name is bob, Age is 13
    Name is bob, Age is 5
    Name is albert, Age is 8

    注意,这里的输出是降序排列的,因为在compare方法中使用o2与o1进行了比较。如果需要升序排列,则如下修改即可:

    return o1.compareTo(o2);

    注意,不要这样修改:

    return -o2.compareTo(o1);

    这是因为compareTo返回的负数值是不确定的,而有一个特殊的负整数,取负时结果仍为负数:

    -Integer.MIN_VALUE == Integer.MIN_VALUE
     
  • 相关阅读:
    eclipse无法打断点,提示debug absent line number information
    jQueryValidator 验证非负数
    Oracle 11g中递归查询父类及子类集合
    修改上传功能时遇到的问题
    使用Tomcat页面乱码问题
    javaScript正则匹配汉字与特殊字符(项目中遇到关键字匹配的方法)
    Oracle 11g中字符串截取的实现
    软连接和硬连接区别 Alex
    Linux发行版的系统目录名称命名规则以及用途 Alex
    如何通过脚本实现显示版本号、CPU、硬盘和内存条大小 Alex
  • 原文地址:https://www.cnblogs.com/pzy4447/p/5024385.html
Copyright © 2020-2023  润新知