TreeSet详解
TreeSet是Set的子类,TreeSet和Set都是java.util 下的,使用时需要导入java.util包。
Set是collection的子类,collection不能实例化,但是它的子类可以,其关系图为:
现在开始对TreeSet进行分析
使用TreeSet集合的类需要导入一下两个包
import java.util.Set;
import java.util.TreeSet;
TreeSet底层是二叉树,可以对对象元素进行排序,但是自定义类需要实现comparable接口,重写comparaTo() 方法。
TreeSet 可以保存对象元素的唯一性(并不是一定保证唯一性,需要根据重写的compaaTo方法来确定)
1 如图,TreeSet存放简单的同一类型的数据。
“a” “1” “c” “f” 全部都为String字符串,输出结果如上图。
但是如果TreeSet保存的数据类型不同时,输出结果又如何
“a” “1” “f” 为String类型,1为int类型,两种类型不同,执行程序时报java.lang.ClassCastExection异常。
2 上面是TreeSet存放简单类型,如果TreeSet存放对象呢?
创建一个自定义类,里面包含几个属性。上面说过,对象元素进行排序,但是自定义类需要实现comparable接口,重写comparaTo() 方法。
2.1 我们先测试一下没有实现comparable接口,重写compareTo()方法时的现象。
如图,如果自定义类没有实现comparable接口,重写comparaTo()方法,会报java.lang.ClassCastException: person cannot be cast to java.lang.Comparable,java.lang.Comparable说明自定义类需要实现comparable接口,重写comparaTo()方法。
2.2 我们再来测试一下实现comparable接口,重写compareTo()方法时的现象。
现在你会发现,执行程序虽然没有报错,但是明明add了三个对象,结果只输出了一个对象的值。原来,TreeSet的排列顺序与重写的compareTo()方法的返回值有关。
return 0:元素每次进行比较,都认为是相同的元素,这是就不再向TreeSet里面插入除第一个元素以外的元素,所以TreeSet中就只插入了一个元素。
return 1:元素每次进行比较,都认为新插入的元素比上一个元素大,于是二叉树存储时,会储存在根的右侧,读取时就是正序排列,先进先出。
return -1:元素每次进行比较,都认为新插入的元素比上一个元素小,于是二叉树存储时,会储存在根的左侧,读取时就是倒序排列,先进后出。
如图:
上面说过 保存对象元素的唯一性(并不是一定保证唯一性,需要根据重写的compaaTo方法来确定),下面来实验一下:
Add两个p3,输出的时候也输出了两个p3对象,这时就没有保证对象的唯一性。
3 根据重写的compaaTo方法来确定保存对象元素的唯一性。
3.1 根据上述规则,我们可以自定义根据对象的某个属性进行比较。
下面我们根据id进行比较
3.2 根据name(根据unicode大小)进行比较
根据3.1 3.2 可以看出,当根据对象的某一个属性进行排序时,可以确保唯一性。
以上是对TreeSet的测试理解,其中还有许多不理解的地方,例如compareTo()方法内部如何实现排序的,等理解后再来完善文档。