这篇开始,我们来学习Set接口的另外一个实现子类TreeSet。TreeSet一般是需要排序才使用的一种集合存储方式,由于继承了Set接口,TreeSet也能实现元素的唯一。下面通过两个练习来理解TreeSet存储基本的包装类和自定义数据类型的过程。
1.TreeSet存储Integer对象
package treeset;
import java.util.TreeSet;
public class Demo1_TreeSet {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
ts.add(1);
ts.add(1);
ts.add(5);
ts.add(5);
ts.add(3);
ts.add(3);
ts.add(4);
System.out.println(ts);
}
}
运行输出:
[1, 3, 4, 5]
这个代码运行结果,证明了TreeSet是可以保证元素唯一存储和TreeSet是默认按照元素从小到大排序。如果需要对一堆元素进行排序,那么我们就会考虑使用TreeSet集合来存储。
2.TreeSet存储自定义类对象
还是利用前面用过的Person.java这个类
package bean;
public class Person {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
下面,写一个TreeSet存储多个Person对象。
package treeset;
import java.util.TreeSet;
import bean.Person;
public class Demo1_TreeSet {
public static void main(String[] args) {
TreeSet<Person> ts = new TreeSet<>();
ts.add(new Person("张三",23));
ts.add(new Person("李四",24));
ts.add(new Person("王五",25));
System.out.println(ts);
}
}
运行一下,结果报“Exception in thread "main" java.lang.ClassCastException: bean.Person cannot be cast to java.lang.Comparable”。这个异常是类转换异常,我们先来在API中搜索看看Comparable这个接口,这个接口下有一个compareTo()方法,返回是int类型。就是一个两个对象比较顺序的方法。
就像前面我们介绍ArrayList的时候,比较两个自定义对象是否相同,需要重写equals方法,那么我们也在Person下重写compareTo()方法试试。我们让Person类继承Comparable接口,然后重写compareTo()方法。
package bean;
public class Person implements Comparable {
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
return 0;
}
}
然后再次运行Demo1_TreeSet.java这个类,运行输出:[Person [name=张三, age=23]],先不管为什么return 0的时候只有一个元素存储进来了。我们分别把return 0改成 reutrn 1和reutrn -1,看看有什么效果。
1) 改成return 1,运行结果
[Person [name=张三, age=23], Person [name=李四, age=24], Person [name=王五, age=25]]
2) 改成return -1,运行结果
[Person [name=王五, age=25], Person [name=李四, age=24], Person [name=张三, age=23]]
上面的测试结果,这里先记录一下结论。
1)当compareTo方法返回0,集合中只有一个元素
2)当compareTo方法返回正数,集合会怎么存就怎么取的顺序
3)当compareTo方法返回负数,集合就会倒序存取
上面compareTo我们只测试了0 -1 和1,其实正数和负数是符合上面的结论。关于为什么会是这样,TreeSet的原理是什么,下一篇介绍和学习。