TreeSet的定制排序:
这里我们举一个例子来理解TreeSet的定制排序
eg:
package 集合;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo1 {
public static void main(String[] args) {
/*
这里我们使用匿名内部类的方式创建了一个Comparator接口的实现类的对象
*/
Comparator com = new Comparator() {
@Override
/*
这里我们可以发现我们重写这个compare()方法比较的是两个User类中的age属性
*/
public int compare(Object o1, Object o2) {
if(o1 instanceof User&&o2 instanceof User){
User u1 = (User)o1;
User u2 = (User)o2;
return Integer.compare(u1.getAge(),u2.getAge());
}else{
throw new RuntimeException("输入数据与User类型不匹配");
}
}
};
/*
这里我们调用了TreeSet类中的有参构造方法,这个时候参数为我们的Comparator接口的实现类的对象
那么这个时候表示我们要使用定制排序的方式进行排序,这个时候也就是根据compare()方法进行判断
*/
TreeSet t = new TreeSet(com);
t.add(new User("Tom",12));
t.add(new User("mark",12));
t.add(new User("jim",13));
t.add(new User("jack",12));
t.add(new User("Tom",15));
/*
通过这里的输出我们可以发现,我们这里在t中只有"Tom",12 还有 "Tom",15 还有 "jim",13,
这个是因为什么?
因为我们的TreeSet中判断数据是否重复是通过比较器中的方法判断的,也即是这个时候只要我们的两个User类的对象的
age相同,就表示这两个对象重复了,所以我们上面年龄为12岁的User对象都算是重复了
*/
t.forEach(System.out::println);
}
}
class User{
private String name;
private int age;
public User(){
}
public User(String name,int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
这里我们总结以下几点:
- 我们使用定制排序的前提是我们创建了一个Comparator接口的实现类的对象,并且将Comparator实现类的这个对象传入TreeSet的构造方法中
- 这个时候我们使用TreeSet类的有参构造方法,将我们创建的Comparator接口的实现类的对象传入这个构造方法中,这个时候我们就是使用compare()方法进行排序
- 我们使用地址排序不是创建Comparator接口的实现类的对象就可以,我们还要将这个实现类的对象传入TreeSet的构造方法中去,这个时候创建的TreeSet才是使用默认排序方式进行的排序
- 我们使用TreeSet的无参构造方法创建出来的对象就是使用自然排序
- 如果我们要使用定制排序就一定要将我们创建的Comparator接口实现类创建对象,然后将这个对象传入TreeSet类的构造方法中
- 我们建议使用TreeSet集合时一定要在TreeSet集合存储的元素的模板类中实现Comparable接口,并且重写这个接口中的compareTo()方法,在这个基础上我们如果要使用定制排序,这个时候如果我们的自然排序满足不了我们的这个时候的需求,这个时候我们就可以创建一个Comparator接口的实现类的对象,然后再将这个对象传入TreeSet构造方法中去实现我们的定制排序
关于TreeSet自然排序与TreeSet定制排序的总结:
在自然排序中,比较两个对象是否相同的标准为:compareTo()方法的返回值为0,为0则表示重复,而不再是使用equals()方法判断
在定制排序中,比较两个对象是否相同的标准为:Compare()方法的返回值为0.为0则表示重复,而不再是使用equals()方法判断
补充:
我们的包装类中有一个compare()静态方法
- 这里我们以Double类中的compare()方法为例讲解
- public static int compare(double a,double b);
- 这个方法是一个静态方法
- 我们使用这个方法要传入两个double型的参数,这个时候我们的compareTo()方法就会返回一个int类型的值,如果形参a>形参b,这个时候返回1,如果形参a<形参b,这个时候返回-1,如果形参a=形参b ,这个时候返回一个0
- 这里我们只是使用Double类中的compare()方法举了一个例子,这个方法在我们的其他包装类中也有
- 包括我们的Boolean类中也有compare()静态方法