首页 > 编程笔记 > Java笔记 阅读:1

Java TreeMap集合的用法(附带实例)

使用 TreeMap 存储 key-value 对数据时,需要根据 key-value 对数据进行排序。TreeMap 可以保证所有的 key-value 对数据处于有序状态。TreeMap 使用 Map 接口中的方法。

TreeSet 底层使用红黑树结构存储数据。

TreeSet自然排序

TreeMap 中所有的 key 都必须实现 Comparable 接口,而且所有的 key 应该是同一个类的对象,否则将会抛出 ClassCastException 异常。

【实例 1】创建集合和 Student 类,使用 TreeSet 实现自然排序,代码如下:
import java.util.Objects;

public class Student implements Comparable {
    private Integer id;
    private String name;
    private Integer age;
    public Student(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public Student() {
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(id, student.id) &&
               Objects.equals(name, student.name) &&
               Objects.equals(age, student.age);
    }
    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
    @Override
    public String toString() {
        return "Student{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", age=" + age +
               '}';
    }
    @Override
    public int compareTo(Object o) {
        if(this == o){
            return 0;
        }
        if(o instanceof Student){
            Student student = (Student)o;
            int value = this.age - student.age;
            if(value != 0){
                return value;
            }
            return -this.name.compareTo(student.name);
        }
        throw new RuntimeException("输入的类型不匹配");
    }
}

import java.util.TreeMap;
public class MapDemo {
    public static void main(String[] args) {
        Student student = new Student(1, "王五", 20);
        Student student02 = new Student(2, "张三", 30);
        Student student04 = new Student(4, "笑笑", 24);
        Student student03 = new Student(3, "小花", 33);
        TreeMap treeMap = new TreeMap<>();
        treeMap.put(student, "01");
        treeMap.put(student02, "02");
        treeMap.put(student03, "03");
        treeMap.put(student04, "04");
        System.out.println(treeMap);
    }
}
程序运行结果如下:

{Student{id=1, name='王五', age=20}=01, Student{id=4, name='笑笑', age=24}=04, Student{id=3, name='小花', age=33}=03, Student{id=2, name='张三', age=30}=02}

在上述代码中实现了自然排序,Student 类实现 Comparable 接口,而且所有的 key 应该是同一个类的对象,否则将会抛出 ClassCastException 异常。

TreeSet定制排序

创建 TreeMap 时,构造器传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要使用 Map 接口的 key 实现 Comparable 接口。

【实例 2】创建集合和 Student 类,使用 TreeSet 实现定制排序,代码如下:
import java.util.Objects;

public class Student02 {
    private Integer id;
    private String name;
    private Integer age;
    public Student02(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public Student02() {
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student02 student = (Student02) o;
        return Objects.equals(id, student.id) &&
               Objects.equals(name, student.name) &&
               Objects.equals(age, student.age);
    }
    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
    @Override
    public String toString() {
        return "Student{" +
               "id=" + id +
               ", name='" + name + '\'' +
               ", age=" + age +
               '}';
    }
}

import java.util.Comparator;
import java.util.TreeMap;

public class MapDemo03 {
    public static void main(String[] args) {
        Student02 student = new Student02(1, "王五", 20);
        Student02 student02 = new Student02(2, "张三", 30);
        Student02 student03 = new Student02(4, "笑笑", 24);
        Student02 student04 = new Student02(3, "小花", 33);
        Comparator comparator = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Student02 && o2 instanceof Student02){
                    Student02 student02_1 = (Student02)o1;
                    Student02 student02_2 = (Student02)o2;
                    int value = student02_1.getAge() - student02_2.getAge();
                    if(value != 0){
                        return value;
                    }
                    return student02_1.getName().compareTo(student02_2.getName());
                }
                throw new RuntimeException("输入的类型不匹配");
            }
        };
        TreeMap treeMap = new TreeMap<>(comparator);
        treeMap.put(student, "01");
        treeMap.put(student02, "02");
        treeMap.put(student03, "03");
        treeMap.put(student04, "04");
        System.out.println(treeMap);
    }
}
执行结果是:

{Student{id=1, name='王五', age=20}=01, Student{id=4, name='笑笑', age=24}=03, Student{id=2, name='张三', age=30}=02, Student{id=3, name='小花', age=33}=04}

在上述代码中,Student02 类不需要实现 Comparable 接口,只要实现 Comparator 接口,就可以实现定制排序。TreeMap 判断两个 key 相等的标准是,两个 key 通过 c ompareTo() 方法或 compare() 方法返回 0。

相关文章