JAVA中的比较器

本文介绍Java中对象排序的方法,包括自然排序和定制排序的概念及其应用。详细解释Comparable和Comparator接口的使用,展示如何通过重写compareTo和compare方法实现不同场景下的排序需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引出

传统的对象之间是一般都是==或者!=
看对象是否为同一个
而没有存在>或者<类似的
但有的时候我们需要根据
对象的某一个属性进行排序
怎么办呢
这个时候就引出来
比较器了
主要是两个接口

Comparable和Comparator

Comparable
一般被成为自然排序(用途:一般是一个类继承接口重写compareTo方法,后面在集合或者其他地方排序的时候可以用)
Comparator
一般称为定制排序(用途:一般来给基本数据类型,或者比较次数较少的(一般是匿名内部类实现))

这两个都是要通过里面的compare方法来实现排序的,所以这个方法一定要重写

注意的:两者都是看retunrn的值,决定对应参数列表的排序
比如
compare(student o1,student o2)

return o1.score-o2.score
如果o1(7)的score大于o2(6)
返回正数
会判定o1排在o2后面(按照参数列表倒序)
此时就是正序  6-7
如果
return o2.score-o1.score
还看前面的数吧
返回是是一个-1,认定o1排在o2前面(按照参数列表o1后o2)
此时就编程倒序了 7-6

如果你是第一个参数减去第二个参数,永远是正序
(第一个参数大,第一个参数后排,第一个参数小,第一个参数前排)
反过来,第二个参数减第一个属性永远是倒序

不懂自己推一推

Cmoparable

Comparable是一个接口

此类常见于java中的Array和Collection的排列

调用Arrays/Collections.sort(对象数组/对象集合)

按照的排序方式就是对应对象内的重写Comparable类的ComparaTo方法

源码

public interface Comparable<T> 
{
    public int compareTo(T o);
}

使用举例

public class Goods implements  Comparable{

    private String name;
    private double price;

    //指明商品比较大小的方式:照价格从低到高排序,再照产品名称从高到低排序
    @Override
    public int compareTo(Object o) {
//        System.out.println("**************");
        if(o instanceof Goods){
            Goods goods = (Goods)o;
            //方式一:
            if(this.price > goods.price){
                return 1;
            }else if(this.price < goods.price){
                return -1;
            }else{
//                return 0;
               return -this.name.compareTo(goods.name);
               //解释一下吧,这里的this.name是一个String类型可以使用对应的方法
               //相当于 String.compareTo(这个String类重写过,默认从小到大排序按名称)
            }
            //方式二:
//           return Double.compare(this.price,goods.price);
        }
//        return 0;
        throw new RuntimeException("传入的数据类型不一致!");
    }
// getter、setter、toString()、构造器:省略
}

Comparator

1.背景:
当元素的类型没实现java.lang.Comparable接口而又不方便修改代码,或者实现了
java.lang.Comparable接口的排序规则不适合当前的操作,
那么可以考虑使用 Comparator 的对象来排序
2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
如果方法返回正整数,则表示o1大于o2;
如果返回0,表示相等;
返回负整数,表示o1小于o2。

举例

Comparator com = new Comparator() {
    //指明商品比较大小的方式:照产品名称从低到高排序,再照价格从高到低排序
    @Override
    public int compare(Object o1, Object o2) {
        if(o1 instanceof Goods && o2 instanceof Goods){
            Goods g1 = (Goods)o1;
            Goods g2 = (Goods)o2;
            if(g1.getName().equals(g2.getName())){
                return -Double.compare(g1.getPrice(),g2.getPrice());
            }else{
                return g1.getName().compareTo(g2.getName());
            }
        }
        throw new RuntimeException("输入的数据类型不一致");
    }
}

使用:
Arrays.sort(goods,Comparator);
Collections.sort(coll,Comparator);
new TreeSet(com);
//comparator一般是用匿名内部类实现
//8后可以用lambda表达式实现 (o1,o2)-> o1.getXXX()-o2.getXXX()
//省略了return 和 {} 和 参数类型

两者区别可以看
Comparable和Comparator区别

集合基本数据类型排序

@SuppressWarnings("all")
public class Main{

public static void main(String [] args){
	Scanner scanner = new Scanner(System.in);
	int a=scanner.nextInt();
	int b=scanner.nextInt();
	int c=scanner.nextInt();
	ArrayList<Integer> arrayList = new ArrayList<Integer>();
	arrayList.add(a);
	arrayList.add(b);
	arrayList.add(c);
	arrayList.sort(new Comparator<Integer>() {

		@Override
		public int compare(Integer o1, Integer o2) {
			return o1-o2;
		}
		
	});
	for (Integer integer : arrayList) {
		System.out.println(integer);
	}
}
}
<think>我们正在讨论Java中的Comparator接口。根据引用内容,Comparator接口用于定义对象的定制排序规则。它位于java.util包中,包含一个compare方法,用于比较两个对象。我们可以通过实现Comparator接口来为一个类定义一种或多种比较规则,而不需要修改类本身(与Comparable接口不同,Comparable需要修改类)。 使用步骤: 1. 创建一个类实现Comparator接口,并指定要比较的对象类型(泛型)。 2. 实现compare方法,该方法接受两个同类型的对象,返回一个整数: - 如果第一个对象小于第二个对象,返回负数。 - 如果第一个对象等于第二个对象,返回0。 - 如果第一个对象大于第二个对象,返回正数。 另外,虽然Comparator接口要求实现equals方法,但通常不需要重写,因为从Object类继承的equals方法已经足够(比较的是对象引用)。所以,我们通常只需要实现compare方法。 此外,从Java 8开始,我们可以使用lambda表达式或方法引用来更简洁地实现Comparator。 示例:假设有一个Person类,有name和age属性。我们想按照年龄排序,然后按照姓名排序。 根据引用[4],我们可以使用链式比较:先按年龄比较,再按姓名比较。可以使用Comparator的thenComparing方法。 下面我们给出具体代码示例。 注意:引用[1]提到通过实现Comparator接口定义比较规则;引用[2]说明了为什么需要比较器;引用[3]详细说明了Comparator接口的方法;引用[4]给出了链式比较的示例。 因此,我们将按照以下步骤进行: 1. 定义Person类(如果已有则不需要)。 2. 创建按年龄比较的Comparator。 3. 创建按姓名比较的Comparator。 4. 组合两个Comparator(先按年龄,再按姓名)。 5. 使用Collections.sort或List.sort方法进行排序。 代码示例:</think>### Java 中 Comparator 接口的实现与使用 在 Java 中,`Comparator` 接口用于实现对象的**定制排序**,特别适用于以下场景: 1. 对无法修改源码的类进行排序 2. 需要多种排序规则(如按年龄、姓名等不同属性排序) 3. 需要链式多重排序(先按年龄再按姓名) #### 实现步骤(两种方式) ##### 方式 1:创建独立比较器类 ```java import java.util.Comparator; // 步骤 1:实现 Comparator 接口 public class AgeComparator implements Comparator<Person> { // 步骤 2:实现 compare() 方法 @Override public int compare(Person p1, Person p2) { // 按年龄升序排序 return p1.getAge() - p2.getAge(); } } ``` ##### 方式 2:使用 Lambda 表达式(Java 8+) ```java Comparator<Person> nameComparator = (p1, p2) -> p1.getName().compareTo(p2.getName()); // 按姓名字典序排序 ``` #### 使用示例 ```java import java.util.*; public class Main { public static void main(String[] args) { List<Person> people = Arrays.asList( new Person("Alice", 30), new Person("Bob", 25), new Person("Charlie", 30) ); // 使用独立比较器 Collections.sort(people, new AgeComparator()); // 使用 Lambda 比较器 Collections.sort(people, (p1, p2) -> p1.getAge() - p2.getAge()); // 链式多重排序(先按年龄升序,再按姓名降序) Comparator<Person> chainComparator = Comparator .comparingInt(Person::getAge) .thenComparing(Comparator.comparing(Person::getName).reversed()); people.sort(chainComparator); } } class Person { private String name; private int age; // 构造方法/getters/setters 省略 } ``` #### 关键特性 1. **`compare(T o1, T o2)` 方法**:必须实现的核心方法,返回: - **负数**:o1 < o2 - **零**:o1 == o2 - **正数**:o1 > o2 2. **链式排序**:通过 `thenComparing()` 实现多级排序[^4] 3. **内置工具方法**: ```java Comparator.comparing(Person::getName) // 方法引用 Comparator.comparingInt(Person::getAge) // 基本类型优化 Comparator.nullsFirst(Comparator) // 处理 null 值 ``` #### 与 Comparable 的区别 | 特性 | Comparator | Comparable | |--------------------|--------------------|------------------| | 排序逻辑位置 | 外部比较器 | 内部比较器 | | 修改原有类 | 不需要 | 需要 | | 多排序规则支持 | ✅ (可创建多个) | ❌ (仅一种) | | 接口方法 | `compare(T o1, T o2)` | `compareTo(T o)` | > 提示:当需要多种排序规则时优先选用 `Comparator`;当对象有自然排序时使用 `Comparable`[^2][^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小袁拒绝摆烂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值