前面里已经说过了,Set接口的实现类一般有HashSet和TreeSet,一般使用的都是HashSet,我们这一节还是来学习一下TreeSet的使用:
TreeSet底层使用TreeMap实现的,内部维持了一个简化版的TreeMap(对比一下,HashSet底层是用HashMap实现的)。TreeSet内部需要对存储的元素进行排序,如果是默认的话,一样会根据key来进行排序,如果是自定义的类,对应实现Comparable接口,这样才能根据compareTo()方法比较对象之间的大小,然后进行内部排序。
TreeMap的使用,在前面也有记录(TreeMap的使用和底层源码),以及comparable接口。因为TreeMap相比HashMap就是在输出需要根据key排序的时候才会用到,因此对应到TreeSet也就一样。
我们来测试TreeSet的使用:
一、TreeSet的使用
首先定义一个TreeSet:
Set<Integer> set=new TreeSet<>();
这时就可以点开TreeSet源码来看:
可以看到他就是用TreeMap实现的。
接着我们无序加入三个元素:
set.add(123);
set.add(2312);
set.add(300);
然后输出他:
for(Integer integer:set) {
System.out.println(integer);
}
我们在TreeMap输出的时候,需要用keySet方法获得key的,但是现在keySet类里面只有一个元素,for语句里面针对的属性名就可以直接只写个set了。
输出结果是这样的:
可以看到,已经有了递增的顺序。
对于TreeMap的排序,如果不是默认key,在key的位置是自己定义的类,就需要用到实现comparable接口,来进行顺序实现,对于TreeSet也是一样:
二、对于Set里的元素为自定义的类,实现Comparable接口
我们首先自定义一个类,注意是要implements comparable接口的,在其中定义属性和默认的构造方法,然后重写toString方法方便输出,接着最重要的就是要实现compareTo接口,传入自己写的类,返回0、1或者-1表示比较大小的结果。
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;
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("["+"id:"+this.id+",name:"+this.name+",salary:"+this.salary+"]");
return stringBuilder.toString();
}
public int compareTo (Employee e) {
if (this.salary>e.salary) {
return 1;
}else if (this.salary<e.salary) {
return -1;
}else {
if (this.id>e.id) {
return 1;
}else if (this.id<e.id) {
return -1;
}else {
return 0;
}
}
}
}
接下来我们在创建自己的TreeSet对象的时候,可以传入的元素就是每一个Employee类型的对象:
Set<Employee> set2=new TreeSet<>();
set2.add(new Employee(123, "Mary", 2000));
set2.add(new Employee(124, "Jenny", 2000));
set2.add(new Employee(124, "Tom", 1000));
set2.add(new Employee(127, "Raj", 5000));
然后,在输出的时候,就会自动进行排序了,那么我们在实现compareTo接口的时候是比较的salary优先,因为我们希望按照这个来升序排序,在salary相等的时候用id进行排序,然后输出。另外重写了toString方法对每一个元素的输出格式进行了限制,这样我们在新定义的TreeSet进行输出:
for(Employee employee:set2) {
System.out.println(employee.toString());
}
结果是这样:
可以看到,确实达到了目的。