TreeSet
【它比HashSet要难用, TreeSet一定要对元素进行大小的比较】
TreeSet并不是你想用就能用的.
如果添加的集合元素已经实现Comparable接口,恭喜你,可以直接添加到TreeSet中。
如果添加的集合元素没有实现Comparable接口,创建TreeSet必须传入Comparator对象。
也要遵守Set规范,因此它也不允许元素重复。
而且它会自动将所有元素按从小到大的顺序排列。
TreeSet如何对元素排序?两种方式:
1. 自然排序:集合元素必须实现Comparable接口。
Comparable接口中只有一个compareTo(T o)方法,如果该方法返回正整数,表明当前对象大于被比较对象。
如果该方法返回负整数,表明当前对象小于被比较对象。
如果该方法返回0,表明当前对象等于被比较对象。
实际上Java的很多类,比如String、Integer、Date等都实现了Comparable
2. 定制排序:集合元素可以不实现Comparable接口。
或者集合元素实现Comparable接口,但不会起作用
要求创建TreeSet时必须传入Comparator对象。
实现Comparator接口时候,需要实现compare(T o1, T o2)方法,
如果该方法返回正整数,表明o1大于被o2。
如果该方法返回负整数,表明o1小于被o2。
如果该方法返回0,表明o1等于o2。
TreeSet不允许元素重复,怎么的两个元素算重复?
标准为:
A。只要两个对象通过compareTo或者compare()方法比较返回了0,那么这两个对象被TreeSet认为是相等的。
---------------------------TreeSet的高级内容--------------------------
TreeSet的实现原理。
TreeSet的代码其实很少,因为它其实是靠TreeMap实现的。
TreeMap底层是“红黑树”:它是一个半平衡的排序二叉树。
——主要就是可保证添加元素(其实就是添加一个节点)时,性能较好;
取出元素,也能快速取出,因此性能较好。
↗ 平衡排序二叉树—— 调整二叉树的开销非常大
树 → 二叉树→排序二叉树
↘ 半平衡的排序二叉树(红黑树)。折中处理。
排序二叉树的好处是:查找起来性能很好。
但在极端情况下,排序二叉树性能很差。
TreeSet与HashSet,谁的性能更好?
习惯上,我们认为HashSet性能更好。
如果HashSet经常发生重Hash,或HashSet形成了大量的链, TreeSet的性能反而更好。
相比之前,TreeSet有一个额外的好处:它可以自动对集合元素进行排序。
TreeSetTest.java
package com.collection;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<Integer> set = new TreeSet<Integer>();
set.add(20);
set.add(10);
set.add(3);
set.add(100);
//打印的时候会按照从小到大的顺序打印出来
//内部采用红黑树(平衡二叉树)来排序
System.out.println(set);
}
}
TreeSetTest2.java
package com.collection;
import java.util.TreeSet;
class Apple implements Comparable<Apple>{
double weight;
public Apple(double weight){
this.weight = weight;
}
//两个对象是否相等只会依赖于compareTo方法,跟equals方法无关
@Override
public int compareTo(Apple o) {
if(this.weight > o.weight)
return 1;
else if(this.weight == o.weight)
return 0;
else
return -1;
//return 0;
}
//重写toString方法,否则会返回hashCode值
@Override
public String toString(){
return "Apple[weigh="+this.weight+"]";
}
@Override
public boolean equals(Object o){
return true;
}
}
public class TreeSetTest2 {
public static void main(String[] args) {
TreeSet<Apple> set = new TreeSet<Apple>();
set.add(new Apple(2.3));
set.add(new Apple(2.5));
set.add(new Apple(2.0));
System.out.println(set);
}
}