第二篇博客
关于java类集TreeSet的杂谈
既然TreeSet本身是可以排序的,那么它是怎么实现排序的呢?
class Person{
private String name;
private int age;
public Person (String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "姓名:"+this.name+",年龄:"+this.age;
}
}
public class TreeSetDemo {
public static void main(String[] args) {
Set<Person> allset = new TreeSet<Person>();
allset.add(new Person("张三",30));
allset.add(new Person("李四",31));
allset.add(new Person("王五",32));
allset.add(new Person("王五",32));
allset.add(new Person("王五",32));
allset.add(new Person("赵六",33));
allset.add(new Person("孙七",33));
System.out.println(allset);
}
}
运行时出现以下错误:
Exception in thread "main" java.lang.ClassCastException: changmin.blog.Person cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at changmin.blog.TreeSetDemo.main(TreeSetDemo.java:24)
以上程序代码出现了ClassCastException异常,是因为TreeSet中的元素是有序存放,所以对于一个对象必须指定好排序规则,且TreeSet中的每个对象所在的类都必须实现Comparable接口才可以正常使用。
下面我们对Person类指定排序规则
class Person implements Comparable<Person>{
private String name;
private int age;
public Person (String name,int age){
this.name=name;
this.age=age;
}
public String toString(){
return "姓名:"+this.name+",年龄:"+this.age;
}
public int compareTo(Person per){
if (this.age>per.age){
return 1;
}else if (this.age<per.age){
return -1;
}else {
return 0;
}
}
}
指定排序规则后运行结果如下:
[姓名:张三,年龄:30, 姓名:李四,年龄:31, 姓名:王五,年龄:32, 姓名:赵六,年龄:33]
从结果中来看,重复的“王五”对象只有一个了;“赵六”和“孙七”的数据中姓名不重复,只是年龄重复了,但是“孙七”却没有加入到集合中。这是由于采用了比较器造成的,因为比较器操作时如果某个属性没有进行比较的指定,则也会认为是同一个对象,所以此时应该在Person类的compareTo方法中增加按姓名比较。
return this.name.compareTo(per.name)
[姓名:张三,年龄:30, 姓名:李四,年龄:31, 姓名:王五,年龄:32, 姓名:孙七,年龄:33, 姓名:赵六,年龄:33] 增加了“孙七”,同时也没有重复内容,但此时的重复内容的去掉并不是真正意义上的去掉重复元素。因为此时靠的是Comparable完成,如果换成HashSet则也会出现重复的内容。