TreeSet
集合
继承关系图和构造器
基本介绍:
当我们使用无参构造器,创建TreeSet
时,仍然是无序的
当我们需要按照某种方式进行排序时,需要使用TreeSet
提供的一个构造器,可以传入一个比较器【匿名内部类】并指定排序规则
TreeSet
构造器
Constructor and Description |
---|
TreeSet() 构造一个新的,空的树组,根据其元素的自然排序进行排序。 【也就是相当于无序的】 |
TreeSet(Collection<? extends E> c) 构造一个包含指定集合中的元素的新树集,根据其元素的 自然排序进行排序 。 |
TreeSet(Comparator<? super E> comparator) 构造一个新的,空的树集,根据指定的比较器进行排序。【自定排序规则】 |
TreeSet(SortedSet<E> s) 构造一个包含相同元素的新树,并使用与指定排序集相同的顺序。 |
方法摘要
Modifier and Type | Method and Description |
---|---|
boolean | add(E e) 将指定的元素添加到此集合(如果尚未存在)。 |
boolean | addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合中。 |
E | ceiling(E e) 返回此集合中最小元素大于或等于给定元素,如果没有此元素,则返回 null 。 |
void | clear() 从此集合中删除所有元素。 |
Object | clone() 返回此 TreeSet 实例的浅拷贝。 |
Comparator<? super E> | comparator() 返回用于对该集合中的元素进行排序的比较器,或null, 如果此集合使用其元素的natural ordering 。 |
boolean | contains(Object o) 如果此集合包含指定的元素,则返回 true 。 |
Iterator<E> | descendingIterator() 以降序返回该集合中的元素的迭代器。 |
NavigableSet<E> | descendingSet() 返回此集合中包含的元素的反向排序视图。 |
E | first() 返回此集合中当前的第一个(最低)元素。 |
E | floor(E e) 返回此集合中最大的元素小于或等于给定元素,如果没有这样的元素,则返回 null 。 |
SortedSet<E> | headSet(E toElement) 返回此集合的部分的视图,其元素严格小于 toElement 。 |
NavigableSet<E> | headSet(E toElement, boolean inclusive) 返回该集合的部分的视图,其元素小于(或等于,如果 inclusive 为真) toElement 。 |
E | higher(E e) 返回严格大于给定元素的该集合中的最小元素,如果没有此元素则返回 null 。 |
boolean | isEmpty() 如果此集合不包含元素,则返回 true 。 |
Iterator<E> | iterator() 以升序返回该集合中的元素的迭代器。 |
E | last() 返回此集合中当前的最后(最高)元素。 |
E | lower(E e) 返回这个集合中最大的元素严格小于给定的元素,如果没有这样的元素,则返回 null 。 |
E | pollFirst() 检索并删除第一个(最低)元素,或返回 null 如果该集合为空。 |
E | pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 。 |
boolean | remove(Object o) 如果存在,则从该集合中删除指定的元素。 |
int | size() 返回此集合中的元素数(其基数)。 |
Spliterator<E> | spliterator() 在此集合中的元素上创建*late-binding和故障切换* Spliterator 。 |
SortedSet<E> | subSet(E fromElement, E toElement) 返回此集合的部分的视图,其元素的范围从 fromElement (含)到 toElement ,排他。 |
SortedSet<E> | tailSet(E fromElement) 返回此组件的元素大于或等于 fromElement 的部分的视图。 |
NavigableSet<E> | tailSet(E fromElement, boolean inclusive) 返回此集合的部分的视图,其元素大于(或等于,如果 inclusive 为真) fromElement 。 |
TreeSet
源码剖析
package collection_.collectionP.set_;
import java.util.Comparator;
import java.util.TreeSet;
/**
* @author: 海康
* @version: 1.0
*/
public class TreeSetSource {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String str1 = (String) o1;
String str2 = (String) o2;
return str1.compareTo(str2);
// return str1.length() - str2.length();
}
});
// TreeSet treeSet = new TreeSet();
treeSet.add("海康");
treeSet.add("湛江");
treeSet.add("海康");
System.out.println(treeSet);
/**
* 源码剖析:
* 第一步:
* TreeSet底层是TreeMap,所以在TreeMap中完成:对比较器的初始化:private final Comparator<? super K> comparator;
* 在追TreeSet的构造顺底层其实TreeMap
* public TreeMap(Comparator<? super K> comparator) {
* this.comparator = comparator;
* }
*
* public TreeSet(Comparator<? super E> comparator) {
* this(new TreeMap<>(comparator));
* }
*
* 第二步:执行add方法
* public boolean add(E e) {
* return m.put(e, PRESENT)==null;
* //PRESENT其实是 :private static final Object PRESENT = new Object();
* }
*
* 往put方法中继续追
* public V put(K key, V value) {//传入key 和 PRESENT [PRESENT其实是占位符]
* Entry<K,V> t = root;// private transient Entry<K,V> root; 当集合为空时,root必须为空
* if (t == null) {//这里是当集合为空时,才会执行
* compare(key, key); // type (and possibly null) check
*
* root = new Entry<>(key, value, null);
* size = 1; 表示集合大小为了1
* modCount++; 表示修改了一次
* return null; 返回null值表示修改成功
* }
* int cmp;
* Entry<K,V> parent;
* // split comparator and comparable paths
* Comparator<? super K> cpr = comparator; // 将比较器引用赋给 cpr
* if (cpr != null) { 如果比较器不为 null
* do {
* parent = t;
* cmp = cpr.compare(key, t.key);
* if (cmp < 0) 当比较小于 0 则放在左边
* t = t.left;
* else if (cmp > 0) 当比较大于 0 则放在右边
* t = t.right;
* else //如果比较器返回的值相等,则将原来的替换掉,并返回原来的值
* return t.setValue(value);
* } while (t != null);
* }
* else { 如果比较器为空时 则执行这里
* if (key == null)
* throw new NullPointerException();
* @SuppressWarnings("unchecked")
* Comparable<? super K> k = (Comparable<? super K>) key;
* do {
* parent = t;
* cmp = k.compareTo(t.key);
* if (cmp < 0)
* t = t.left;
* else if (cmp > 0)
* t = t.right;
* else
* return t.setValue(value);
* } while (t != null);
* }
* Entry<K,V> e = new Entry<>(key, value, parent);
* if (cmp < 0)
* parent.left = e;
* else
* parent.right = e;
* fixAfterInsertion(e);
* size++;
* modCount++;
* return null;
* }
*
*
* public V setValue(V value) { 如果比较器返回的值相等,则将原来value的替换掉,并返回原来的值value
* V oldValue = this.value;
* this.value = value;
* return oldValue;
* }
*/
}
}
注意:当使用比较器时,比较器比较后返回的值相等,则将原来的value值替换掉,并返回原来的value值
package com.hspedu.set_;
import java.util.Comparator;
import java.util.TreeSet;
@SuppressWarnings({"all"})
public class TreeSet_ {
public static void main(String[] args) {
//1. 当我们使用无参构造器,创建TreeSet时,仍然是无序的
//2. 希望添加的元素,按照字符串大小来排序
//3. 使用TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)
// 并指定排序规则
//4. 简单看看源码
//老韩解读
/*
1. 构造器把传入的比较器对象,赋给了 TreeSet的底层的 TreeMap的属性this.comparator
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
2. 在 调用 treeSet.add("tom"), 在底层会执行到
if (cpr != null) {//cpr 就是我们的匿名内部类(对象)
do {
parent = t;
//动态绑定到我们的匿名内部类(对象)compare
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else //如果相等,即返回0,这个Key就没有加入
return t.setValue(value);
} while (t != null);
}
*/
// TreeSet treeSet = new TreeSet();
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//下面 调用String的 compareTo方法进行字符串大小比较
//如果要求加入的元素,按照长度大小排序
//return ((String) o2).compareTo((String) o1);
return ((String) o1).length() - ((String) o2).length();
}
});
//添加数据.
treeSet.add("jack");
treeSet.add("tom");//3
treeSet.add("sp");
treeSet.add("a");
treeSet.add("abc");//3
System.out.println("treeSet=" + treeSet);
}
}