Java TreeSet案例怎么排序

wen java案例 26

Java TreeSet 排序案例

TreeSet 提供了两种排序方式:自然排序定制排序,我来给你展示具体的案例代码。

Java TreeSet案例怎么排序

自然排序(Comparable接口)

import java.util.TreeSet;
// 学生类实现Comparable接口
class Student implements Comparable<Student> {
    private String name;
    private int age;
    private double score;
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    // 实现compareTo方法,按年龄排序
    @Override
    public int compareTo(Student other) {
        // 先按年龄排序
        int ageCompare = Integer.compare(this.age, other.age);
        if (ageCompare != 0) {
            return ageCompare;
        }
        // 年龄相同时按成绩排序
        return Double.compare(this.score, other.score);
    }
    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + ", score=" + score + "}";
    }
}
public class TreeSetNaturalSortDemo {
    public static void main(String[] args) {
        TreeSet<Student> students = new TreeSet<>();
        students.add(new Student("张三", 20, 85.5));
        students.add(new Student("李四", 18, 90.0));
        students.add(new Student("王五", 22, 78.0));
        students.add(new Student("赵六", 20, 95.0));
        students.add(new Student("张三", 20, 85.5)); // 重复元素,不会被添加
        System.out.println("TreeSet元素(按年龄排序):");
        for (Student s : students) {
            System.out.println(s);
        }
    }
}

定制排序(Comparator接口)

import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetCustomSortDemo {
    public static void main(String[] args) {
        // 方式1:使用匿名内部类
        TreeSet<Student> students1 = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                // 按成绩降序排序
                int scoreCompare = Double.compare(s2.getScore(), s1.getScore());
                if (scoreCompare != 0) {
                    return scoreCompare;
                }
                // 成绩相同时按姓名排序
                return s1.getName().compareTo(s2.getName());
            }
        });
        // 添加学生
        students1.add(new Student("张三", 20, 85.5));
        students1.add(new Student("李四", 18, 90.0));
        students1.add(new Student("王五", 22, 78.0));
        students1.add(new Student("赵六", 20, 95.0));
        System.out.println("按成绩降序排序:");
        for (Student s : students1) {
            System.out.println(s);
        }
        // 方式2:使用Lambda表达式(Java 8+)
        TreeSet<Student> students2 = new TreeSet<>(
            (s1, s2) -> {
                // 先按姓名排序
                int nameCompare = s1.getName().compareTo(s2.getName());
                if (nameCompare != 0) {
                    return nameCompare;
                }
                // 姓名相同时按年龄排序
                return Integer.compare(s1.getAge(), s2.getAge());
            }
        );
        students2.add(new Student("张三", 20, 85.5));
        students2.add(new Student("张三", 18, 90.0));
        students2.add(new Student("李四", 22, 78.0));
        System.out.println("\n按姓名升序,姓名相同按年龄:");
        for (Student s : students2) {
            System.out.println(s);
        }
    }
}
// 完善Student类,增加getter方法
class Student implements Comparable<Student> {
    private String name;
    private int age;
    private double score;
    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }
    public String getName() { return name; }
    public int getAge() { return age; }
    public double getScore() { return score; }
    @Override
    public int compareTo(Student other) {
        int ageCompare = Integer.compare(this.age, other.age);
        if (ageCompare != 0) {
            return ageCompare;
        }
        return Double.compare(this.score, other.score);
    }
    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + ", score=" + score + "}";
    }
}

字符串自定义排序案例

import java.util.Comparator;
import java.util.TreeSet;
public class StringSortDemo {
    public static void main(String[] args) {
        // 案例1:按字符串长度排序
        TreeSet<String> lengthSort = new TreeSet<>(
            (s1, s2) -> {
                int lenCompare = Integer.compare(s1.length(), s2.length());
                if (lenCompare != 0) {
                    return lenCompare;
                }
                // 长度相同时按字母顺序
                return s1.compareTo(s2);
            }
        );
        lengthSort.add("Java");
        lengthSort.add("Python");
        lengthSort.add("C");
        lengthSort.add("JavaScript");
        lengthSort.add("Go");
        System.out.println("按字符串长度排序:");
        for (String s : lengthSort) {
            System.out.println(s + " (长度: " + s.length() + ")");
        }
        // 案例2:忽略大小写排序
        TreeSet<String> caseInsensitiveSort = new TreeSet<>(
            String.CASE_INSENSITIVE_ORDER
        );
        caseInsensitiveSort.add("Apple");
        caseInsensitiveSort.add("banana");
        caseInsensitiveSort.add("Cherry");
        caseInsensitiveSort.add("date");
        System.out.println("\n忽略大小写排序:");
        for (String s : caseInsensitiveSort) {
            System.out.println(s);
        }
    }
}

复杂对象多字段排序

import java.util.*;
class Employee {
    private String name;
    private String department;
    private double salary;
    private int age;
    public Employee(String name, String department, double salary, int age) {
        this.name = name;
        this.department = department;
        this.salary = salary;
        this.age = age;
    }
    // getter方法
    public String getName() { return name; }
    public String getDepartment() { return department; }
    public double getSalary() { return salary; }
    public int getAge() { return age; }
    @Override
    public String toString() {
        return String.format("%-8s | 部门:%-6s | 薪资:%.1f | 年龄:%d", 
                           name, department, salary, age);
    }
}
public class MultiFieldSortDemo {
    public static void main(String[] args) {
        // 多字段排序:先按部门,再按薪资降序,最后按年龄
        TreeSet<Employee> employees = new TreeSet<>(
            Comparator.comparing(Employee::getDepartment)
                     .thenComparing(Employee::getSalary, Comparator.reverseOrder())
                     .thenComparing(Employee::getAge)
        );
        employees.add(new Employee("张三", "技术部", 15000, 28));
        employees.add(new Employee("李四", "市场部", 12000, 25));
        employees.add(new Employee("王五", "技术部", 18000, 32));
        employees.add(new Employee("赵六", "市场部", 12000, 27));
        employees.add(new Employee("钱七", "技术部", 15000, 30));
        System.out.println("多字段排序(部门→薪资降序→年龄):");
        System.out.println("姓名     | 部门    | 薪资     | 年龄");
        System.out.println("-".repeat(45));
        for (Employee e : employees) {
            System.out.println(e);
        }
    }
}

注意事项

public class TreeSetNoteDemo {
    public static void main(String[] args) {
        // 1. 不能存储null元素
        TreeSet<String> set = new TreeSet<>();
        // set.add(null); // 会抛出NullPointerException
        // 2. 自定义对象必须实现Comparable或提供Comparator
        // 3. compareTo/compare返回0表示元素重复,不会添加
        // 4. 排序规则应满足一致性(传递性、自反性等)
        // 5. 使用Comparator.of方法优雅组合比较器
        TreeSet<String> words = new TreeSet<>(
            Comparator.comparingInt(String::length)
                     .thenComparing(String::compareToIgnoreCase)
                     .reversed()  // 反转整个排序
        );
        words.add("apple");
        words.add("banana");
        words.add("cherry");
        words.add("date");
        words.add("elderberry");
        System.out.println("按长度降序,长度相同忽略大小写:");
        words.forEach(System.out::println);
    }
}
排序方式 实现方法 适用场景
自然排序 实现 Comparable 接口的 compareTo() 对象有默认排序规则
定制排序 创建 Comparator 对象传入构造器 需要多种排序方式或临时排序

关键点:

  • TreeSet 元素必须可比较
  • 多个排序字段时使用 Comparator.thenComparing()
  • compareTo/compare 返回0视为重复元素
  • 使用Lambda可以简化代码

抱歉,评论功能暂时关闭!