Java集合(6):TreeSet

一.TreeSet介绍

  与HashSet是基于HashMap实现一样,TreeSet是基于TreeMap实现的。TreeSet是一个有序集合,TreeSet中的元素将按照升序排列,缺省是按照自然排序进行排列,Integer能排序(有默认顺序), String能排序(有默认顺序), 如果想把自定义类的对象存入TreeSet进行排序, 那么必须实现Comparable接口。或者有一个自定义的比较器。我们可以在构造TreeSet对象时,传递实现Comparator接口的比较器对象。

1.TreeSet的继承关系

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable

2.TreeSet的类图关系如下:

  通过源码我们知道TreeSet继承自AbstractSet,实现了NavigableSet、Cloneable、Serializable接口。其中AbstractSet提供 Set 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。NavigableSet是扩展的 SortedSet,具有了为给定搜索目标报告最接近匹配项的导航方法,这就意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。Cloneable支持克隆,Serializable支持序列化。

二.TreeSet源码解析

1.私有属性

1 private transient NavigableMap<E,Object> m;
2
3 //PRESENT会被当做Map的value与key构建成键值对
4 private static final Object PRESENT = new Object();

2.TreeSet的构造方法

 1 //默认构造方法,根据其元素的自然顺序进行排序
 2 public TreeSet() {
 3     this(new TreeMap<E,Object>());
 4 }
 5
 6 //构造一个包含指定 collection 元素的新 TreeSet,它按照其元素的自然顺序进行排序。
 7 public TreeSet(Comparator<? super E> comparator) {
 8         this(new TreeMap<>(comparator));
 9 }
10
11 //构造一个新的空 TreeSet,它根据指定比较器进行排序。
12 public TreeSet(Collection<? extends E> c) {
13     this();
14     addAll(c);
15 }
16
17 //构造一个与指定有序 set 具有相同映射关系和相同排序的新 TreeSet。
18 public TreeSet(SortedSet<E> s) {
19     this(s.comparator());
20     addAll(s);
21 }
22
23 TreeSet(NavigableMap<E,Object> m) {
24     this.m = m;
25 }

3.其他方法

3.1 add

public boolean add(E e)

将指定的元素添加到此 set(如果该元素尚未存在于 set 中)。

3.2 addAll

public  boolean addAll(Collection<? extends E> c)

将指定 collection 中的所有元素添加到此 set 中。

3.3 remove

public boolean remove(Object o)

将指定的元素从 set 中移除(如果该元素存在于此 set 中)。

3.4 clear

public void clear()

移除此 set 中的所有元素。

3.5 clone

public Object clone()

返回 TreeSet 实例的浅表副本。属于浅拷贝。

3.6 size

public int size()

返回 set 中的元素数(set 的容量)。

3.7 isEmpty

public boolean isEmpty()

如果此 set 不包含任何元素,则返回 true。

3.8 comparator

public Comparator<? super E> comparator()

返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。

3.9 contains

public boolean contains(Object o)

如果此 set 包含指定的元素,则返回 true。

3.10 iterator

public Iterator<E> iterator()

返回在此 set 中的元素上按升序进行迭代的迭代器。

3.11 first

public E first()

返回此 set 中当前第一个(最低)元素。

3.12 last

public E last()

返回此 set 中当前最后一个(最高)元素。

3.13 higher

public E higher(E e)

返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 null。

3.14 lower

public E lower(E e)

返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null。

3.15 ceiling

public E ceiling(E e)

返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null。

3.16 floor

public E floor(E e)

返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。

还有一些其他的方法,太多了,这里就不写了,都快写成中文API了,上面这些都是些较为常用的方法,其他的方法用到的时候查下源码吧。

三.TreeSet使用示例

1.String 类的排序

 1 public class TreeSetTest {
 2     public static void main(String[] args) {
 3         Set ts = new TreeSet();
 4         ts.add("abc");
 5         ts.add("xyz");
 6         ts.add("rst");
 7         Iterator it = ts.iterator();
 8         while (it.hasNext()) {
 9             System.out.println(it.next());
10         }
11     }
12 }
输出结果:
abc
rst
xyz

打印结果不是和先前加入的顺序一样,它是按照一个字母的排序法进行排序的。这是因为String 类实现了Comparable接口。

2.自定义类的排序

如果我们自己定义的一个类的对象要加入到TreeSet当中,那么这个类必须要实现Comparable接口。

 1 public class test_treeset {
 2      @SuppressWarnings("unchecked")
 3     public static void main(String[] args) {
 4             Set ts = new TreeSet();
 5             ts.add(new Teacher("zhangsan", 1));
 6             ts.add(new Teacher("lisi", 2));
 7             ts.add(new Teacher("wangmazi", 3));
 8             ts.add(new Teacher("wangwu",4));
 9             ts.add(new Teacher("mazi", 3));
10             Iterator it = ts.iterator();
11             while (it.hasNext()) {
12                 System.out.println(it.next());
13             }
14         }
15 }
16 class Teacher implements Comparable {
17     int num;
18     String name;
19
20     Teacher(String name, int num) {
21         this.num = num;
22         this.name = name;
23     }
24
25     public String toString() {
26         return "学号:" + num + "\t\t姓名:" + name;
27     }
28
29     //o中存放时的红黑二叉树中的节点,从根节点开始比较
30     public int compareTo(Object o) {
31         Teacher ss = (Teacher) o;
32         int result = num < ss.num ? 1 : (num == ss.num ? 0 : -1);//降序
33         //int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);//升序
34         if (result == 0) {
35             result = name.compareTo(ss.name);
36         }
37         return result;
38     }
39 }
运行结果:
学号:4 姓名:wangwu
学号:3    姓名:mazi
学号:3    姓名:wangmazi
学号:2    姓名:lisi
学号:1    姓名:zhangsan

注意:如果将int result = num > ss.num ? 1 : (num == ss.num ? 0 : -1);写成了int result = ss.num > num ? 1 : (ss.num == num ? 0 : -1);那么得到的结果就是倒序排列的,并不是升序的。

3.比较器

  在使用TreeSet对加入到其中的元素进行排序的时候可以像Arrays对数组中的元素进行排序和Collections对集合中的元素进行排序一样,传递一个比较器。

  构造一个新的空TreeSet,它根据指定比较器进行排序。插入到该 set 的所有元素都必须能够由指定比较器进行相互比较:对于 set 中的任意两个元素 e1 和e2,执行 comparator.compare(e1, e2) 都不得抛出 ClassCastException。如果用户试图将违反此约束的元素添加到 set 中,则 add 调用将抛出 ClassCastException。

 1 class Teacher {
 2     int num;
 3     String name;
 4
 5     Teacher(String name, int num) {
 6         this.num = num;
 7         this.name = name;
 8     }
 9
10     public String toString() {
11         return "学号:" + num + "    姓名:" + name;
12     }
13
14     static class TeacherCompare implements Comparator {// 老师自带的一个比较器
15         public int compare(Object o1, Object o2) {
16             Teacher s1 = (Teacher) o1;// 转型
17             Teacher s2 = (Teacher) o2;// 转型
18             int result = s1.num > s2.num ? 1 : (s1.num == s2.num ? 0 : -1);
19             if (result == 0) {
20                 result = s1.name.compareTo(s2.name);
21             }
22             return result;
23         }
24     }
25 }
运行结果:
学号:1 姓名:lisi
学号:2 姓名:zhangsan
学号:3 姓名:mazi
学号:3 姓名:wangmazi

参考:http://cmsblogs.com/?p=1162

http://www.cnblogs.com/meng72ndsc/archive/2010/12/23/1914477.html

时间: 2024-08-12 06:56:16

Java集合(6):TreeSet的相关文章

java 集合框架(TreeSet操作,自动对数据进行排序,重写CompareTo方法)

/*TreeSet * treeSet存入数据后自动调用元素的compareTo(Object obj) 方法,自动对数据进行排序 * 所以输出的数据是经过排序的数据 * 注:compareTo方法返回值有:负数,零,正数.分别表示小于,等于,大于 * 对于存入自定义的对象元素,要重写元素的compareTo(Object obj)方法 * 元素定义时,需要实现Comparable接口 * */ 1 import java.util.Iterator; 2 import java.util.Tr

java 集合框架-TreeSet

/* TreeSet可以对Set集合中的对象进行排序: 原理,TreeSet在底层调用了Comparable接口的方法compareTo(). 所以,在使用TreeSet存储自定义对象时,要想实现自定义类对象的自然排序,需要类实现Comparable接口,并重写覆盖接口唯一的方法compareTo(). 需求: 往TreeSet集合中存储自定义对象学生. 想按照学生的年龄进行排序. 记住:排序时,当主要条件相同时,一定判断一下次要条件. 在本例中,出现了两个同学的年龄是一样的,如果不进行判断次要

死磕 java集合之TreeSet源码分析

问题 (1)TreeSet真的是使用TreeMap来存储元素的吗? (2)TreeSet是有序的吗? (3)TreeSet和LinkedHashSet有何不同? 简介 TreeSet底层是采用TreeMap实现的一种Set,所以它是有序的,同样也是非线程安全的. 源码分析 经过前面我们学习HashSet和LinkedHashSet,基本上已经掌握了Set实现的套路了. 所以,也不废话了,直接上源码: package java.util; // TreeSet实现了NavigableSet接口,所

java 集合框架-TreeSet练习

import java.util.*; /* 练习:按照字符串长度排序. 字符串本身具备比较性,但是它的比较方式不是所需要的.这时就只能使用比较器 注意:在方式二中: int num=new Integer(str1.length()).compareTo(new Integer(str2.length())); 此时num的值有三种可能.正数.负数.零.千万不要写下面的代码: if(num==1) return 1; num不一定等于1.我们在函数中返回的0,1,-1只是代表三种情况:零,正数

死磕 java集合之终结篇

概览 我们先来看一看java中所有集合的类关系图. 这里面的类太多了,请放大看,如果放大还看不清,请再放大看,如果还是看不清,请放弃. 我们下面主要分成五个部分来逐个击破. List List中的元素是有序的.可重复的,主要实现方式有动态数组和链表. java中提供的List的实现主要有ArrayList.LinkedList.CopyOnWriteArrayList,另外还有两个古老的类Vector和Stack. 关于List相关的问题主要有: (1)ArrayList和LinkedList有

Java集合框架总结(3)——TreeSet类的排序问题

Java集合框架总结(3)--TreeSet类的排序问题 TreeSet支持两种排序方法:自然排序和定制排序.TreeSet默认采用自然排序. 1.自然排序 TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,这种方式就是自然排序.(比较的前提:两个对象的类型相同). java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现该接口的类必须实现该

java 17 - 9 HashSet集合、TreeSet集合的练习

HashSet集合的练习 1 package zl_TreeSetTest; 2 /* 3 创建学生类 4 成员变量: 5 A:姓名 6 B:语文成绩 数学成绩 英语成绩 7 */ 8 public class Student { 9 private String name ; 10 private int chinese; 11 private int english; 12 private int math; 13 14 public Student() { 15 super(); 16 /

Java 集合系列 17 TreeSet

java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例 Java 集合系列 05 Vector详细介绍(源码解析)和使用示例 Java 集合系列 06 Stack详细介绍(源码解析)和使用示例 Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和

Java 集合系列17之 TreeSet详细介绍(源码解析)和使用示例

概要 这一章,我们对TreeSet进行学习.我们先对TreeSet有个整体认识,然后再学习它的源码,最后再通过实例来学会使用TreeSet.内容包括:第1部分 TreeSet介绍第2部分 TreeSet数据结构第3部分 TreeSet源码解析(基于JDK1.6.0_45)第4部分 TreeSet遍历方式第5部分 TreeSet示例 转载请注明出处:http://www.cnblogs.com/skywang12345/admin/EditPosts.aspx?postid=3311268 第1部