comparator接口中compare比较方法详述

本文介绍了Comparator接口在Java中如何用于控制对象排序,重点讲解了compare方法的使用和Lambda表达式的应用,以及如何通过重写compare方法实现自定义排序策略。举例说明了使用Lambda简化代码以及Array.sort的限制。

java.util 包下接口 Comparator
类型参数: T - 此 Comparator 可以比较的对象类型

  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort
    或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序
    set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
 int compare(T o1, T o2) 
          比较用来排序的两个参数。
方法详细信息
compare
int  compare ( T o1, T o2 )
比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。 分别返回 -101。 
参数: 
o1 - 要比较的第一个对象。 
o2 - 要比较的第二个对象。 
返回: 
根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。 
抛出: 
ClassCastException - 如果参数的类型不允许此 Comparator 对它们进行比较。

*********通过重写Comparator接口中的抽象方法compare,自定义元素的排序方式。

  • Compare的返回值反应的是两个参数的权重,返回值为1时,前者(o1)权重大,返回值为-1时,后者(o2)权重大。然后排序结果按照权重(注意这里不是值的大小)由小到大进行排序。即权重默认升序排列。
例:o1 =4 ,o2 = 6return o2 – o1; {即返回值为正数,即为1,那么前者权重大,排序为o2,o1; 
即为64,值降序排列}
	return o1 – o2; {即返回值为负数,即为-1,那么后者权重大,排序为o1,o2; 
即为46,值升序排列}

参数为接口时,可以使用lambda表达式。
1)	Lambda表达式的标准格式为:(参数类型 参数名称)> { 代码语句 }
	1.	小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。 
	2.>是新引入的语法格式,代表指向动作。 
	3.	大括号内的语法与传统方法体要求基本一致。
2)	Lambda省略格式
	1. 小括号内参数的类型可以省略;  
	2. 如果小括号内有且仅有一个参,则小括号可以省略; 
	3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
3)	Lambda的使用前提
	1.	使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。无论是JDK内置的 RunnableComparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一 时,才可以使用Lambda2.	使用Lambda必须具有上下文推断。也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
1.	Array.sort()不能对int数组进行自定义排序,只能对Integer数组使用,因为int数组没有实现该接口,只能用于对象类型的自定义排序。
2.	compareTo()方法比较的时候是按照ASCII码逐位比较的.
例:
public String largestNumber(int[] nums) {
    int n = nums.length;
    String numsToWord[] = new String[n];
    for(int i=0;i<n;i++){
        numsToWord[i] = String.valueOf(nums[i]);
    }
    //compareTo()方法比较的时候是按照ASCII码逐位比较的
    //通过比较(a+b)和(b+a)的大小,就可以判断出a,b两个字符串谁应该在前面
    //所以[3,30,34]排序后变为[34,3,30]
    //[233,23333]排序后变为[23333,233]
    Arrays.sort(numsToWord,(a,b)->{
        /*应该是指数组中,任何两个元素都按这种方式进行排序*/
        return (b+a).compareTo(a+b);
    });
    //如果排序后的第一个元素是0,那后面的元素肯定小于或等于0,则可直接返回0
    if(numsToWord[0].equals("0")){
        return "0";
    }
    StringBuilder sb = new StringBuilder();
    for(int i=0;i<n;i++){
        sb.append(numsToWord[i]);
    }
    return sb.toString();
}

<think>我们正在讨论Java中的Comparator接口,特别是thenComparing方法的使用。 thenComparing方法用于在已有的比较器基础上,添加一个次要的比较规则。当主要比较规则认为两个对象相等时,就会使用这个次要规则进行比较。 使用场景:例如,先按姓名排序,如果姓名相同再按年龄排序。 示例步骤: 1. 创建一个类(例如Person),包含多个属性(如name和age)。 2. 创建主要比较器(例如按name比较)。 3. 使用thenComparing方法链式调用添加次要比较器(例如按age比较)。 注意:thenComparing有多个重载方法,可以接受不同的参数(如Function、Comparator等)。 下面是一个具体的代码示例:</think>### Java Comparator接口中thenComparing方法的使用 `Comparator.thenComparing()`方法用于创建**链式比较器**,当主比较器认为两个对象相等时,会继续使用指定的次要比较器进行比较。该方法常用于多级排序场景。 #### 基础语法 ```java Comparator<T> thenComparing(Comparator<? super T> other) ``` #### 使用示例 假设有`Student`类: ```java class Student { String name; int age; double score; // 构造方法和getter省略 } ``` **场景1:二级排序(姓名+年龄)** ```java Comparator<Student> byName = Comparator.comparing(Student::getName); Comparator<Student> byAge = Comparator.comparingInt(Student::getAge); // 先按姓名排序,姓名相同再按年龄排序 Comparator<Student> combined = byName.thenComparing(byAge); students.sort(combined); ``` **场景2:三级排序(分数降序+年龄升序+姓名)** ```java Comparator<Student> finalComparator = Comparator.comparingDouble(Student::getScore).reversed() // 分数降序 .thenComparingInt(Student::getAge) // 年龄升序 .thenComparing(Student::getName); // 姓名升序 students.sort(finalComparator); ``` **场景3:混合Lambda表达式** ```java students.sort( Comparator.comparing((Student s) -> s.getScore(), Comparator.reverseOrder()) .thenComparing(s -> s.getAge()) .thenComparing(s -> s.getName(), String.CASE_INSENSITIVE_ORDER) // 忽略大小写 ); ``` #### 关键特性 1. **链式调用**:支持无限级联`thenComparing()` 2. **空值处理**:使用`Comparator.nullsFirst()`/`nullsLast()`处理null值 ```java Comparator.nullsFirst(byName).thenComparing(byAge) ``` 3. **方法引用**:可直接使用类方法 ```java Comparator.comparing(Student::getName) .thenComparing(Student::getAge) ``` #### 注意事项 - 主比较器相等时才会触发次要比较器 - 每个比较器可独立设置排序方向(升序/降序) - 使用`reversed()`反转排序方向时需注意作用域 ```java // 正确:整体反转 combined.reversed() // 错误:仅反转最后一个比较器 byName.thenComparing(byAge.reversed()) ``` > 示例输出(三级排序): > ``` > 张三(95.5, 20) > 李四(95.5, 22) // 同分数时按年龄升序 > 王五(88.0, 19) > ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值