我们前面知道,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