java集合系列——Set之HashSet和TreeSet介紹(十)
一.Set的簡介
Set是一個不包含重復元素的 collection。更確切地講,set 不包含滿足 e1.equals(e2) 的元素。對 e1 和 e2,並且最多包含一個為 null 的元素。
Set的類關系圖:
1.繼承於Collection接口,具有增刪查改的方法!
2.AbstractCollection抽象類,實現了Collection接口,並實現了裏面的一些方法,如isEmpty、contains等。
3.Set的兩個實現類,HashSet和TreeSet
- HashSet實現本質其實就是HashMap,HashSet裏面的元素是無序的。
- TreeSet實現本質其實就是TreeSet,TreeSet裏面的元素是有序的。
二.HashSet
1.概述
HashSet實現Set接口,那麽它也是一個不包含重復元素的一個無序的集合,允許使用null,有且僅有一個元素為null!
HashSet也是一個非同步的方法,如果要在多個線程中使用,要註意進行同步封裝!
Set s = Collections.synchronizedSet(new HashSet(...));
HashSet通過iterator()返回的叠代器是fail-fast的。
2.繼承關系和API
HashSet API
類 HashSet<E>
java.lang.Object
繼承者 java.util.AbstractCollection<E>
繼承者 java.util.AbstractSet<E>
繼承者 java.util.HashSet<E>
類型參數:
E - 此 set 所維護的元素的類型
所有已實現的接口:
Serializable, Cloneable, Iterable<E>, Collection<E>, Set<E>
LinkedHashSet繼承了HashSet,實現鏈表的set集合。
(1):構造方法
HashSet()
構造一個新的空 set,其底層 HashMap 實例的默認初始容量是 16,加載因子是 0.75。
HashSet(Collection<? extends E> c)
構造一個包含指定 collection 中的元素的新 set。
HashSet(int initialCapacity)
構造一個新的空 set,其底層 HashMap 實例具有指定的初始容量和默認的加載因子(0.75)。
HashSet(int initialCapacity, float loadFactor)
構造一個新的空 set,其底層 HashMap 實例具有指定的初始容量和指定的加載因子。
(2)方法:
boolean add(E e)
如果此 set 中尚未包含指定元素,則添加指定元素。
void clear()
從此 set 中移除所有元素。
Object clone()
返回此 HashSet 實例的淺表副本:並沒有復制這些元素本身。
boolean contains(Object o)
如果此 set 包含指定元素,則返回 true。
boolean isEmpty()
如果此 set 不包含任何元素,則返回 true。
Iterator<E> iterator()
返回對此 set 中元素進行叠代的叠代器。
boolean remove(Object o)
如果指定元素存在於此 set 中,則將其移除。
int size()
返回此 set 中的元素的數量(set 的容量)。
3.總結
HashSet中含有一個"HashMap類型的成員變量"map,HashSet的操作函數,實際上都是通過map實現的。
有兩種遍歷的方式:
(1)使用 Iterator
第一步:根據iterator()獲取HashSet的叠代器。
第二步:遍歷叠代器獲取各個元素。
for(Iterator iterator = set.iterator();
iterator.hasNext(); ) {
iterator.next();
}
(2)使用foreach
第一步:根據toArray()獲取HashSet的元素集合對應的數組。
第二步:遍歷數組,獲取各個元素。
Object[] object = (String[])set.toArray();
for (Object obj : object)
System.out.printf(obj);
三.TreeSet
1.概述
基於 TreeMap 的 NavigableSet 實現。使用元素的自然順序對元素進行排序,或者根據創建 set 時提供的 Comparator進行排序,具體取決於使用的構造方法。
2.繼承關系和API
TreeSet API
(1)繼承關系:
類 TreeSet<E>
java.lang.Object
繼承者 java.util.AbstractCollection<E>
繼承者 java.util.AbstractSet<E>
繼承者 java.util.TreeSet<E>
類型參數:
E - 此 set 維護的元素的類型
所有已實現的接口:
Serializable, Cloneable, Iterable<E>, Collection<E>, NavigableSet<E>, Set<E>, SortedSet<E>
繼承於AbstractSet,AbstractSet實現了equals和hashcode方法。
實現了NavigableSet接口,意味著它支持一系列的導航方法。比如查找與指定目標最匹配項。
實現了Cloneable接口,意味著它能被克隆。
實現了java.io.Serializable接口,意味著它支持序列化。
(2)構造方法:
TreeSet()
構造一個新的空 set,該 set 根據其元素的自然順序進行排序。
TreeSet(Collection<? extends E> c)
構造一個包含指定 collection 元素的新 TreeSet,它按照其元素的自然順序進行排序。
TreeSet(Comparator<? super E> comparator)
構造一個新的空 TreeSet,它根據指定比較器進行排序。
TreeSet(SortedSet<E> s)
構造一個與指定有序 set 具有相同映射關系和相同排序的新 TreeSet。
(3)方法:
boolean add(E e)
將指定的元素添加到此 set(如果該元素尚未存在於 set 中)。
boolean addAll(Collection<? extends E> c)
將指定 collection 中的所有元素添加到此 set 中。
E ceiling(E e)
返回此 set 中大於等於給定元素的最小元素;如果不存在這樣的元素,則返回 null。
void clear()
移除此 set 中的所有元素。
Object clone()
返回 TreeSet 實例的淺表副本。
Comparator<? super E> comparator()
返回對此 set 中的元素進行排序的比較器;如果此 set 使用其元素的自然順序,則返回 null。
boolean contains(Object o)
如果此 set 包含指定的元素,則返回 true。
Iterator<E> descendingIterator()
返回在此 set 元素上按降序進行叠代的叠代器。
NavigableSet<E> descendingSet()
返回此 set 中所包含元素的逆序視圖。
E first()
返回此 set 中當前第一個(最低)元素。
E floor(E e)
返回此 set 中小於等於給定元素的最大元素;如果不存在這樣的元素,則返回 null。
SortedSet<E> headSet(E toElement)
返回此 set 的部分視圖,其元素嚴格小於 toElement。
NavigableSet<E> headSet(E toElement, boolean inclusive)
返回此 set 的部分視圖,其元素小於(或等於,如果 inclusive 為 true)toElement。
E higher(E e)
返回此 set 中嚴格大於給定元素的最小元素;如果不存在這樣的元素,則返回 null。
boolean isEmpty()
如果此 set 不包含任何元素,則返回 true。
Iterator<E> iterator()
返回在此 set 中的元素上按升序進行叠代的叠代器。
E last()
返回此 set 中當前最後一個(最高)元素。
E lower(E e)
返回此 set 中嚴格小於給定元素的最大元素;如果不存在這樣的元素,則返回 null。
E pollFirst()
獲取並移除第一個(最低)元素;如果此 set 為空,則返回 null。
E pollLast()
獲取並移除最後一個(最高)元素;如果此 set 為空,則返回 null。
boolean remove(Object o)
將指定的元素從 set 中移除(如果該元素存在於此 set 中)。
int size()
返回 set 中的元素數(set 的容量)。
NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive)
返回此 set 的部分視圖,其元素範圍從 fromElement 到 toElement。
SortedSet<E> subSet(E fromElement, E toElement)
返回此 set 的部分視圖,其元素從 fromElement(包括)到 toElement(不包括)。
SortedSet<E> tailSet(E fromElement)
返回此 set 的部分視圖,其元素大於等於 fromElement。
NavigableSet<E> tailSet(E fromElement, boolean inclusive)
返回此 set 的部分視圖,其元素大於(或等於,如果 inclusive 為 true)fromElement。
3.總結
(1)TreeSet中不允許使用null元素!在添加的時候如果添加null,則會拋出NullPointerException異常。
(2)TreeSet是基於TreeMap實現的。TreeSet中的元素支持2種排序方式:自然排序 或者 根據創建TreeSet 時提供的 Comparator 進行排序。這取決於使用的構造方法。
(3)TreeSet是非同步的方法。 它的iterator 方法返回的叠代器是fail-fast的。
(4)TreeSet不支持快速隨機遍歷,只能通過叠代器進行遍歷!
例子:
a.使用Iterator順序遍歷
for(Iterator iter = set.iterator(); iter.hasNext(); ) {
iter.next();
}
b.使用foreach
Object[] object = (Object[])set.toArray();
for (Object obj : object)
System.out.printf(obj);
四.源碼
對TreeSet和HashSet的源碼不再進行剖析,二者分別是基於TreeMap和HashMap實現的,只是對應的節點中只有key,而沒有value,因此對TreeMap和HashMap比較了解的話,對TreeSet和HashSet的理解就會非常容易。
五.總結對比(使用場景)
1.HashSet是一個無序的集合,基於HashMap實現;TreeSet是一個有序的集合,基於TreeMap實現。
2.HashSet集合中允許有null元素,TreeSet集合中不允許有null元素。
3.HashSet和TreeSet都是非同步!在使用Iterator進行叠代的時候要註意fail-fast。
java集合系列——Set之HashSet和TreeSet介紹(十)