MST

星途 面试题库

面试题:Java TreeSet自然排序在复杂对象场景下的应用

假设有一个自定义类Student,包含name(String类型)和age(int类型)属性。要求使用TreeSet对Student对象进行自然排序,首先按age升序,如果age相同则按name的字典序升序。请编写实现代码,并解释实现过程中如何处理Comparable接口或Comparator接口。
36.9万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
import java.util.TreeSet;

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

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Student other) {
        if (this.age != other.age) {
            return this.age - other.age;
        } else {
            return this.name.compareTo(other.name);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        TreeSet<Student> treeSet = new TreeSet<>();
        treeSet.add(new Student("Alice", 20));
        treeSet.add(new Student("Bob", 18));
        treeSet.add(new Student("Alice", 18));

        for (Student student : treeSet) {
            System.out.println("Name: " + student.getName() + ", Age: " + student.getAge());
        }
    }
}

实现过程说明

  1. 实现Comparable接口:为了让Student类对象能够在TreeSet中进行自然排序,Student类实现了Comparable接口,并实现了compareTo方法。
  2. compareTo方法逻辑
    • 首先比较两个Student对象的age属性,如果当前对象的age小于传入对象的age,返回一个负整数;如果大于,返回一个正整数;如果相等,则比较name属性。
    • 比较name属性时,调用String类的compareTo方法,该方法会按照字典序进行比较,同样返回负整数、正整数或0,以表示当前对象的name在字典序上小于、大于或等于传入对象的name
  3. 使用TreeSet:在main方法中,创建了一个TreeSet对象,并向其中添加Student对象。由于Student类实现了Comparable接口,TreeSet会自动按照compareTo方法定义的规则对元素进行排序。最后遍历TreeSet,输出排序后的结果。

如果使用Comparator接口,步骤如下:

import java.util.Comparator;
import java.util.TreeSet;

class Student {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        if (s1.getAge() != s2.getAge()) {
            return s1.getAge() - s2.getAge();
        } else {
            return s1.getName().compareTo(s2.getName());
        }
    }
}

public class Main {
    public static void main(String[] args) {
        TreeSet<Student> treeSet = new TreeSet<>(new StudentComparator());
        treeSet.add(new Student("Alice", 20));
        treeSet.add(new Student("Bob", 18));
        treeSet.add(new Student("Alice", 18));

        for (Student student : treeSet) {
            System.out.println("Name: " + student.getName() + ", Age: " + student.getAge());
        }
    }
}

使用Comparator接口说明

  1. 创建Comparator实现类:创建一个实现Comparator接口的类StudentComparator,在compare方法中定义比较逻辑,与Comparable接口中compareTo方法的逻辑一致。
  2. 使用TreeSet:在创建TreeSet对象时,将StudentComparator的实例作为参数传入构造函数。这样TreeSet会使用我们自定义的Comparator来对Student对象进行排序。