java 自定义排序实现

在java中,要实现自定义排序可以使用两种方法:

  • 让排序的对象的类实现Comparable接口
  • 新建一个类实现比较器Comparator接口

Comparable接口

Comparable接口中有一个compareTo(T o)方法:

public int compareTo(T o);

compareTo() 方法用于将 Number 对象与方法的参数进行比较。可用于比较 Byte, Long, Integer等。
该方法用于两个相同数据类型的比较,两个不同类型的数据不能用此方法来比较。
实例:

public class Test{ 
   public static void main(String args[]){
      Integer x = 5;
      System.out.println(x.compareTo(3));
      System.out.println(x.compareTo(5));
      System.out.println(x.compareTo(8));            
     }
}

输出:

	1
	0
	-1

返回值:

  • 如果指定的数与参数相等返回 0。
  • 如果指定的数小于参数返回 -1。
  • 如果指定的数大于参数返回 1。
实现Comparable接口自定义排序规则

这种方法需要要进行排序的对象的那个类实现Comparable接口,泛用性比较高,在类中重写一次Comparable接口中的compareTo()方法,再对该对象进行排序时,排序的方式都是使用的自己定义的规则。
但是这种方法不能对没有实现Comparable接口的类对象使用,比如我们就不能使用这种方式对String类型的排序方式进行改变,因为我们不能去修改String类。

实例:

自定义一个学生类型,实现Comparable接口,按照学生的年龄逆序排序:

public static void main(String[] args) {

    Student[] students=new Student[4];
    for(int i=0;i<4;i++){
        students[i]=new Student();
    }
    students[0].age=10;
    students[0].name="li";
    students[0].num=1;
    students[1].age=22;
    students[1].name="li11";
    students[1].num=2;
    students[2].age=4;
    students[2].name="li222";
    students[2].num=3;
    students[3].age=40;
    students[3].name="l";
    students[3].num=4;
    Arrays.sort(students);
   System.out.println(Arrays.toString(students));
}

class Student implements Comparable<Student>{
    String name;
    int age;
    int num;

    public int getNum() {
        return num;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
    @Override
    public int compareTo(Student o) {
        return o.age-age;
    }
}

输出:

[Student{name='l', age=40}, Student{name='li11', age=22}, Student{name='li', age=10}, Student{name='li222', age=4}]

默认的sort是升序排序,重写了Comparable中的方法compareTo,让sort按照student的年龄倒序排序。

comparator接口(比较器)

comparator接口(比较器)中有一个compare方法:

compare(Object o1,Object o2):比较o1和o2的大小

返回值:

  • 如果方法返回正整数,则表示o1大于o2,
  • 如果返回0,表示二者相等,
  • 如果返回负整数,表示o1小于o2.
新建类实现Comparator接口实现排序规则

新建一个类实现比较器Comparator接口,这种方法需要在sort方法中new 这个类
这种方法的弊端就是每次排序都需要重写一次排序规则,也就是重写Comparator接口中的compare()方法。
为了简便,这种方法通常用内部类或lambda表达式实现。

普通实现:

student类的数据仍旧和上文中一样,此次按照名字的长度顺序排序:

class StudentCompare implements Comparator<Student> {

    @Override
    public int compare(Student o1,Student o2) {
        return o1.name.length()-o2.name.length();
    }
}

Arrays.sort(students,new StudentCompare());
System.out.println(Arrays.toString(students));

输出:

[Student{name='l', age=40}, Student{name='li', age=10}, Student{name='li11', age=22}, Student{name='li222', age=4}]
内部类实现:
Arrays.sort(students,new StudentCompare(){
    @Override
    public int compare(Student o1,Student o2) {
        return o1.name.length()-o2.name.length();
    }
});
lambda表达式实现:
Arrays.sort(students,(o1,o2)->{
    return o1.name.length() - o2.name.length();
});

或者更加简洁的形式:

Arrays.sort(students, Comparator.comparingInt(o -> o.name.length()));

注意:

  1. Array.sort()不能对int数组进行自定义排序,只能对Integer数组使用,因为int数组没有实现该接口。Array.sort()不能对基本类型使用自定义排序,想要使用Arrays.sort()排序可以将基本类型转换为对应的包装器类型,Arrays.sort()只能用于对象类型的数据自定义排序规则。(当然,可以使用sort()方法对基本类型升序排序,只是不能自定义排序
  2. compareTo()方法比较的时候是按照ASCII码逐位比较的.

lambda表达式介绍:

参数为接口时,可以使用lambda表达式。

  1. Lambda表达式的标准格式为:(参数类型 参数名称) ‐> { 代码语句 }
  1. 小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
  2. ‐>是新引入的语法格式,代表指向动作。
  3. 大括号内的语法与传统方法体要求基本一致。
  1. Lambda省略格式
  1. 小括号内参数的类型可以省略;
  2. 如果小括号内有且仅有一个参,则小括号可以省略;
  3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
  1. Lambda的使用前提
  1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一 时,才可以使用Lambda。
  2. 使用Lambda必须具有上下文推断。也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每周都想吃火锅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值