黑马程序员--07.集合框架--07.【TreeSet】【TreeSet底层的二叉树】
来源:互联网 发布:怎么搭建linux测试环境 编辑:程序博客网 时间:2024/05/29 11:12
集合框架--7
TreeSet概述 TreeSet底层的二叉树
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1. TreeSet概述
(1). Set常用子类的回顾
[1]. Set集合具有无序性和唯一性
[2]. HashSet 底层数据结构是哈希表,线程非同步。
保证元素唯一性的办法就是调用元素的hashCode方法和equals方法
[3]. TreeSet 底层数据结构是二叉树,线程非同步。
【TreeSet的优势】可以对元素进行排序
【TreeSet的无序性】由于TreeSet会对添加的元素进行排序,所以这一般会和添加元素的顺序不一致,这样就会导致从TreeSet中取出元素的顺序和存入时候的顺序不一致。所以说是无序的。
(2). TreeSet产生的一个异常
【产生异常的原因】
TreeSet能够进行排序。但是自定义的Person类并没有给出排序的规则。即普通的自定义类不具备排序的功能,所以要实现Comparable接口。
(3). 让TreeSet中存储的元素具有比较性 ----实现Comparable接口
[1]. Comparable接口的原型
public interface Comparable<T>{
public int compareTo(T o);
}
Comparable接口仅仅有一个方法需要实现,compareTo方法需要被子类实现。
[2]. Comparable接口的描述:
Compares this object with the specifiedobject for order.
Returns a negative integer, zero, or apositive integer as this object is less than,equal to, or greater than the specified object
翻译下:因为这个对象(指的是实现Comparable接口的类的对象) 小于,等于或者大于指定对象,所以,返回一个负数,0或者一个正数。
[注意]当compareTo方法返回0的时候,表示这两个对象相同。
依据Set接口的特点,相同的对象是不能出现在一个Set集合中的,否则有悖于Set集合无序性。
【结论】当两个对象通过compareTo的比较返回0的时候,从compareTo方法参数中接受的对象不能被存入TreeSet集合。
[2]. 示例代码:
import java.util.*;class Student implements Comparable{ private String name; private int age; public Student(String name, int age){ this.name =name; this.age =age; } public String getName(){ return this.name; } public void setName(String name){ this.name =name; } public int getAge(){ return this.age; } public void setAge(int age){ this.age = age; } public String toString(){ return this.name+"::::"+ this.age; } public int compareTo(Object o){ if(!(o instanceof Student)) throw new RuntimeException("This is not a instance of Class \"Student\" "); Students =(Student)o; sop(this.name +"......compareTo...."+ s.name); if(this.age > s.age) return 1; else if(this.age ==s.age) return 0; return -1; } public static void sop(Object o){ System.out.println(o); }} class TreeSetDemo{ public static void sop(Object o){ System.out.println(o); } public static void main(String[] args){ TreeSetts =new TreeSet(); ts.add(new Student("lisi02", 22)); ts.add(new Student("lisi007", 20)); ts.add(new Student("lisi09", 19)); Iteratorit =ts.iterator(); while(it.hasNext()){ sop(it.next()); } }}
打印结果:
除了第一个元素添加进来的时候,没有调用compareTo()方法,其余的元素添加进来的时候,TreeSet都调用了这些元素的compareTo方法。
输出的时候,这些元素都被按照年龄来排序输出。
(4). 细化排序的条件
[1]. 现在将数据变化一下,多加入一个元素:
ts.add(new Student("lisi02", 22));ts.add(new Student("lisi007", 20));ts.add(new Student("lisi09", 19));ts.add(new Student("lisi08", 19));
也就是添加了两个年龄一样的Student对象。
【产生的问题】发现lisi08在被TreeSet添加的时候,确实调用了这个元素的compareTo方法。但是最后TreeSet集合中却没有加入这个元素。
【产生的原因】因为当;lisi08......compareTo....lisi09打印的时候,说明这两个元素进行了比较。但是,比较的时候,两者的年龄均为19,所以elseif(this.age ==s.age)这个分支执行,返回0。
返回0就意味着TreeSet判定这两个对象是一样的,就不能被存入集合中。
[2]. 细化判断条件
【要点】当主要条件相同的时候,一定要判断次要条件。
这里面,只有当Student类的年龄和姓名都一样的时候,才应该被视为是同一个对象。所以当年龄相同的时候,应该继续判断这两个对象的姓名是否相同。
修改代码示例:
public int compareTo(Object o){ if(!(o instanceof Student)) throw new RuntimeException("This is not a instance of Class \"Student\" "); Students =(Student)o; sop(this.name +"......compareTo...."+ s.name); if(this.age > s.age) return 1; else if(this.age ==s.age) return this.name.compareTo(s.getName()); return -1;}
打印结果:
可以看到年龄相同但是姓名不同的lisi08和lisi09都被成功地添加到TreeSet集合中来。
2. TreeSet底层的二叉树
1). TreeSet的二叉树存储元素的过程
(1). 示例代码
TreeSet ts =new TreeSet();ts.add(new Student("lisi02", 22));ts.add(new Student("lisi007", 20));ts.add(new Student("lisi09", 19));ts.add(new Student("lisi08", 19));ts.add(new Student("lisi11", 40));ts.add(new Student("lisi16", 30));ts.add(new Student("lisi12", 36));ts.add(new Student("lisi10", 29));ts.add(new Student("lisi22", 90));
(2). 存储过程分析
[1]. 先存入一个元素22。
[2]. 20进来时,调用自身的compareTo方法,要和22比较。发现20 <22,compareTo返回负数,此时存入二叉树的左边。如图:
[3]. 19进来,先和22比较一下。19 <22,返回负数。此时19往22的左边走。22的左边还有一个20,再次比较一下:19 < 20, 19也放在20的左边。如图:
[4]. 有一个lisi08—19的元素要加入进来。分别和22, 20比较之后,compareTo方法都返回负数。这个元素要放在22, 20的左边。当lisi08—19和已存在的lisi09—19比较的时候,TreeSet发现两者的年龄相同,又一次调用returnthis.name.compareTo(s.getName()); 结果lisi08—19所在的compareTo返回负数(字符串lisi08 < lisi09)。则此时lisi08—19仍然放到lisi09—19的左边。如图:
[5]. "lisi11", 40进来。和22比较之后,40 > 22, compareTo返回正数。放在22的右边。【这样减少了很多次的比较】。如图:
[6].30 >22--->放在22的右边 30 <40--->放在40的左边。如图:
[7].36 >22--->放在22的右边 36 <40--->放在40的左边 36 > 30--->放在30的右边。如图:
[8].29 >22--->放在22的右边 29 <40--->放在40的左边 29 < 30--->放在30的左边。如图:
[9].90 >22--->放在22的右边 90 > 40--->放在40的右边。如图:
打印结果:【TreeSet内部存在了优化, 将lisi007---20作为了根节点】
【二叉树的优势】减少了比较的次数。
(3). 取出过程分析
[1]. 根元素的左叉的数 <右叉的数 先遍历左边
[2]. 再遍历右边
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
- 黑马程序员--07.集合框架--07.【TreeSet】【TreeSet底层的二叉树】
- 黑马程序员--07.集合框架--08.【TreeSet的Comparator排序】【TreeSet总结】
- 黑马程序员——17,集合,TreeSet,二叉树,泛型
- 黑马程序员-集合框架【TreeSet】、【二叉树】、【Comparable接口】、【Comparator接口】
- [黑马程序员]集合--TreeSet
- 黑马程序员 集合框架之TreeSet实例
- 黑马程序员--java集合TreeSet
- 黑马程序员_Set集合的子类HashSet集合,TreeSet集合
- 黑马程序员——>第十五天<集合框架(TreeSet-泛型)>
- 黑马程序员—Java集合框架(Set、HashSet、TreeSet)
- 黑马程序员——集合框架(TreeSet)
- 黑马程序员:TreeSet的特征
- 黑马程序员 集合ArrayList、HashSet和TreeSet的使用
- 黑马程序员——TreeSet集合添加元素的原理
- TreeSet底层数据结构是二叉树
- 黑马程序员--集合之HashSet/TreeSet原理
- 黑马程序员——TreeSet集合
- 集合框架--TreeSet集合
- ArcGIS10.0和Oracle10g的空间数据管理平台(C#开发)-ArcGIS_Engine中的数据访问
- Spinner 改变字体,颜色等...
- CTS测试与GTS测试区别
- 【js学习笔记-043】-- ECMAScript5数组方法
- what is the purpose of using translatable in Android strings?
- 黑马程序员--07.集合框架--07.【TreeSet】【TreeSet底层的二叉树】
- 2013年7月25日更新
- 深度探索智能指针(SmartPointer)
- S3C2440上LCD驱动 (FrameBuffer)实例开发讲解
- u-boot传递给内核的参数bootargs和命令bootcmd(上)
- UNIX网络编程——UDP缺乏流量控制(改进版)
- iOS应用崩溃日志揭秘
- 第一篇博客
- man手册中echo的用法