TreeSet详解

TreeSet是Set的子类,TreeSet和Set都是java.util 下的,使用时需要导入java.util包。

Set是collection的子类,collection不能实例化,但是它的子类可以,其关系图为:

 

 TreeSet详解

 

现在开始对TreeSet进行分析

使用TreeSet集合的类需要导入一下两个包

import java.util.Set;

import java.util.TreeSet;

 

TreeSet底层是二叉树,可以对对象元素进行排序,但是自定义类需要实现comparable接口,重写comparaTo() 方法。

TreeSet 可以保存对象元素的唯一性(并不是一定保证唯一性,需要根据重写的compaaTo方法来确定)

 

 

1 如图,TreeSet存放简单的同一类型的数据。

 TreeSet详解

 

 

“a” “1” “c” “f”   全部都为String字符串,输出结果如上图。

但是如果TreeSet保存的数据类型不同时,输出结果又如何

TreeSet详解

 

“a” “1” “f”  为String类型,1为int类型,两种类型不同,执行程序时报java.lang.ClassCastExection异常。

 

 

2 上面是TreeSet存放简单类型,如果TreeSet存放对象呢?

创建一个自定义类,里面包含几个属性。上面说过,对象元素进行排序,但是自定义类需要实现comparable接口,重写comparaTo() 方法。

2.1 我们先测试一下没有实现comparable接口,重写compareTo()方法时的现象。

 TreeSet详解

 

 TreeSet详解

 

 

如图,如果自定义类没有实现comparable接口,重写comparaTo()方法,会报java.lang.ClassCastException: person cannot be cast to java.lang.Comparable,java.lang.Comparable说明自定义类需要实现comparable接口,重写comparaTo()方法。

 

2.2 我们再来测试一下实现comparable接口,重写compareTo()方法时的现象。

 TreeSet详解

 

 TreeSet详解

 

 

现在你会发现,执行程序虽然没有报错,但是明明add了三个对象,结果只输出了一个对象的值。原来,TreeSet的排列顺序与重写的compareTo()方法的返回值有关。

return 0:元素每次进行比较,都认为是相同的元素,这是就不再向TreeSet里面插入除第一个元素以外的元素,所以TreeSet中就只插入了一个元素。

return 1:元素每次进行比较,都认为新插入的元素比上一个元素大,于是二叉树存储时,会储存在根的右侧,读取时就是正序排列,先进先出。

return -1:元素每次进行比较,都认为新插入的元素比上一个元素小,于是二叉树存储时,会储存在根的左侧,读取时就是倒序排列,先进后出。

如图:

 

 TreeSet详解

TreeSet详解

 

 TreeSet详解

 

 

 TreeSet详解

 

 

 

上面说过 保存对象元素的唯一性(并不是一定保证唯一性,需要根据重写的compaaTo方法来确定),下面来实验一下:

 TreeSet详解

 

 

Add两个p3,输出的时候也输出了两个p3对象,这时就没有保证对象的唯一性。

 

3 根据重写的compaaTo方法来确定保存对象元素的唯一性。

3.1 根据上述规则,我们可以自定义根据对象的某个属性进行比较。

下面我们根据id进行比较

 TreeSet详解

TreeSet详解

 

 

 

 

3.2 根据name(根据unicode大小)进行比较

 TreeSet详解

 

 TreeSet详解

 

 

根据3.1 3.2 可以看出,当根据对象的某一个属性进行排序时,可以确保唯一性。

 

以上是对TreeSet的测试理解,其中还有许多不理解的地方,例如compareTo()方法内部如何实现排序的,等理解后再来完善文档。

 

上一篇:java – TreeSet:有效小于值的元素数


下一篇:容器