Java(3)--Collections排序(Comparable和Comparator接口的实现)

前言

  • 包装类Collections的排序方法可以运用到各种集合框架,非常方便
  • 分析看不懂请结合程序示例看
  • 有问题欢迎评论或者私信!!!

接口分析

Comparable接口

  • Comparable接口在 java.lang.Comparable 包下

  • Comparable接口的实现方法:public int compareTo(T t);

  • Comparable接口是在集合的(类的)内部实现的排序方式,调用的实质 t1.compareTo(t2);

  • 在排序对象本身支持相互比较所需要的接口(如Integer、String、Double、Float等)时,可以直接调用 Collections.sort() 方法的Comparable接口(参考程序示例)

  • 当数值或ASCII码值从小到大的默认顺序或者排序的根据对象不满足程序需求时,可以重写compareTo方法(参考程序示例)

Comparator接口

  • Comparator接口在 java.util.Comparator 包下

  • Comparator接口的实现方法:public int compare(T t1, T t2);

  • Comparator接口是在集合的(类的)外部实现的排序方式,需要用到一个比较容器调用的实质是 compare(t1 , t2);(参考程序示例)

  • 在排序对象本身不支持相互比较所需要的接口,例如对整数采用绝对值大小排序,显然对象本身的Integer自然排序是不能实现的,同时如果Integer类也不容许你在它的内部重写compareTo()去改变它的排序行为,所以就可以用到Comparator接口(参考程序示例)

compareTo和compare方法

  • Comparable接口的实现方法:public int compareTo(T t),调用的实质 t1.compareTo(t2);

    在方法内部返回一个运算结果,例如返回:t1.x - t2.x,则按从小到大的顺序排序

    若返回:t2.x - t1.x,则按从大到小的顺序排序

  • Comparator接口的实现方法:public int compare(T t1, T t2),调用的实质是 compare(t1 , t2);

    在方法内部返回一个运算结果,例如返回:t1.x - t2.x,则按从小到大的顺序排序

    若返回:t2.x - t1.x,则按从大到小的顺序排序

  • compareTo默认的调用可以实现字符串的比较,比较方法:先比较第一个字符,不同则返回ASCII码的差值,若第一个字符相同,则比较第二个字符,若前面字符相同则比较长度。

    例如:

    String a = 'abc';
    String b = 'cde';
    String c = 'abcde';
    int d = a.compareTo(b);
    int e = a.compareTo(c);
    

​ 返回d = -2,由a的ASCII码值减去b的ASCII码值得来。e = -2,因为前字符相同,a.length() - c.length() = -2.

相关之处

  • 对于一个对象的排序,既可以用Comparable接口实现,也能用Comparator接口实现,只是两种排序的实现方式不同,

  • 在某些情况的排序下,可以用Comparator接口,在接口的compare方法中再次调用compareTo方法进行比较。例如如下情况:

    输入学生的学号、姓名、班级、成绩,分别根据这四个数据进行排序。

​ 对学号的排序,可以调用Comparable接口重写comparaTo方法按学号从小到大排序

​ 对姓名的排序,可以实现一个比较容器,在容器中重写compare方法,在compare方法中调用compareTo方法实现对字符串的比较,然后返回对字符串的比较结果。

class NameUPComparator implements java.util.Comparator {
    public int compare(Object o1, Object o2) {
        Student s1 = (Student)o1;// 转化成当前类型的对象
        Student s2 = (Student)o2;
        return s1.getName().compareTo(s2.getName());
    }
}

在调用sort方法时,则要通过:

Collections.sort(studentList,new NameUPComparator());

程序示例

调用默认的Comparable接口

import java.util.ArrayList;
import java.util.Collections;

public class CompObj {

    public String toString() {
        return "[x = " + x + "]";
    }

    public static void main(String[] args) {
        ArrayList<Integer> al = new ArrayList<Integer>();// 单一Integer数据的ArrayList,有本身支持比较的接口Integer
        al.add(3);
        al.add(1);
        al.add(2);
        System.out.println("Before sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
        Collections.sort(al); // 调用Collections的sort方法-静态方法
        System.out.println("After sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
    }
}

在这里插入图片描述

调用重写compareTo方法的Comparable接口

根据x值排序

import java.util.ArrayList;
import java.util.Collections;

public class CompObj implements java.lang.Comparable { // 定义要排序的类

    int x;
    int y;

    public CompObj(int n1, int n2) {
        x = n1;
        y = n2;
    }

    public String toString() {
        return "[x = " + x + ", y = " + y + "]";
    }

    public int compareTo(Object o) {
        CompObj co = (CompObj) o;
        if (this.x != co.x) {
            return this.x - co.x;
        } else {
            return this.y - co.y;
        }
    }

    public static void main(String[] args) {
        ArrayList<CompObj> al = new ArrayList<CompObj>();
        al.add(new CompObj(3, 1));
        al.add(new CompObj(1, 3));
        al.add(new CompObj(2, 2));
        al.add(new CompObj(2, 1));
        System.out.println("Before sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
        Collections.sort(al); // 调用Collections的sort方法-静态方法
        System.out.println("After sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
    }

}

在这里插入图片描述

注意事项

  • compareTo()方法的形参为Object类的对象,在比较之前要进行类型转换成为CompObj类的对象

  • 在重写的compareTo方法中,若俩对象的x值相同,则比较y值

  • 若改为

    if (this.x != co.x) {
                return co.x - this.x;
            } else {
                return co.y - this.y;
            }
    

    则按照从大到小的顺序排序

调用重写compareTo方法的Comparator接口

根据y值排序

import java.util.ArrayList;
import java.util.Collections;

class ObjComparator implements java.util.Comparator {
    public int compare(Object o1, Object o2) {
        CompObj co1 = (CompObj) o1; // 转化成当前类型的对象
        CompObj co2 = (CompObj) o2;
        if (co1.y != co2.y) {
            return co1.y - co2.y;// 先根据y值排序
        } else {
            return co1.x - co2.x;
        }
    }
}

public class CompObj { // 无需实现Comparable接口
    int x;
    int y;

    public CompObj(int n1, int n2) {
        x = n1;
        y = n2;
    }

    public String toString() {
        return "[x = " + x + ", y = " + y + "]";
    }

    public static void main(String[] args) {
        ArrayList al = new ArrayList();
        al.add(new CompObj(3, 2));
        al.add(new CompObj(1, 3));
        al.add(new CompObj(1, 2));
        System.out.println("Before sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
        Collections.sort(al, new ObjComparator());
        System.out.println("After sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
    }
}

在这里插入图片描述

调用重写compareTo方法的Comparator接口实现绝对值排序

根据x的绝对值排序

import java.util.ArrayList;
import java.util.Collections;

class AbsComparator implements java.util.Comparator {
    public int compare(Object o1, Object o2) {
        CompObj co1 = (CompObj) o1;// 转化成当前类型的对象
        CompObj co2 = (CompObj) o2;
        int v1 = Math.abs(co1.x);// 把对象co1的x成员转化成绝对值
        int v2 = Math.abs(co2.x);
        return v1 - v2;
    }
}

public class CompObj { // 无需实现Comparable接口
    int x;
    int y;

    public CompObj(int n1, int n2) {
        x = n1;
        y = n2;
    }

    public String toString() {
        return "[x = " + x + ", y = " + y + "]";
    }

    public static void main(String[] args) {
        ArrayList al = new ArrayList();
        al.add(new CompObj(3, 2));
        al.add(new CompObj(-2, 3));
        al.add(new CompObj(1, 2));
        System.out.println("Before sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
        Collections.sort(al, new AbsComparator());
        System.out.println("After sort!");
        for (int i = 0; i < al.size(); i++) {
            System.out.println(al.get(i));
        }
    }
}

在这里插入图片描述

反思总结

  • 起床整到现在,饿的一批
  • 觉得有帮助到你就点个赞吧🙏🙏🙏
  • 下期出数据结构的约瑟夫问题
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值