Java-对象排序

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

Collections.sort(l);

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

Classes Implementing Comparable
Class Natural 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
 
时间: 2024-10-07 01:35:03

Java-对象排序的相关文章

Java对象排序小测试

import java.util.ArrayList; import java.util.Collections; import java.util.List; /**  * Java对象排序  */ public class User implements Comparable<User> {     private int idx;     public User(int idx) {         this.idx = idx;     }     public int getIdx(

利用Apache的commons-beanutils和commons-collections包实现Java对象的按属性排序

在日常工作中经常用到需要对java对象集合或者Map集合中的某个属性做排序,这个需求可以利用Apache的commons-beanutils和commons-collections包来实现,主要实现方式如下: public static <T> void sort(List<T> list, String property, boolean asc) { Comparator<?> comparator = ComparableComparator.getInstanc

Java对象比较器对泛型List进行排序-Demo

针对形如:字段1 字段2 字段3 字段n 1 hello 26 7891 world 89 5562 what 55 4562 the 85 452 fuck 55 995 haha 98 455 以上类型的查询数据结果,需要对 字段3 进行求和分组(在SQL查询无法一次性完成的情况下,通常采用Java分组排序),大概思路如下: 1.在Bean中添加相关的分组标记字段,对求和或者其它统计的结果进行插入分组标记,下面demo中为bigIdOrder标记 2.对完成标记的List进行标记的补全 3.

Java集合中对象排序

集合中的对象排序需求还是比较常见的,当然我们可以重写equals方法,循环比较:同时Java为我们提供了更易使用的APIs.当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序. 下面通过两个例子分别用Comparable和Comparator实现对User对象中年龄排序. Comparable接口方式 类自身实现Comparable接口,实现该接口中的compareTo方法. import java.util.A

Java comparable接口 对象排序

前面写了一篇文章是关于comparator的,那么comparable就必须拿出来做了分析对比. 关于这俩个接口的文章也比较多,本文着重从完整的代码示例去展现说明. OK 首先,还是看下Comparator这里接口的代码: public interface Comparable<T> { /** * Compares this object with the specified object for order. Returns a * negative integer, zero, or a

装箱/拆箱 对象排序

package one; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import j

XML编程总结(六)——使用JAXB进行java对象和xml格式之间的相互转换

(六)使用JAXB进行java对象和xml格式之间的相互转换 JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标志可以转换为JSON对象的JAVA类. JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术.该过程中,JAXB也提供了将XML实例文档反向生成Java对象树

List对象排序的通用方法

转自 @author chenchuang import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Collections;import java.util.Comparator;import java.util.List; /**  * List对象排序的通用方法  *   * @author chenchuang  *   * @param <E>

List对象排序通用方法

在数据库中查出来的列表list中,往往需要对不同的字段重新排序,一般的做法都是使用排序的字段,重新到数据库中查询.如果不到数据库查询,直接在第一次查出来的list中排序,无疑会提高系统的性能. 只要把第一次查出来的结果存放在session中,就可以对list重新排序了.一般对list排序可以使用Collections.sort(list),但如果list中包含是一个对象的话,这种方法还是行不通的.那要怎么排序呢?如果有一个UserInfo对象,包含如下字段: private java.lang.

java之j2se:再学java对象容器

今天是开学第一天,按照上学期的讲课进度,本该是可以开始学习多线程了,但是由于换了老师,可能交接方面有点出入,又给我们讲授了一遍java对象容器,所以这也是为什么题目为"再学". 本文目录: 集合的主要用途 单值类集合:List类与Set类 键值对类集合:Map类 集合的主要用途:集合主要在查询数据返回的时候常用.比如要使用jsp做一个学生信息管理系统,需要从数据库中返回查询学生的结果,把这些结果放入一个集合里,再通过方法返回,在显示层(view)可以使用jsp标签来把他们显示出来. 单