jmu-Java-PTA题解 (5.2 - 面向对象进阶--02-接口-Comparator) 网安2312陈卓

问题要求

Arrays.sort可以对所有实现Comparable的对象进行排序。但如果有多种排序需求,如有时候需对name进行降序排序,有时候只需要对年龄进行排序。使用Comparable无法满足这样的需求。可以编写不同的Comparator来满足多样的排序需求。

  1. 编写PersonSortable2类
    属性:private name(String)、private age(int)
    有参构造函数:参数为name,age
    toString方法:返回格式name-age

  2. 编写Comparator类

    1. 编写NameComparator类,实现对name进行升序排序
    2. 编写AgeComparator类,对age进行升序排序
  3. main方法中
    1.输入n
    2. 输入n行name age,并创建n个对象放入数组
    3. 对数组按照name进行升序排序后输出。
    4. 在3的基础上对数组按照age进行升序排序后输出。
    5. 最后最后两行使用如下代码输出NameComparator与AgeComparator所实现的所有接口。

System.out.println(Arrays.toString(NameComparator.class.getInterfaces()));
System.out.println(Arrays.toString(AgeComparator.class.getInterfaces()));

输入样例:

5
zhang 15
zhang 12
wang 14
Wang 17
li 17

输出样例:

NameComparator:sort
Wang-17
li-17
wang-14
zhang-15
zhang-12
AgeComparator:sort
zhang-12
wang-14
zhang-15
Wang-17
li-17
//最后两行是标识信息

关键点

  • 接口实现与排序需求:Comparator 接口的使用是关键。通过实现 Comparator 接口,分别创建 NameComparator 和 AgeComparator 类,来满足对 PersonSortable2 对象的不同排序需求。这使得在不修改对象类本身(PersonSortable2 类)的情况下,能够灵活地根据不同的属性进行排序,体现了接口的灵活性和扩展性。
  • 对象类的设计:PersonSortable2 类的设计要合理,包含了需要排序的属性(name 和 age),并且提供了相应的访问方法(getName 和 getAge)以及便于输出的 toString 方法。有参构造函数方便了对象的初始化,为后续的排序操作提供了基础。
  • compare 方法的实现:在 NameComparator 和 AgeComparator 的 compare 方法中,根据不同的属性(name 和 age)实现了具体的比较逻辑。对于 name 的比较,使用了 String 类的 compareTo 方法;对于 age 的比较,直接进行数值相减。正确的比较逻辑是实现准确排序的核心。
  • 排序操作的调用:在 main 方法中,使用 Collections.sort 方法,并传入相应的 Comparator 实现类(NameComparator 或 AgeComparator)来对 ArrayList 中的 PersonSortable2 对象进行排序。这要求对 Collections 工具类的 sort 方法有正确的理解和使用,确保排序操作能够按照预期进行。
  • 反射获取接口信息:通过反射机制,使用 class.getInterfaces() 方法获取 NameComparator 和 AgeComparator 类所实现的接口信息。这部分代码展示了 Java 反射的基本应用,能够在运行时获取类的接口信息,增加了代码的动态性和可扩展性。

解题步骤

第一步:编写 PersonSortable2 类

定义 PersonSortable2 类,包含私有属性 name 和 age,并提供有参构造函数用于初始化属性,同时实现 getName、getAge 方法用于获取属性值,以及重写 toString 方法以便按要求格式输出对象信息。

class PersonSortable2 {
    private String name;
    private int age;

    // 有参构造函数
    public PersonSortable2(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 获取name的方法
    public String getName() {
        return this.name;
    }

    // 获取age的方法
    public int getAge() {
        return this.age;
    }

    // 重写toString方法
    public String toString() {
        return name + "-" + age;
    }
}

第二步:编写 Comparator 类

分别编写 NameComparator 类和 AgeComparator 类,都实现 Comparator 接口,并根据不同属性重写 compare 方法以实现升序排序。

class NameComparator implements Comparator<PersonSortable2> {
    public int compare(PersonSortable2 e1, PersonSortable2 e2) {
        int namecompare = e1.getName().compareTo(e2.getName());
        if (namecompare != 0) {
            return namecompare;
        } else {
            return 0;
        }
    }
}

class AgeComparator implements Comparator<PersonSortable2> {
    public int compare(PersonSortable2 e1, PersonSortable2 e2) {
        return e1.getAge() - e2.getAge();
    }
}

第三步:编写 main 方法

在 main 方法中,首先通过 Scanner 从控制台读取输入的整数 n,然后通过循环读取 n 行 name 和 age 的数据,创建 n 个 PersonSortable2 对象并添加到 ArrayList 中。接着使用 Collections.sort 方法分别传入 NameComparator 和 AgeComparator 对数组进行排序,并按要求输出排序结果。最后通过反射获取并输出两个比较器类所实现的接口信息。

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        ArrayList<PersonSortable2> arr = new ArrayList<PersonSortable2>();
        for (int i = 0; i < n; i++) {
            String name = in.next();
            int age = in.nextInt();
            PersonSortable2 e = new PersonSortable2(name, age);
            arr.add(e);
        }
        Collections.sort(arr, new NameComparator());
        System.out.println("NameComparator:sort");
        for (PersonSortable2 e : arr) {
            System.out.println(e.toString());
        }
        Collections.sort(arr, new AgeComparator());
        System.out.println("AgeComparator:sort");
        for (PersonSortable2 e : arr) {
            System.out.println(e.toString());
        }
        System.out.println(Arrays.toString(NameComparator.class.getInterfaces()));
        System.out.println(Arrays.toString(AgeComparator.class.getInterfaces()));
    }
}

整体流程图:

整体代码:

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

class PersonSortable2{
    private String name;
    private int age;

    public void PersonSortable(String name, int age){
        this.name = name;
        this.age = age;
    }

    public String getName(){
        return this.name;
    }

    public int getAge(){
        return this.age;
    }

    public String toString(){
        return name+"-"+age;
    }
}

class NameComparator implements Comparator<PersonSortable2>{
    public int compare(PersonSortable2 e1, PersonSortable2 e2){
        int namecompare = e1.getName().compareTo(e2.getName());
        if(namecompare!=0){
            return namecompare;
        }else{
            return 0;
        }
    }
}

class AgeComparator implements Comparator<PersonSortable2>{
    public int compare(PersonSortable2 e1, PersonSortable2 e2){
        return e1.getAge()-e2.getAge();
    }
}

public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        ArrayList<PersonSortable2> arr = new ArrayList<PersonSortable2>();
        for(int i=0; i<n; i++){
            PersonSortable2 e = new PersonSortable2();
            String name = in.next();
            int age = in.nextInt();
            e.PersonSortable(name,age);
            arr.add(e);
        }
        Collections.sort(arr,new NameComparator());
        System.out.println("NameComparator:sort");
        for(PersonSortable2 e:arr){
            System.out.println(e.toString());
        }
        Collections.sort(arr,new AgeComparator());
        System.out.println("AgeComparator:sort");
        for(PersonSortable2 e:arr){
            System.out.println(e.toString());
        }
        System.out.println(Arrays.toString(NameComparator.class.getInterfaces()));
        System.out.println(Arrays.toString(AgeComparator.class.getInterfaces()));
    }
}

思考:在解决该问题的过程中,7运用 Comparator 接口体现了 Java 面向对象编程中接口的强大作用和灵活性。与 Comparable 接口相比,Comparator 接口提供了一种更灵活的排序方式。Comparable 接口将排序逻辑直接定义在类内部,这意味着一个类只能有一种默认的排序方式,并且如果需要修改排序逻辑,就必须修改类的源代码。而 Comparator 接口将排序逻辑与类本身分离,使得同一个类可以根据不同的需求实现多种排序策略 ,并且使用 Comparator 接口使得代码的扩展性更强。当项目需求发生变化,需要增加新的排序规则时,只需要创建一个新的 Comparator 实现类,而不需要修改原有的类代码。这种设计模式遵循了 “开闭原则”,即对扩展开放,对修改关闭,使得代码在面对需求变更时更加健壮和易于维护。此外,通过反射获取接口信息的操作展示了 Java 语言强大的自省能力。这种能力使得程序在运行时能够动态地获取类的信息,包括接口、方法、属性等,为程序的动态性和灵活性提供了支持。在实际开发中,反射机制可以用于各种场景,如依赖注入、动态代理等,极大地增强了程序的适应性和可扩展性。

posted @ 2025-04-23 10:24  取名字比写博客还难  阅读(26)  评论(0)    收藏  举报