Iterator
迭代器,所有的collection集合相关的类都可以使用迭代器遍历。迭代器Iterator是一个接口,它提供的API有:
abstract boolean hasNext()
abstract E next()
abstract void remove()
ListIterator
listIterator是一个接口,继承了Iterator接口。由于这个迭代器只适用于List接口的实现类,由list的特殊性,这个迭代器在list的基础上增加了许多方法:
在Iterator的基础上,新增的方法有:
abstract void add(E object)
abstract boolean hasPrevious()
abstract int nextIndex()
abstract E previous()
abstract int previousIndex()
abstract void set(E object)
Map
- Map 是映射接口,Map中存储的内容是键值对(key-value)。
- AbstractMap 是继承于Map的抽象类,它实现了Map中的大部分API。其它Map的实现类可以通过继承AbstractMap来减少重复编码。
- SortedMap 是继承于Map的接口。SortedMap中的内容是排序的键值对,排序的方法是通过比较器(Comparator)。
- NavigableMap 是继承于SortedMap的接口。相比于SortedMap,NavigableMap有一系列的导航方法,如"获取大于/等于某对象的键值对"、“获取小于/等于某对象的键值对”等等。
- TreeMap 继承于AbstractMap,且实现了NavigableMap接口;因此,TreeMap中的内容是“有序的键值对”
- HashMap 继承于AbstractMap,但没实现NavigableMap接口;因此,HashMap的内容是“键值对,但不保证次序”!
- Hashtable 虽然不是继承于AbstractMap,但它继承于Dictionary(Dictionary也是键值对的接口),而且也实现Map接口;因此,Hashtable的内容也是“键值对,也不保证次序”。但和HashMap相比,Hashtable是线程安全的,而且它支持通过Enumeration去遍历。
- WeakHashMap 继承于AbstractMap。它和HashMap的键类型不同,WeakHashMap的键是“弱键”。
Map的API:
abstract void clear()
abstract boolean containsKey(Object key)
abstract boolean containsValue(Object value)
abstract Set<Entry<K, V>> entrySet()
abstract boolean equals(Object object)
abstract V get(Object key)
abstract int hashCode()
abstract boolean isEmpty()
abstract Set<K> keySet()
abstract V put(K key, V value)
abstract void putAll(Map<? extends K, ? extends V> map)
abstract V remove(Object key)
abstract int size()
abstract Collection<V> values()
有一部分来自于collection接口。
-
关于MAPMap提供接口分别用于返回 键集、值集或键-值映射关系集。
- entrySet()用于返回键-值(Map.Entry)集的Set集合
- keySet()用于返回键集的Set集合
- values()用户返回值集的Collection集合
-
因为Map中不能包含重复的键;每个键最多只能映射到一个值。所以,键-值集、键集都是Set,值集时Collection。
-
Map提供了“键-值对”、“根据键获取值”、“删除键”、“获取容量大小”等方法。
package com.xzj;
import java.awt.*;
import java.util.*;
import java.util.Map.Entry;
// @ author :zjxu time:2019-01-14
public class Main {
public static void main(String[] args) {
Map<String, Point> hashMap = new HashMap<>();
hashMap.put("xzj", new Point(23, 326));
hashMap.put("xxx", new Point(23, 325));
hashMap.put("yyy", new Point(23, 324));
hashMap.put("zzz", new Point(23, 327));
Collection<Point> values = hashMap.values();
Iterator iteratorValue = values.iterator();
while (iteratorValue.hasNext()) {
System.out.println(iteratorValue.next().toString());
}
Set<Entry<String, Point>> entrySet = hashMap.entrySet();
Iterator<Entry<String, Point>> iteratorEntry = entrySet.iterator();
while (iteratorEntry.hasNext()) {
System.out.println(iteratorEntry.next().toString());
}
}
}
SortedMap
SortedMap是一个继承于Map接口的接口。它是一个有序的SortedMap键值映射。SortedMap的排序方式有两种:自然排序 、 用户指定比较器。
插入有序 SortedMap 的所有元素都必须实现 Comparable 接口(或者被指定的比较器所接受)。
另外,所有SortedMap 实现类都应该提供 4 个“标准”构造方法:
- void(无参数)构造方法,它创建一个空的有序映射,按照键的自然顺序进行排序。
- 带有一个 Comparator 类型参数的构造方法,它创建一个空的有序映射,根据指定的比较器进行排序。
- 带有一个 Map 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系与参数相同,按照键的自然顺序进行排序。
- 带有一个 SortedMap 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系和排序方法与输入的有序映射相同。无法保证强制实施此建议,因为接口不能包含构造方法。
NavigableMap
NavigableMap是继承于SortedMap的接口。它是一个可导航的键-值对集合,具有了为给定搜索目标报告最接近匹配项的导航方法。 NavigableMap分别提供了获取“键”、“键-值对”、“键集”、“键-值对集”的相关方法。
API如下:
abstract Entry<K, V> ceilingEntry(K key)
abstract Entry<K, V> firstEntry()
abstract Entry<K, V> floorEntry(K key)
abstract Entry<K, V> higherEntry(K key)
abstract Entry<K, V> lastEntry()
abstract Entry<K, V> lowerEntry(K key)
abstract Entry<K, V> pollFirstEntry()
abstract Entry<K, V> pollLastEntry()
abstract K ceilingKey(K key)
abstract K floorKey(K key)
abstract K higherKey(K key)
abstract K lowerKey(K key)
abstract NavigableSet<K> descendingKeySet()
abstract NavigableSet<K> navigableKeySet()
abstract NavigableMap<K, V> descendingMap()
abstract NavigableMap<K, V> headMap(K toKey, boolean inclusive)
abstract SortedMap<K, V> headMap(K toKey)
abstract SortedMap<K, V> subMap(K fromKey, K toKey)
abstract NavigableMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)
abstract SortedMap<K, V> tailMap(K fromKey)
abstract NavigableMap<K, V> tailMap(K fromKey, boolean inclusive)
其中的API大致分为如下几类:
-
提供操作键-值对的方法。
- lowerEntry、floorEntry、ceilingEntry 和 higherEntry 方法,它们分别返回与小于、小于等于、大于等于、大于给定键的键关联的 Map.Entry 对象。
- firstEntry、pollFirstEntry、lastEntry 和 pollLastEntry 方法,它们返回和/或移除最小和最大的映射关系(如果存在),否则返回 null。
-
提供操作键的方法。这个和第1类比较类似。
- lowerKey、floorKey、ceilingKey 和 higherKey 方法,它们分别返回与小于、小于等于、大于等于、大于给定键的键。
-
获取键集。
- navigableKeySet、descendingKeySet分别获取正序/反序的键集。
-
获取键-值对的子集。
AbstractMap
- AbstractMap类提供 Map 接口的骨干实现,以最大限度地减少实现此接口所需的工作。
- 要实现不可修改的映射,编程人员只需扩展此类并提供 entrySet 方法的实现即可,该方法将返回映射的映射关系 set 视图。
- 通常,返回的 set 将依次在 AbstractSet 上实现。此 set 不支持 add() 或 remove() 方法,其迭代器也不支持 remove() 方法。
- 要实现可修改的映射,编程人员必须另外重写此类的 put 方法(否则将抛出 UnsupportedOperationException),entrySet().iterator() 返回的迭代器也必须另外实现其 remove 方法。
AbstractMap实现了Map、接口中的大部分方法。而后添加了一个entrySet的方法。没有继承这个抽象类的HashTable没有这个方法。
abstract Set<Entry<K, V>> entrySet()
void clear()
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean equals(Object object)
V get(Object key)
int hashCode()
boolean isEmpty()
Set<K> keySet()
V put(K key, V value)
void putAll(Map<? extends K, ? extends V> map)
V remove(Object key)
int size()
String toString()
Collection<V> values()
Object clone()
TreeMap
- TreeMap 是一个有序的key-value集合,它是通过红黑树实现的。
- TreeMap 继承于AbstractMap,所以它是一个Map,即一个key-value集合。
- TreeMap 实现了NavigableMap接口,意味着它支持一系列的导航方法。比如返回有序的key集合。
- TreeMap 实现了Cloneable接口,意味着它能被克隆。
- TreeMap 实现了java.io.Serializable接口,意味着它支持序列化。
- TreeMap基于红黑树实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
- TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。
- 另外,TreeMap是非同步的。
API如下:
Entry<K, V> ceilingEntry(K key)
K ceilingKey(K key)
void clear()
Object clone()
Comparator<? super K> comparator()
boolean containsKey(Object key)
NavigableSet<K> descendingKeySet()
NavigableMap<K, V> descendingMap()
Set<Entry<K, V>> entrySet()
Entry<K, V> firstEntry()
K firstKey()
Entry<K, V> floorEntry(K key)
K floorKey(K key)
V get(Object key)
NavigableMap<K, V> headMap(K to, boolean inclusive)
SortedMap<K, V> headMap(K toExclusive)
Entry<K, V> higherEntry(K key)
K higherKey(K key)
boolean isEmpty()
Set<K> keySet()
Entry<K, V> lastEntry()
K lastKey()
Entry<K, V> lowerEntry(K key)
K lowerKey(K key)
NavigableSet<K> navigableKeySet()
Entry<K, V> pollFirstEntry()
Entry<K, V> pollLastEntry()
V put(K key, V value)
V remove(Object key)
int size()
SortedMap<K, V> subMap(K fromInclusive, K toExclusive)
NavigableMap<K, V> subMap(K from, boolean fromInclusive, K to, boolean toInclusive)
NavigableMap<K, V> tailMap(K from, boolean inclusive)
SortedMap<K, V> tailMap(K fromInclusive)
HashMap
- HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
- 继承于AbstractMap,实现了Map、Cloneable、java.io.Serializable接口。
- HashMap 的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。
HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。容量 是哈希表中桶的数量,初始容量 只是哈希表在创建时的容量。加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容量的乘积时,则要对该哈希表进行 rehash 操作(即重建内部数据结构),从而哈希表将具有大约两倍的桶数。 通常,默认加载因子是 0.75, 这是在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本(在大多数 HashMap 类的操作中,包括 get 和 put 操作,都反映了这一点)。在设置初始容量时应该考虑到映射中所需的条目数及其加载因子,以便最大限度地减少 rehash 操作次数。如果初始容量大于最大条目数除以加载因子,则不会发生 rehash 操作。
API如下:
void clear()
Object clone()
boolean containsKey(Object key)
boolean containsValue(Object value)
Set<Entry<K, V>> entrySet()
V get(Object key)
boolean isEmpty()
Set<K> keySet()
V put(K key, V value)
void putAll(Map<? extends K, ? extends V> map)
V remove(Object key)
int size()
Collection<V> values()
LinkedHashMap
Map基本都可以使用HashMap,不过HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序。HashMap的这一缺点往往会带来困扰,因为有些场景,我们期待一个有序的Map。
这个时候,LinkedHashMap就闪亮登场了,他继承自HashMap,虽然增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序。该迭代顺序可以是插入顺序或者是访问顺序。
关 注 点 | 结 论 |
---|---|
LinkedHashMap是否允许空 | Key和Value都允许空 |
LinkedHashMap是否允许重复数据 | Key重复会覆盖、Value允许重复 |
LinkedHashMap是否有序 | 有序 |
LinkedHashMap是否线程安全 | 非线程安全 |
1、LinkedHashMap可以认为是HashMap+LinkedList,即它既使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序。
2、LinkedHashMap的基本实现思想就是----多态。可以说,理解多态,再去理解LinkedHashMap原理会事半功倍;反之也是,对于LinkedHashMap原理的学习,也可以促进和加深对于多态的理解。
HashTable
由于HashMap和HashTable的特殊关系,这里就只讨论二者区别。
HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题。HashMap的工作原理、ArrayList与Vector的比较以及这个问题是有关Java 集合框架的最经典的问题。Hashtable是个过时的集合类,存在于Java API中很久了。在Java 4中被重写了,实现了Map接口,所以自此以后也成了Java集合框架中的一部分。Hashtable和HashMap在Java面试中相当容易被问到,甚至成为了集合框架面试题中最常被考的问题,所以在参加任何Java面试之前,都不要忘了准备这一题。
HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分别。主要的区别有:线程安全性,同步(synchronization),以及速度。
- HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null( HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行 )。
- HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。
- 另一个区别是HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常。但这并不是一个一定发生的行为,要看JVM。这条同样也是Enumeration和Iterator的区别。
- 由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢。如果你不需要同步,只需要单一线程,那么使用HashMap性能要好过Hashtable。
- HashMap不能保证随着时间的推移Map中的元素次序是不变的。
HashMap可以通过下面的语句进行同步: Map m = Collections.synchronizeMap(hashMap);
Collection
Collection是一个接口,其下有两个接口和(List接口和Set接口)一个抽象类(AbstractCollection)。
由于Collection实现了Iterator接口,所以collection所有的实现类对象,都可以使用迭代器Iterator遍历
collection提供的API如下:
abstract boolean add(E object)
abstract boolean addAll(Collection<? extends E> collection)
abstract void clear()
abstract boolean contains(Object object)
abstract boolean containsAll(Collection<?> collection)
abstract boolean equals(Object object)
abstract int hashCode()
abstract boolean isEmpty()
abstract Iterator<E> iterator()
abstract boolean remove(Object object)
abstract boolean removeAll(Collection<?> collection)
abstract boolean retainAll(Collection<?> collection)
abstract int size()
abstract <T> T[] toArray(T[] array)
abstract Object[] toArray()
所有的Collection的实现类的构造方法,都可以使用另一个Collection的对象作为参数,添加进去,从而构造一个新的collection对象。也就是说,可以通过构造方法,将一个collection的对象,转化成另一种集合类对象。
package com.xzj;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
// @ author :zjxu time:2019-01-14
public class Main {
public static void main(String[] args) {
ArrayList<Point> arrayList = new ArrayList<>();
arrayList.add(new Point(0, 3));
arrayList.add(new Point(1, 2));
Set<Point> set = new HashSet(arrayList);
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toString());
}
}
}
List
list是一个接口,抽象类AbstractList实现了这个接口和AbstractCollection这个抽象类。
list是一个有序的队列 。其中的每一个元素都有自己的index,从’0’开始,依次增加。由于序列性,可以使用for-index遍历。
list中可以存在重复的元素。
list中允许使用空元素
list在collection的基础上添加的API如下:
abstract void add(int location, E object)
abstract boolean addAll(int location, Collection<? extends E> collection)
abstract E get(int location)
abstract int indexOf(Object object)
abstract int lastIndexOf(Object object)
abstract ListIterator<E> listIterator(int location)
abstract ListIterator<E> listIterator()
abstract E remove(int location)
abstract E set(int location, E object)
abstract List<E> subList(int start, int end)
ArrayList
继承图:
- ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。
- ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
- ArrayList实现了RandmoAccess接口,即提供了随机访问功能。在ArrayList中,我们即可以通过元素的index快速获取元素对象,这就是快速随机访问。
- ArrayList 实现Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。
- ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。
ArrayList的API如下:
// Collection中定义的API
boolean add(E object)
boolean addAll(Collection<? extends E> collection)
void clear()
boolean contains(Object object)
boolean containsAll(Collection<?> collection)
boolean equals(Object object)
int hashCode()
boolean isEmpty()
Iterator<E> iterator()
boolean remove(Object object)
boolean removeAll(Collection<?> collection)
boolean retainAll(Collection<?> collection)
int size()
<T> T[] toArray(T[] array)
Object[] toArray()
// AbstractCollection中定义的API
void add(int location, E object)
boolean addAll(int location, Collection<? extends E> collection)
E get(int location)
int indexOf(Object object)
int lastIndexOf(Object object)
ListIterator<E> listIterator(int location)
ListIterator<E> listIterator()
E remove(int location)
E set(int location, E object)
List<E> subList(int start, int end)
// ArrayList新增的API
Object clone()
void ensureCapacity(int minimumCapacity)
void trimToSize()
void removeRange(int fromIndex, int toIndex)
Vector
vector的继承图:
- Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
- Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能。
- Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。
- 在Vector中,我们可以通过元素的序号快速获取元素对象;这就是快速随机访问。
- Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。
- 和ArrayList不同,Vector中的操作是线程安全的。
API:
synchronized boolean add(E object)
void add(int location, E object)
synchronized boolean addAll(Collection<? extends E> collection)
synchronized boolean addAll(int location, Collection<? extends E> collection)
synchronized void addElement(E object)
synchronized int capacity()
void clear()
synchronized Object clone()
boolean contains(Object object)
synchronized boolean containsAll(Collection<?> collection)
synchronized void copyInto(Object[] elements)
synchronized E elementAt(int location)
Enumeration<E> elements()
synchronized void ensureCapacity(int minimumCapacity)
synchronized boolean equals(Object object)
synchronized E firstElement()
E get(int location)
synchronized int hashCode()
synchronized int indexOf(Object object, int location)
int indexOf(Object object)
synchronized void insertElementAt(E object, int location)
synchronized boolean isEmpty()
synchronized E lastElement()
synchronized int lastIndexOf(Object object, int location)
synchronized int lastIndexOf(Object object)
synchronized E remove(int location)
boolean remove(Object object)
synchronized boolean removeAll(Collection<?> collection)
synchronized void removeAllElements()
synchronized boolean removeElement(Object object)
synchronized void removeElementAt(int location)
synchronized boolean retainAll(Collection<?> collection)
synchronized E set(int location, E object)
synchronized void setElementAt(E object, int location)
synchronized void setSize(int length)
synchronized int size()
synchronized List<E> subList(int start, int end)
synchronized <T> T[] toArray(T[] contents)
synchronized Object[] toArray()
synchronized String toString()
synchronized void trimToSize()
LinkedList
继承图:
- LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
- LinkedList 实现 List 接口,能对它进行队列操作。
- LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用
- LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
- LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
- LinkedList 是非同步的。
LinkedList的本质是双向链表。
- header是双向链表的表头,它是双向链表节点所对应的类Entry的实例
- Entry中包含成员变量: previous, next, element。
- 其中,previous是该节点的上一个节点,next是该节点的下一个节点,element是该节点所包含的值。
- size是双向链表中节点的个数。
- LinkedList继承于AbstractSequentialList,并且实现了Dequeue接口。
- LinkedList包含两个重要的成员:header 和 size。
API:
boolean add(E object)
void add(int location, E object)
boolean addAll(Collection<? extends E> collection)
boolean addAll(int location, Collection<? extends E> collection)
void addFirst(E object)
void addLast(E object)
void clear()
Object clone()
boolean contains(Object object)
Iterator<E> descendingIterator()
E element()
E get(int location)
E getFirst()
E getLast()
int indexOf(Object object)
int lastIndexOf(Object object)
ListIterator<E> listIterator(int location)
boolean offer(E o)
boolean offerFirst(E e)
boolean offerLast(E e)
E peek()
E peekFirst()
E peekLast()
E poll()
E pollFirst()
E pollLast()
E pop()
void push(E e)
E remove()
E remove(int location)
boolean remove(Object object)
E removeFirst()
boolean removeFirstOccurrence(Object o)
E removeLast()
boolean removeLastOccurrence(Object o)
E set(int location, E object)
int size()
<T> T[] toArray(T[] contents)
Object[] toArray()
Stack
继承图:
Stack是栈。它的特性是:先进后出(FILO, First In Last Out)。
java工具包中的Stack是继承于Vector(矢量队列)的,由于Vector是通过数组实现的,这就意味着,Stack也是通过数组实现的,而非链表。当然,我们也可以将LinkedList当作栈来使用!
由于Stack和继承于Vector,因此它也包含Vector中的全部API。
其中常用的API如下:
boolean empty()
synchronized E peek()
synchronized E pop()
E push(E object)
synchronized int search(Object o)
List总结
- List 是一个接口,它继承于Collection的接口。它代表着有序的队列。
- AbstractList 是一个抽象类,它继承于AbstractCollection。AbstractList实现List接口中除size()、get(int location)之外的函数。
- AbstractSequentialList 是一个抽象类,它继承于AbstractList,实现了“链表中,根据index索引值操作链表的全部函数”。
- ArrayList, LinkedList, Vector, Stack是List的4个实现类。
- ArrayList 是一个数组队列,相当于动态数组。它由数组实现,随机访问效率高,随机插入、随机删除效率低。
- LinkedList 是一个双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList随机访问效率低,但随机插入、随机删除效率低。
- Vector 是矢量队列,和ArrayList一样,它也是一个动态数组,由数组实现。但是ArrayList是非线程安全的,而Vector是线程安全的。
- Stack 是栈,它继承于Vector。它的特性是:先进后出(FILO, First In Last Out)。
Set
- Set 是继承于Collection的接口。它是一个不允许有重复元素的集合。
- AbstractSet 是一个抽象类,它继承于AbstractCollection
- AbstractCollection实现了Set中的绝大部分函数,为Set的实现类提供了便利。
- HastSet 和 TreeSet 是Set的两个实现类。
- HashSet依赖于HashMap,它实际上是通过HashMap实现的。HashSet中的元素是无序的。
- TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的。TreeSet中的元素是有序的。
- Set都是线程不安全的。
TreeSet
继承图
- TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。
- 它继承于AbstractSet抽象类,实现了NavigableSet, Cloneable, java.io.Serializable接口。
- TreeSet 继承于AbstractSet,所以它是一个Set集合,具有Set的属性和方法。
- TreeSet 实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。
- TreeSet 实现了Cloneable接口,意味着它能被克隆。
- TreeSet 实现了java.io.Serializable接口,意味着它支持序列化。
在Set中,数据存储的结构是无序的。TreeSet对Set中的元素排序,由于TreeSet的有序性,所以TreeSet中不允许有空元素的存在。TreeSet中元素排序的方式有两种:自然排序和比较器排序。排序的结果的存储结构使用红黑树。
1
自然排序方法要求添加进入set的元素自身实现Comparable接口,重写compareTo方法。按照compareTo规定的排序规则,来对添加进Set的元素排序。
2
比较器排序的方法就是,编写一个比较器的对象,在初始化的时候,将其加载到TreeSet的构造函数中。这样,set中的元素就会按照比较器的规则来将插入set中的元素排序。
下面是TreeSet的API:
boolean add(E object)
boolean addAll(Collection<? extends E> collection)
void clear()
Object clone()
boolean contains(Object object)
E first()
boolean isEmpty()
E last()
E pollFirst()
E pollLast()
E lower(E e)
E floor(E e)
E ceiling(E e)
E higher(E e)
boolean remove(Object object)
int size()
Comparator<? super E> comparator()
Iterator<E> iterator()
Iterator<E> descendingIterator()
SortedSet<E> headSet(E end)
NavigableSet<E> descendingSet()
NavigableSet<E> headSet(E end, boolean endInclusive)
SortedSet<E> subSet(E start, E end)
NavigableSet<E> subSet(E start, boolean startInclusive, E end, boolean endInclusive)
NavigableSet<E> tailSet(E start, boolean startInclusive)
SortedSet<E> tailSet(E start)
HashSet
继承图:
- HashSet 是一个没有重复元素的集合。
- 它是由HashMap实现的,不保证元素的顺序,而且HashSet允许使用 null 元素。
- HashSet是非同步的。
HashSet的主要API:
boolean add(E object)
void clear()
Object clone()
boolean contains(Object object)
boolean isEmpty()
Iterator<E> iterator()
boolean remove(Object object)
int size()
LinkedHashSet
- LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。
- 这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
- 但是实际上,它的保存顺序是按照哈希码保存的。
- 允许可以存在空元素,空元素的遍历顺序在最前。
set总结
Set的结构图如下:
- HashSet是无序的(按照hash顺序的,但是Hash是无序的)。
- Tree是有序的,拥有自己的比较器或者是比较方法。
- LinkedHashSet在HashSet的基础上,使用链表将HashSet中的元素连接起来,遍历顺序添加的顺序。
Queue
Queue是一个接口,其下还有Deque、BlockingQueue、AbstractQueue接口。
结构图:
PriorityQueue
- 非线程安全,该线程安全版本为PriorityBlockingQueue。
- 不允许使用非空元素。
- 实际上是一个堆,默认为最小堆,也可以添加比较器。
- 新建对象的时候可以指定一个初始容量,其容量会自动增加。
- 不允许使用 null 元素。
- 对元素采用的是堆排序,迭代器只是对整个数组的依次遍历。
API如下:
Modifier and Type | Method and Description |
---|---|
boolean |
add(E e) 将指定的元素插入到此优先级队列中。 |
void |
clear() 从此优先级队列中删除所有元素。 |
Comparator<? super E> |
comparator() 返回用于为了在这个队列中的元素,或比较null 如果此队列根据所述排序natural ordering的元素。 |
boolean |
contains(Object o) 如果此队列包含指定的元素,则返回 true 。 |
Iterator<E> |
iterator() 返回此队列中的元素的迭代器。 |
boolean |
offer(E e) 将指定的元素插入到此优先级队列中。 |
E |
peek() 检索但不删除此队列的头,如果此队列为空,则返回 null 。 |
E |
poll() 检索并删除此队列的头,如果此队列为空,则返回 null 。 |
boolean |
remove(Object o) 从该队列中删除指定元素的单个实例(如果存在)。 |
int |
size() 返回此集合中的元素数。 |
Spliterator<E> |
spliterator() 在此队列中的元素上创建late-binding和失败快速 Spliterator 。 |
Object[] |
toArray() 返回一个包含此队列中所有元素的数组。 |
<T> T[] |
toArray(T[] a) 返回一个包含此队列中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。 |