欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java集合中的TreeMap使用

程序员文章站 2022-05-20 10:33:14
...

Java集合中的TreeMap使用

存储结构

TreeMap的存储结构和TreeSet都是基于红黑树来实现,通过看源码我们可以知道,TreeSet的底层就是使用了TreeMap,其中TreeSet的add方法也是根据TreeMap的key值来进行添加。我们都知道,红黑树是基于二叉排序树来进一步实现的,也就是说在根节点的左边的值都是小于根节点的值,根节点右边的值都是大于根节点的值,如果插入节点的值在树中已经有了,那么就不会进行重复插入,这也进一步体现了TreeSet和TreeMap的元素是不重复的特性。

注意事项

因为红黑树具有排序的性质,不管key值和value值添加的是何种泛型,我们都需要先进行排序,再进行添加,这也就带来了一个问题。假如我们创建了一个Student类,该类中有学生的姓名和年龄属性。而我们想用此类作为TreeSet的key值,那么怎么样才能对Student类进行排序呢?

我们先来模拟一下这样的场景:

/**
 * TreeMap的使用
 * 存储结构:红黑树
 *
 * @author :twb
 * @// TODO: 2021/3/28
 * @version 1.8
 */
public class Demo1 {
    public static void main(String[] args) {
        TreeMap<Student,String>  treeMap = new TreeMap<>();
        Student s1 = new Student("twb",34);
        Student s2 = new Student("tss",33);
        Student s3= new Student("tzw",28);
        Student s4= new Student("lxk",31);

        //添加元素
        treeMap.put(s1,"邵阳");
        treeMap.put(s2,"衡阳");
        treeMap.put(s3,"常德");
        treeMap.put(s4,"衡阳");

        System.out.println("添加后的元素个数为:"+treeMap.size());
        System.out.println("添加后的元素数为:"+treeMap.toString());//报错
    }
}

在运行了以上 程序以后,编译器开始报错,是哪一句我已经标出来了,错误为:com.HashMap.Student cannot be cast to java.lang.Comparable.

以上错误的大概意思就是类型转换错误,如果我们想要打印出元素,那么就需要对Student需要重写实现compareble接口来重写compare方法.

具体操作如下:

        TreeMap<Student,String>  treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override //重写compare方法
            public int compare(Student o1, Student o2) {
                int n1 = o1.getStuNo()-o2.getStuNo();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1; //如果学号相同则返回姓名比较,否则返回学号比较
            }
        });

当然了,也可以单独对Student类进行操作,具体怎么实现了我就不在这里演示了。

基本使用

/**
 * TreeMap的使用
 * 存储结构:红黑树
 *
 * @author :twb
 * @// TODO: 2021/3/28
 * @version 1.8
 */
public class Demo1 {
    public static void main(String[] args) {
        TreeMap<Student,String>  treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int n1 = o1.getStuNo()-o2.getStuNo();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1;
            }
        });
        Student s1 = new Student("twb",34);
        Student s2 = new Student("tss",33);
        Student s3= new Student("tzw",28);
        Student s4= new Student("lxk",31);

        //添加元素
        treeMap.put(s1,"邵阳");
        treeMap.put(s2,"衡阳");
        treeMap.put(s3,"常德");
        treeMap.put(s4,"衡阳");

        System.out.println("添加后的元素个数为:"+treeMap.size());
        System.out.println("添加后的元素数为:"+treeMap.toString());//Student需要重写实现compareble接口重写compare方法
        //删除元素
//        treeMap.remove(s1);//根据key值删除元素
//        treeMap.remove(s1,"邵阳");// 根据key和value值删除元素
//        treeMap.remove(new Student("tss",33));// 删除匿名类时Student需要重写实现compareble接口重写compare方法
        System.out.println("删除后的元素个数为:"+treeMap.size());

        //遍历
        //keySet遍历
        System.out.println("keySet遍历:");
        Set keySet = treeMap.keySet();
        for(Object key:keySet)
        {
            System.out.println(key+"-->"+treeMap.get(key));
        }
        System.out.println("=====================");
        //entrySet遍历
        System.out.println("entrySet遍历:");
        Set<Map.Entry<Student,String>> entrySets = treeMap.entrySet();
        for(Map.Entry<Student,String> entry:entrySets)
        {
            System.out.println(entry.getKey()+"-->"+entry.getValue());
        }
        //判空
        System.out.println(treeMap.isEmpty()); //false
        //判包含
        System.out.println(treeMap.containsKey(new Student("twb",34)));//true 根据key值来判定
        System.out.println(treeMap.containsValue("长沙"));//false 根据value值来判定
    }
}
添加后的元素个数为:4
添加后的元素数为:{Student{name='tzw', stuNo=28}=常德, Student{name='lxk', stuNo=31}=衡阳, Student{name='tss', stuNo=33}=衡阳, Student{name='twb', stuNo=34}=邵阳}
删除后的元素个数为:4
keySet遍历:
Student{name='tzw', stuNo=28}-->常德
Student{name='lxk', stuNo=31}-->衡阳
Student{name='tss', stuNo=33}-->衡阳
Student{name='twb', stuNo=34}-->邵阳
=====================
entrySet遍历:
Student{name='tzw', stuNo=28}-->常德
Student{name='lxk', stuNo=31}-->衡阳
Student{name='tss', stuNo=33}-->衡阳
Student{name='twb', stuNo=34}-->邵阳
false
true
false

通过遍历我们可以看到以上的元素是以学号进行排序的。