首页 > 编程知识 正文

treeset底层实现原理,set实现原理

时间:2023-05-05 17:02:49 阅读:111425 作者:3650

TreeSet是Set接口的另一个实现类,它使用自平衡排序二叉树在内部存储元素。 这样的结构使您可以对元素进行排序,而在TreeSet集合中没有重复的元素。 二叉树是指各节点最多具有2个子节点的顺序树,由各节点及其子节点构成的树称为子树,通常左侧的子节点称为“左子树”,右侧的子节点称为“右子树”。 二叉树中要素的存储结构如图所示。

在实际应用中,二叉树可分为许多种类,如对二叉树进行排序、平衡二叉树等。 TreeSet集合内部使用自平衡排序二叉树。 其特征是,保存的元素按大小排序,可以删除重复的元素。 例如,在一个二叉树中按照13、8、17、17、1、11、15、25的顺序存储8个要素,将二叉树进行排序存储时,如图所示,集合内的存储结构形成树结构。

从图中可以看出,在TreeSet集合中依次收纳要素时,首先将最初收纳的要素放在二叉树的最上面,将之后收纳的要素与最初的要素进行比较,如果比最初的要素小,则将该要素放在左边的部分树上,如果比第1个要素大,则将该要素放在右边的部分树上,依此类推二叉树中已经有17个要素的情况下,集合中有17个要素的情况下,TreeSet会去除重复的要素。

既然了解了二叉树存储元素的原理,我们将在一个案例中展示TreeSet对元素的排序效果,如下例所示。 importjava.util.Iterator;

importjava.util.TreeSet;

公共类扩展{

publicstaticvoidmain (字符串[ ] args ) {

TreeSetts=newTreeSet (; 创建TreeSet集合

ts.add(jack ); 将元素添加到TreeSet集合

ts.add(Helena );

ts.add(Helena );

ts.add(Eve );

Iteratorit=ts.iterator (; 获取迭代器对象

while(it.Hasnext ) ) ) )。

system.out.println(it.next ) );

}

}

}

执行结果: Eve

埃琳娜

杰克

如图所示,迭代器重复的字符串元素按字母顺序打印。 这些元素之所以可以排序,是因为每次将元素存储在TreeSet集合中时,都会将它们与其他元素进行比较,最后插入到有序的对象序列中。 比较集合中的元素时,将调用compareTo ()方法。 此方法是在Comparable接口中定义的,因此必须实现Comparable接口才能对集合中的元素进行排序。 JDK中的大多数类都实现了Comparable接口,并具有Integer、Double、String等接口中的CompareTo )方法。

在TreeSet集合中存储Student类型的对象时,如果Student类没有实现Comparable接口,则无法比较Student类型的对象。 此时,TreeSet集合不知道按什么排序规则对Student对象进行排序,并最终报告程序错误。 因此,要在TreeSet集合中存储Student对象,必须在Student类中实现Comparable接口,如示例所示。 importjava.util.Iterator;

importjava.util.TreeSet;

classtudentimplementscomparable//定义student类实现comparable接口

字符串名称;

输入;

公共结构(string name,intage ) )//创建构造方法

this.name=name;

this.age=age;

}

重写publicStringtoString () Object类的toString )方法,并返回描述信息

返回名称' : ' age;

}

重写公共计算机(objectobj )计算机接口的计算机方法

sudents=(student ) obj; //将比较对象改为Student型

if(this.age-s.age0) )//定义比较方式

返回1;

}

if(this.age-s.age==0) {

return this.name.com Pareto (s.name ); //返回比较结果

}

回退

rn -1;

}

}

public class Example {

public static void main(String[] args) {

TreeSet ts = new TreeSet(); // 创建TreeSet 集合

ts.add(new Student("Jack", 19)); // 向集合中添加元素

ts.add(new Student("Rose", 18));

ts.add(new Student("Tom", 19));

ts.add(new Student("Rose", 18));

Iterator it = ts.iterator();

while (it.hasNext()) {

System.out.println(it.next());

}

}

}

运行结果:Rose:18

Jack:19

Tom:19

例中,Student 类实现了Comparable 接口中的compareTo()方法。在compareTo()方法中,首先先针对age值进行比较,根据比较结果返回-1和1,当age相同时,再对name进行比较。因此,从运行结果可以看出,学生首先按照年龄排序,年龄相同时会按照姓名排序。

有时候,定义的类没有实现Comparable接口或者实现了Comparable接口而不想按照定义的compareTo()方法进行排序。例如,希望字符串可以按照长度来进行排序,这时,可以通过自定义比较器的方式对TreeSet集合中的元素排序,即实现Comparator接口,在创建TreeSet集合时指定比较器。接下来通过一个案例来实现TreeSet集合中字符串按照长度进行排序,如例所示。import java.util.Comparator;

import java.util.Iterator;

import java.util.TreeSet;

class MyComparator implements Comparator { // 定义比较器实现Comparator 接口

public int compare(Object obj1, Object obj2) { // 实现比较方法

String s1 = (String) obj1;

String s2 = (String) obj2;

int temp = s1.length() - s2.length();

return temp;

}

}

public class Example {

public static void main(String[] args) {

TreeSet ts = new TreeSet(new MyComparator()); // 创建TreeSet 对象时传入自定义比较器

ts.add("Jack"); // 向该Set 对象中添加字符串

ts.add("Helena");

ts.add("Eve");

Iterator it = ts.iterator(); // 获取Iterator 对象

// 通过while 循环,逐渐将集合中的元素打印出来

while (it.hasNext()) {

// 如果Iterator 有元素进行迭代,则获取元素并进行打印

Object obj = it.next();

System.out.println(obj);

}

}

}

运行结果:Eve

Jack

Helena

例中,定义了一个MyComparator类实现了Comparator接口,在compare()方法中实现元素的比较,这就相当于定义了一个比较器。在创建TreeSet集合时,将MyComparator比较器对象传入,当向集合中添加元素时,比较器对象的compare()方法就会被自动调用,从而使存入TreeSet集合中的字符串按照长度进行排序。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。