Java基础:Collections.sort的两种⽤法排序详解

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java基础:Collections.sort的两种⽤法排序详解相关的知识,希望对你有一定的参考价值。

文章目录

Collections

sort函数定义

Collections是⼀个⼯具类,sort是其中的静态⽅法,是⽤来对List类型进⾏排序的,它有两种参数形式:

public static <T extends Comparable<? super T>> void sort(List<T> list)  
	list.sort(null);


public static <T> void sort(List<T> list, Comparator<? super T> c)  
	list.sort(c);

基本使用

第一种方法

⾸先使⽤基本类型(此处使⽤Integer)来演示第⼀个⽅法:

static List<Integer> intList = Arrays.asList(2, 3, 1);

private static void sortBaseTypeByDefaultMode() 
    System.out.println("before sort:");
    System.out.println(Arrays.toString(intList.toArray()));
    System.out.println("=========================");
    Collections.sort(intList);
    System.out.println("after sort:");
    System.out.println(Arrays.toString(intList.toArray()));


public static void main(String[] args) 
    leetcode.sortBaseTypeByDefaultMode();

运行结果如下:

第一种方法

可以看到,默认的排序是正序,那么如何实现逆序呢,这就要使⽤第⼆种⽅式了,即通过实现Comparator接⼝的compare⽅法来完成⾃定义排序,代码如下:

static List<Integer> intList = Arrays.asList(2, 3, 1);

private static void sortBaseTypeByIDefineMode() 
    System.out.println("before sort:");
    System.out.println(Arrays.toString(intList.toArray()));
    System.out.println("=========================");
    Collections.sort(intList, new Comparator<Integer>() 
        @Override
        public int compare(Integer o1, Integer o2) 
            // 返回值为int类型,⼤于0表⽰正序,⼩于0表⽰逆序
            return o2 - o1;
        
    );
    System.out.println("after sort:");
    System.out.println(Arrays.toString(intList.toArray()));


public static void main(String[] args) 
// leetcode.sortBaseTypeByDefaultMode();
    leetcode.sortBaseTypeByIDefineMode();

可以看到,已经实现了逆序的排序了。

⾃定义类的排序

接下来看看⾃定义类的排序:
定义⼀个Emp类:

public class Emp 
    private int empno;
    private String ename;

    public int getEmpno() 
        return empno;
    

    public void setEmpno(int empno) 
        this.empno = empno;
    

    public String getEname() 
        return ename;
    

    public void setEname(String ename) 
        this.ename = ename;
    


    public Emp(int empno, String ename) 
        super();
        this.empno = empno;
        this.ename = ename;
    

    @Override
    public String toString() 
        return "empno:\\t" + empno + "\\tename:\\t" + ename;
    

⾸先使⽤同样的⽅式来使⽤Collections.sort⽅法:

定义泛型违Emp类型的List,使⽤sort⽅法的第⼆种形式:

static List<Emp> empList;

static 
    Emp emp1 = new Emp(2, "Guan YunChang");
    Emp emp2 = new Emp(3, "Zhang Fei");
    Emp emp3 = new Emp(1, "Liu Bei");
    empList = Arrays.asList(emp1, emp2, emp3);



private static void sortEmpByIDefineMode() 
    System.out.println("before sort:");
    System.out.println(Arrays.toString(empList.toArray()));
    System.out.println("=========================");
    Collections.sort(empList, new Comparator<Emp>() 

        @Override
        public int compare(Emp o1, Emp o2) 
            /*按员⼯编号正序排序*/
            return o1.getEmpno() - o2.getEmpno();
            /*按员⼯编号逆序排序*/
            //return o2.getEmpno()-o1.getEmpno();
            /*按员⼯姓名正序排序*/
            //return o1.getEname().compareTo(o2.getEname());
            /*按员⼯姓名逆序排序*/
            //return o2.getEname().compareTo(o1.getEname());
        
    );
    System.out.println("after sort:");
    System.out.println(Arrays.toString(empList.toArray()));



public static void main(String[] args) 
//        leetcode.sortBaseTypeByDefaultMode();
//        leetcode.sortBaseTypeByIDefineMode();
    leetcode.sortEmpByIDefineMode();

运行结果如下:

那么使用第一种方式能不能行呢,答案是可以的,但是不是直接的使用sort,例如下面是要报错的:

Collections.sort(empList);

我们需要这样做:⾸先让Emp类继承Comparable接⼝并重写compareTo⽅法(为了和上⾯的排序⽅式区别开,此次按照员⼯姓名逆序排列):


@Override
public int compareTo(Emp emp) 
    /*按员⼯编号正序排序*/
    //return this.getEmpno()-emp.getEmpno();
    /*按员⼯编号逆序排序*/
    //return emp.getEmpno()-this.getEmpno();
    /*按员⼯姓名正序排序*/
    //return this.getEname().compareTo(emp.getEname());
    /*按员⼯姓名逆序排序*/
    return emp.getEname().compareTo(this.getEname());

main函数中调用方法

private static void sortEmpByIDafaultMode() 
    System.out.println("before sort:");
    System.out.println(Arrays.toString(empList.toArray()));
    System.out.println("=========================");
    Collections.sort(empList);
    System.out.println("after sort:");
    System.out.println(Arrays.toString(empList.toArray()));


public static void main(String[] args) 
//        leetcode.sortBaseTypeByDefaultMode();
//        leetcode.sortBaseTypeByIDefineMode();
//        leetcode.sortEmpByIDefineMode();
    leetcode.sortEmpByIDafaultMode();

运行结果如下:

总结:

1.对于String或Integer这些已经实现Comparable接⼝的类来说,可以直接使⽤Collections.sort⽅法传⼊list参数来实现默认⽅式(正序)排序;
2.如果不想使⽤默认⽅式(正序)排序,可以通过Collections.sort传⼊第⼆个参数类型为Comparator来⾃定义排序规则;
3.对于⾃定义类型(如本例⼦中的Emp),如果想使⽤Collections.sort的⽅式⼀进⾏排序,可以通过实现Comparable接⼝的compareTo⽅法来进⾏,如果不实现,则参考第2点;

4.jdk1.8的Comparator接⼝有很多新增⽅法,其中有个⽅法⽐较实⽤,是⽤来切换正序和逆序的:reversed(),代码如下:

private static void sortEmpByIDefineMode() 
    System.out.println("before sort:");
    System.out.println(Arrays.toString(empList.toArray()));
    System.out.println("=========================");
    Comparator<Emp> comparator = new Comparator<Emp>() 
        @Override
        public int compare(Emp o1, Emp o2) 
            /*按员⼯编号正序排序*/
            return o1.getEmpno() - o2.getEmpno();
            /*按员⼯编号逆序排序*/
            //return o2.getEmpno()-o1.getEmpno();
            /*按员⼯姓名正序排序*/
            //return o1.getEname().compareTo(o2.getEname());
            /*按员⼯姓名逆序排序*/
            //return o2.getEname().compareTo(o1.getEname());
        

    ;

    /* 新 的 逆 序 实 现 ⽅ 式 */
    Collections.sort(empList, comparator.reversed());
    System.out.println("after sort:");
    System.out.println(Arrays.toString(empList.toArray()));

复写的compare⽅法定义的是按员⼯编号正序排序,在使⽤reversed翻转后结果如下:

Comparator是个接⼝,可重写compare()及equals()这两个⽅法,⽤于⽐价功能;如果是null的话,就是使⽤元素的默认顺序,如a,b,c,d,e,f,g,就是a,b,c,d,e,f,g这样,当然数字也是这样的。

compare(a,b)⽅法:根据第⼀个参数⼩于、等于或⼤于第⼆个参数分别返回负整数、零或正整数。
equals(obj)⽅法:仅当指定的对象也是⼀个 Comparator,并且强⾏实施与此 Comparator 相同的排序时才返回 true。

Collections.sort(list, new PriceComparator());的第⼆个参数返回⼀个int型的值,就相当于⼀个标志,告诉sort⽅法按什么顺序来对list进⾏排序。

具体实现代码⽅法如下:

package com.leetcode.www;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.TreeMap;

/**
 * 书实体类
 *
 * @author yjd
 */
public class Book implements Comparable  // 定义名为Book的类,默认继承⾃Object类

    public int id;// 编号
    public String name;// 名称
    public double price; // 价格
    private String author;// 作者
    public GregorianCalendar calendar;// 出版⽇期

    public Book() 
        this(0, "X", 0.0, new GregorianCalendar(), "");
    


    public Book(int id, String name, double price, GregorianCalendar calender, String author) 
        this.id = id;
        this.name = name;
        this.price = price;
        this.calendar = calender;
        this.author = author;
    

    // 重写继承⾃⽗类Object的⽅法,满⾜Book类信息描述的要求
    public String toString() 
        String showStr = id + "\\t" + name; // 定义显⽰类信息的字符串
        DecimalFormat formatPrice = new DecimalFormat("0.00");// 格式化价格到⼩数点后两位
        showStr += "\\t" + formatPrice.format(price);// 格式化价格
        showStr += "\\t" + author;
        SimpleDateFormat formatDate = new SimpleDateFormat("yyyy年MM⽉dd⽇");
        showStr += "\\t" + formatDate.format(calendar.getTime()); // 格式化时间
        return showStr; // 返回类信息字符串
    

    public int compareTo(Object obj) 
        // Comparable接⼝中的⽅法
        Book b = (Book) obj;
        return this.id - b.id; // 按书的id⽐较⼤⼩,⽤于默认排序
    


    public static void main(String[] args) 
        Book b1 = new Book(10000, "红楼梦", 150.86, new GregorianCalendar(2009, 01, 25), "曹雪芹、⾼鄂");
        Book b2 = new Book(10001, "三国演义", 99.68, new GregorianCalendar(2008, 7, 8), "罗贯中 ");
        Book b3 = new Book(10002, "⽔浒传", 100.8, new GregorianCalendar(2009, 6, 28), "施耐庵 ");
        Book b4 = new Book(10003, "西游记", 120.8, new GregorianCalendar(2011, 6, 8), "吴承恩");
        Book b5 = new Book(10004, "天龙⼋部", 10.4, new GregorianCalendar(2011, 9, 23), "搜狐");
        TreeMap tm = new TreeMap();
        tm.put(b1, new Integer(255));
        tm.put(b2, new Integer(122));
        tm.put(b3, new Integer(688));
        tm.put(b4, new Integer(453));
        tm.put(b5, new Integer(40));
        Iterator it = tm.keySet().iterator();
        Object key = null, value = null;
        Book bb = null;
        while (it.hasNext()) 
            key = it.next();
            bb = (Book) key;
            value = tm.get(key);
            System.out.println(bb.toString() + "\\t库存:" + tm.get(key));
        
    

⾃定义⽐较器和测试类:

package com.leetcode.www;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;


public class UseComparator 
    public static void main(String args[]) 
        List<Book> list = new ArrayList<Book>(); // 数组序列
        Book b1 = new Book(10000, "红楼梦", 150.86, new 

以上是关于Java基础:Collections.sort的两种⽤法排序详解的主要内容,如果未能解决你的问题,请参考以下文章

java list排序的两种方式(实现Comparable接口和Collections.sort重载方法)

Collections.sort的两种用法 转

java集合进行排序的两种方式

39-java中Arrays.sort 和 collections.sort()总结

java基础总结4

Java:Collections.sort和Arrays.sort的区别