我的Java学习笔记(26)—容器接口之Map接口3(以TreeMap为实现类)TreeMap的使用和底层源码

本文探讨了Map接口的实现类之一——TreeMap,重点在于其排序功能和如何通过实现Comparable接口对自定义类进行排序。通过实例展示了TreeMap的使用,以及与HashMap、HashTable的区别。在讲解中,解释了compareTo方法在自定义类排序中的作用,并通过代码演示了如何根据salary和id进行排序。
摘要由CSDN通过智能技术生成
我们前面知道,Map接口的实现类有HashMap、TreeMap、HashTable、Properties等等实现类。

前面详细分析并且实现过的HashMap就是最常用的了。TreeMap和HashMap对于调用者来说是没有区别的,HashMap效率相比之下比TreeMap高。

TreeMap是当需要排序的Map时才选用TreeMap(需要Map里的key或者value有序)。

一、TreeMap的使用:

和测试HashMap一样,我们简单定义一个TreeMap类,然后put对应的一些元素:

       Map<Integer, String> trMap =new TreeMap<>();//定义一个TreeMap,泛型填入key和value的类型
       trMap.put(30, "aa");
       trMap.put(15, "bb");
       trMap.put(7, "cc");
       trMap.put(20, "dd");

然后我们用keySet方法获取key字段,然后根据获取到的key进行键值对的输出:

       for(Integer kInteger:trMap.keySet()) {
            System.out.println(kInteger+"---"+trMap.get(kInteger));
       }

可以看到输出结果:

在这里插入图片描述

我们在put的时候并没有按照key递增的方式进行,但是却可以这样输出,这就是所说的排序功能。

这里由于对TreeMap的定义,是integer和String类型,可以对他进行排序,那么这个排序机制对于其他类型的key字段是怎么做的,如果key是我们自定义的类,还能继续进行排序吗?

这个答案涉及到一个叫comparable的接口

二、comparable接口

我们自定义一个Employee类,这个类去给他实现Comparable接口,这个接口需要增加泛型:

class Employee implements Comparable<Employee>{
     int id;
     String name;
     double salary;
     public Employee(int id, String name, double salary) {
           super();
           this.id = id;
           this.name = name;
           this.salary = salary;
     }
}

这个时候已经编译器提示需要重写一个叫compareTo的方法了

 @Override
 public int compareTo(Employee o) {
       // TODO Auto-generated method stub
       return 0;
 }

这个方法里面写明了参数和返回值,具体需要我们自己实现,功能是就是用this对象和指定的对象就是括号里的o进行比较来实现排序,返回一个负数、0、正数,对应小于,等于和大于。

我们重写一下,我们想要优先比较salary,如果相等,再比较id,这样的逻辑去让这个类作为key值的时候进行排序:

 @Override
 public int compareTo(Employee o) {
       // TODO Auto-generated method stub
       if (this.salary<o.salary) {
            return -1;
       }else if (this.salary>o.salary) {
            return 1;
       }else {
            if (this.id<o.id) {
                 return -1;
            }else if (this.id>o.id) {
                 return 1;
            }else {
                 return 0;
            }
       }
 }

这个时候我们再返回去新定义TreeMap对象,然后put一些值再进行输出测试:

       Map<Employee1, String> trMap2=new TreeMap<>();
       trMap2.put(new Employee1(100, "john", 40000),  "good");
       trMap2.put(new Employee1(123, "archie", 450000),  "great");
       trMap2.put(new Employee1(231, "eddie", 43000),  "good");
       
       for(Employee1 employee1:trMap2.keySet()) {
            System.out.println(employee1+"---"+trMap2.get(employee1));
       }

可以看到输出结果:

在这里插入图片描述

显然对应的已经按照salary在排序了(根据后面的good和great看得出来),我们想要前面的输出不是对象地址而是具体内容,我们在这个类里重写一下toString方法:

 @Override
 public String toString() {
       // TODO Auto-generated method stub
       StringBuilder stringBuilder=new StringBuilder();
       stringBuilder.append("["+this.id+","+this.name+","+this.salary+"]");
       return stringBuilder.toString();
 }

这次再运行一下:

在这里插入图片描述
可以看到按照salary进行了排序输出。

三、HashTable

HashTable和HashMap的用法几乎一样,底层实现也是几乎一样,不过HashTable的方法添加了synchronized关键字来确保线程同步检查,所以效率相应较低。

对比HashMap和HashTable

1.HashMap:效率高,线程不安全,允许key或value为null

2.HashTable:线程安全,效率低,不允许key或value为null

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值