• 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
     
  • 相关阅读:
    Collections与Arrays
    TreeMap
    HashMap
    单列集合的体系
    泛型的上下限
    09年最受关注的十大Visual Studio插件
    编码中的硬回车与软回车
    无法打开包括文件:'atlrx.h'的解决办法[原]
    【转】Notepad++,Eclipse和Visual Studio 2005常用快捷键对比
    【转】printf格式控制(你所不知道的printf妙用)
  • 原文地址:https://www.cnblogs.com/pzy4447/p/5024385.html
Copyright © 2020-2023  润新知