Java中定制比较器

当需要进行比较而默认的比较方式不满足我们的需求时,可以自己写比较器。

class ComparatorName implements Comparator<T> {
    //按照需求写比较器方法
    public int compare(T t1, T t2) {    }
}

华为机试题:错误纪录功能

import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) throws IOException{
        Scanner in = new Scanner(System.in);
        List<String> list = new ArrayList<>();
        List<List<String>> result = new ArrayList<>();
        while(in.hasNext()) {
            String tempFilename = in.next();
            int lineNum = in.nextInt();
            in.nextLine();
            String[] arr = tempFilename.split("\\\\");
            String filename = arr[arr.length - 1];
            String input = filename + " " + lineNum;
            if(!list.contains(input)) {
                list.add(input);
                List<String> temp = new ArrayList<>();
                temp.add(input);
                temp.add(1 + "");
                result.add(temp);
            } else {
                Iterator<List<String>> iterator = result.iterator();
                while(iterator.hasNext()) {
                    List<String> temp = iterator.next();
                    if(input.equals(temp.get(0))) {
                        int count = Integer.parseInt(temp.get(1));
                        count++;
                        temp.set(1, count + "");
                    }
                }
            }
        }
        in.close();

        String[] resultArr = new String[result.size()];
        int j = 0;
        for(List<String> e : result) {
            String sName = e.get(0).split(" ")[0];
            if(sName.length() > 16) {
                sName = sName.substring(sName.length() - 16);
                String lNum = e.get(0).split(" ")[1];
                resultArr[j++] = sName + " " + lNum + " " + e.get(1);
                continue;
            }
            resultArr[j++] = e.get(0) + " " + e.get(1);
        }

        sort(resultArr, new StringComparator());       //根据出现次数进行递减排序

        if(resultArr.length <= 8)         //输出结果
            for(String e : resultArr)
                System.out.println(e);
        else {
            for(int i = 0; i < 8; i++)
                System.out.println(resultArr[i]);
        }
    }

    public static void sort(String[] s, Comparator<String> cmp) {
        int j;
        for(int i = 1; i < s.length; i++) {
            String temp = s[i];
            for(j = i; j > 0 && cmp.compare(temp, s[j - 1]) > 0; j--)
                s[j] = s[j - 1];
            s[j] = temp;
        }
    }
}

/*
 * 定制比较器
 */
class StringComparator implements Comparator<String> {
    public int compare(String s1, String s2) {
        int lastSubStr1 = Integer.parseInt(s1.split(" ")[s1.split(" ").length - 1]);
        int lastSubStr2 = Integer.parseInt(s2.split(" ")[s2.split(" ").length - 1]);
        return lastSubStr1 - lastSubStr2;
    }
}
<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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值