接下来的对Java的分析都是基于jdk1.8版本
在开发过程中,常常需要集中存放多个数据。我们知道,数组可以实现这个功能。但是,数组的长度是固定的,如果我们存放的数据数量是动态变化的该怎么办?这个时候,就要用到Java的集合类了。
集合框架
所有的集合都位于java.util包下。Java集合类有两个主要的接口:Collection和Map。他们是集合的根接口。在集合中,Map结尾的类实现了Map接口,而其他的集合类实现了Collection接口。
集合框架图图片来自:https://img-blog.csdn.net/20160124221843905
分析一下上图:
1、Collection是一个接口,它包含了集合的基本操作和属性。分为了List、Set和Queue三大分支。其中,List是一个有序的队列,其中的元素不唯一。而Set是一个无序的集合,其中的元素是唯一的。
2、List的实现类有ArrayList、LinkedList、Vector及Stack。
3、Set的实现类有HashSet、TreeSet、LinkedHashSet及EnumSet。
4、Map也是一个接口,而且是一个映射接口,值以键值对(key-value)的形式存储。实现类有EnumMap、HashMap、TreeMap、WeakHaskMap、ConcurrentHashMap及IdentityHashMap。
5、Iteator是一个用来遍历集合的工具,我们可以看到Collection接口就依赖于Iterabe接口,所以,在Collection的实现类中可以使用Iterator来遍历元素。
接下来,就一个个看一下。
Collection及其实现
Collection的定义及方法
Collection接口的定义如下:
public interface Collection<E> extends Iterable<E> {}
集合层次结构中的根接口,JDK不提供此接口的任何直接实现:它提供了更具体的子接口的实现,如Set和List。
包含的API如下:
Iterator<E> iterator();
int size();
boolean isEmpty();
Object[] toArray();
<T> T[] toArray(T[] a);
boolean add(E e);
boolean addAll(Collection<? extends E> c);
boolean remove(Object o);
boolean removeAll(Collection<?> c);
boolean contains(Object o);
boolean containsAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
boolean equals(Object o);
int hashCode();
还有默认方法
default boolean removeIf(Predicate<? super E> filter) {...}
//以下三个方法与Spliterator相关
default Spliterator<E> spliterator() {...}
default Stream<E> stream() {...}
default Stream<E> parallelStream() {...}
这些方法主要就是对元素的添加、删除、比较和对集合的判空、遍历获取大小等。
List接口的定义及其方法
List接口的定义如下:
public interface List<E> extends Collection<E> {}
List是一个有序集合。该接口的用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引(列表中的位置)访问元素并搜索列表中的元素。
因为继承于Collection接口,所以包含有其定义的所有方法,并且新增了部分方法,新增的方法如下:
E get(int index);
E set(int index, E element);
void add(int index, E element);
boolean addAll(int index, Collection<? extends E> c);
E remove(int index);
int indexOf(Object o);
int lastIndexOf(Object o);
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
List<E> subList(int fromIndex, int toIndex);
及默认方法
default void replaceAll(UnaryOperator<E> operator) {...}
default void sort(Comparator<? super E> c) {...}
//重写Collection的默认方法,主要是变了第二个参数。
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
因为List是有序的,可以根据角标对其中的元素进行操作。所以,List中增加了部分使用角标操作数据的方法。
Set接口的定义及其方法
Set也是继承于Collection的一个接口,我们看一下它的定义:
public interface Set<E> extends Collection<E> {}
Set是一个不包含重复元素的集合。 集合中任意两个元素 e1.equals(e2)必为false。并且最多只包含一个null元素。
和List一样,Set也含有Collection定义的所有方法,但是没有新增方法,只重写了一个默认方法:
//也是只改变了第二个参数
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT);
}
AbstractCollection的定义及作用
定义如下:
public abstract class AbstractCollection<E> implements Collection<E> {}
AbstractCollection是一个抽象类,实现了Collection中除了iterator()和size()之外的函数。它实现了Collection中其他集合类通用的方法,那么其他集合类(比如:AbstractList、AbstractSet及ArrayDeque)就可以通过继承它来减少部分工作。
AbstractList的定义及作用
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
AbstractList是一个抽象类,实现了List中除了size()和get(int Location)之外的函数。它是为了方便随机访问数据的集合(比如:AbstractSequentialList、ArrayList等)实现List。
AbstractSequentialList的定义及作用
public abstract class AbstractSequentialList<E> extends AbstractList<E> {}
继承于AbstractList,实现了其get(int index)等方法。为了方便顺序访问数据的集合(如LinkedList)实现List。
AbstractSet的定义及其作用
定义如下:
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {}
AbstractSet是一个抽象类,实现了equals(Object c)、hashCode()和removeAll(Collection<?> c)()方法。它是为了方便其他的类实现Set。
Queue的定义及方法
定义如下:
public interface Queue<E> extends Collection<E> {}
队列,用于在处理前保持元素的集合。 除了有基本的集合操作外,队列还提供插入,提取和检查操作。它的方法有:
//如果可以在不违反容量限制的情况下立即执行此操作,则将指定的元素插入此队列,成功时返回true,如果当前没有空间,则抛出IllegalStateException
boolean add(E e);
//如果可以在不违反容量限制的情况下立即执行此操作,则将指定的元素插入此队列。 使用容量限制队列时,此方法通常优于add(),只能通过抛出异常来插入元素。
boolean offer(E e);
//检索并删除此队列的头部。 此方法与poll()的不同之处仅在于,如果此队列为空,则会抛出异常。
E remove();
//检索并删除此队列的头部,如果此队列为空,则返回null。
E poll();
//检索但不删除此队列的头部。 此方法与 peek()的区别仅在于,如果此队列为空,则抛出异常。
E element();
//检索但不移除此队列的头部,如果此队列为空,则返回null。
E peek();
Deque的定义及方法
定义如下:
public interface Deque<E> extends Queue<E> {}
Deque是一种线性集合,支持两端插入和移除元素。此接口支持限制容量大小的队列以及不限制容量大小的队列。除了Queue的方法外,还有以下方法
//容量允许的情况下,在队列的开头插入元素。如果没有空间,则抛出IllegalStateException异常。
void addFirst(E e);
//将指定元素插入此双端队列的前面,除非它违反容量限制。 使用容量限制的双端队列时,此方法通常优于addFirst()方法
boolean offerFirst(E e);
//容量允许的情况下,在队列的末尾插入元素。如果没有空间,则抛出IllegalStateException异常。
void addLast(E e);
//在此双端队列的末尾插入指定的元素,除非它违反容量限制。 使用容量限制的双端队列时,此方法通常优于addLast()方法
boolean offerLast(E e);
//检索并删除此双端队列的第一个元素。如果此双端队列为空,则会抛出异常。
E removeFirst();
//检索并删除此双端队列的第一个元素,如果此双端队列为空,则返回null。
E pollFirst();
//检索并删除此双端队列的最后一个元素。 如果此双端队列为空,则会抛出异常。
E removeLast();
//检索并删除此双端队列的最后一个元素,如果此双端队列为空,则返回null。
E pollLast();
//检索此双端队列的第一个元素。如果队列为空,则抛出异常
E getFirst();
//检索此双端队列的第一个元素,如果此双端队列为空,则返回null。
E peekFirst();
//检索此双端队列的最后一个元素。如果队列为空,则抛出异常
E getLast();
//检索此双端队列的最后一个元素,如果此双端队列为空,则返回null。
E peekLast();
//从此双端队列中删除指定元素的第一个匹配项。如果双端队列不包含该元素,则不会更改。 如果有,删除第一个与o相同的元素,并返回true。
boolean removeFirstOccurrence(Object o);
//从此双端队列中删除指定元素的最后一个匹配项。如果双端队列不包含该元素,则不会更改。 如果有,删除最后一个与o相同的元素,并返回true。
boolean removeLastOccurrence(Object o);
//如果可以在不违反容量限制的情况下立即执行此操作,则将指定的元素插入此双端队列的尾部,成功时返回true,如果当前没有空间可用,抛出IllegalStateException异常。
boolean add(E e);
//如果可以在不违反容量限制的情况下立即执行此操作,则将指定的元素插入此双端队列的尾部,成功时返回true,如果当前没有空间可用,返回false。
boolean offer(E e);
//检索并删除此双端队列的头部。如果此双端队列为空,则会抛出异常。
E remove();
//检索并删除此双端队列的头部。如果此双端队列为空,则返回null
E poll();
//检索此双端队列的头部。如果此双端队列为空,则会抛出异常。
E element();
//检索此双端队列的头部。如果此双端队列为空,则返回null。
E peek();
//如果可以在不违反容量限制的情况下立即执行此操作,则将元素推送到此双端队列的头部,如果当前没有可用空间则抛出IllegalStateException异常。
void push(E e);
//删除并返回此双端队列的第一个元素。
E pop();
//从此双端队列中删除第一次出现的指定元素。 如果队列不包含该元素,则它将保持不变。如果有,删除第一次出现的指定元素并返回true。
boolean remove(Object o);
//如果此双端队列包含指定的元素,则返回true
boolean contains(Object o);
//反回队列中的元素个数
int size();
//返回队列的迭代器,元素从头部到尾部顺序返回
Iterator<E> iterator();
//以相反的顺序返回此双端队列中元素的迭代器,元素从尾部到头部顺序返回
Iterator<E> descendingIterator();
Iterator及其实现
Iterator的方法及作用
Iterator是一个泛型接口,包含4个方法:
public interface Iterator<E>{
E next();
boolean hasNext();
void remove();
default void forEachRemaining(Consumer <? super E> action);
}
通过反复调用next方法,可以逐个访问集合中的每个元素。但是,到达集合末尾,next将抛出一个NoSuchElementException。因此,需要在调用next之前调用hasNext方法来判断是否有下一个元素。
在Java SE 8中可以调用forEachRemaining方法,并提供一个lambda表达式来遍历集合。
元素被访问的顺序取决于集合的类型。如果对ArrayList进行迭代,迭代器将从索引0开始,每迭代一次,索引值加一。然而,如果访问HashSet,每个元素将按照某种随机的次序出现,我们无法预知元素被访问的次序。
Java的迭代器是位于两个元素之间的,当调用next时,迭代器就越过下一个元素,并返回那个元素的引用。
Iterator接口的remove方法将会删除刚刚越过的元素。而且,不能连续调用remove方法,应该在remove方法中间使用next方法,让其越过元素。
ListIterator的方法及作用
定义如下:
public interface ListIterator<E> extends Iterator<E> {}
它继承于Iterator,用来遍历List,允许程序员在任一方向遍历列表,在迭代期间修改列表,并获取迭代器在列表中的当前位置。它没有当前元素,光标总是位于以遍历过的元素和下一个元素之间。除了Iterator的方法外,他还有自己的方法。
//反向遍历列表的时候,如果有元素,则返回true(光标前面是否有元素)
boolean hasPrevious();
/**返回列表中的上一个元素并向后移动光标位置。 可以重复调用此方法以向后遍历列表,或者与对next()的调用混合以来回传递。 (请注意,对next()和previous()的交替调用将重复返回相同的元素。
**/
E previous();
//返回后续调用next()将返回的元素的索引,如果列表迭代器位于列表的末尾,则返回列表大小。
int nextIndex();
//返回后续调用previous()将返回的元素的索引。(如果列表迭代器位于列表的开头,则返 回-1。)
int previousIndex();
//用指定的元素替换next()或previous()返回的最后一个元素(可选操作)。 只有在最后一次调用 next()或previous()后才调用remove()和add(),才能进行此调用。
void set(E e);
//将指定的元素插入列表(可选操作)。 该元素紧接在link #next()返回的元素之前插入(如果有),并且在previous()返回的元素之后插入,如果有的话。 (如果列表中不包含任何元素,则新元素将成为列表中的唯一元素。)新元素将插入隐式游标之前:next()的后续调用不受影响,随后调用previous()将返回新元素。
void add(E e);
Map及其实现
Map的定义及方法
定义如下:
public interface Map<K, V> {}
Map是一个键值对映射接口。Map中不能包含重复的键,每个键也只能映射一个值。
Map的方法:
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V> m);
void clear();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
boolean equals(Object o);
int hashCode();
以及默认方法
default V getOrDefault(Object key, V defaultValue){}
default void forEach(BiConsumer<? super K, ? super V> action){}
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function){}
default V putIfAbsent(K key, V value){}
default boolean remove(Object key, Object value){}
default boolean replace(K key, V oldValue, V newValue){}
default V replace(K key, V value){}
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction){}
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction){}
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction){}
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction){}
Map的方法用来返回键集、值集以及键跟值的映射关系。且提供了判空、清除及删除等操作。
Map.Entry的定义及方法
定义如下:
interface Entry<K, V> {}
这是Map内部的一个接口,辅助Map的部分方法。Entry的方法有:
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
还有部分默认方法
public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey(){}
public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue(){}
public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp){}
public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp){}
AbstractMap定义及方法
定义如下:
public abstract class AbstractMap<K,V> implements Map<K,V> {}
此类实现了Map除entrySet()外的所有方法。内部有一个抽象类SimpleEntry继承了Entry做辅助工作。此类还有自己的方法:
//返回一个克隆副本,但是值跟键都是null
protected Object clone() throws CloneNotSupportedException {}
//SimpleEntry和SimpleImmutableEntry的实用方法。 测试是否相等,检查空值。
private static boolean eq(Object o1, Object o2) {}
ConcurrentMap的定义与方法
定义如下:
public interface ConcurrentMap<K,V> extends Map<K,V> {}
它的实现类可以为线程提供安全性和原子性保证。其实就是线程安全。它的方法如下:
V putIfAbsent(K key, V value);
boolean remove(Object key, Object value);
boolean replace(K key, V oldValue, V newValue);
V replace(K key, V value);
还有默认方法
default V getOrDefault(Object key, V defaultValue){}
default void forEach(BiConsumer<? super K, ? super V> action){}
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function){}
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction){}
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction){}
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction){}
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction){}
ConcurrentMap提供线程安全性和原子性保证的映射。
内存一致性效果:与其他并发集合一样,在将对象作为键或值放入ConcurrentMap之前的线程中的操作发生在从另一个线程中的ConcurrentMap访问或删除该对象之后的操作之前。
SortedMap定义及方法
定义如下:
public interface SortedMap<K,V> extends Map<K,V> {}
SortedMap接口主要提供有序的Map实现。它按照自然顺序或指定的比较器对键进行排序,它的实现类是TreeMap。它的方法如下:
Comparator<? super K> comparator();
SortedMap<K,V> subMap(K fromKey, K toKey);
SortedMap<K,V> headMap(K toKey);
SortedMap<K,V> tailMap(K fromKey);
K firstKey();
K lastKey();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
NavigableMap的定义及方法
定义如下:
public interface NavigableMap<K,V> extends SortedMap<K,V> {}
NavigableMap扩展了 SortedMap,具有了针对给定搜索目标返回最接近匹配项的导航方法。方法 lowerEntry、floorEntry、ceilingEntry 和 higherEntry 分别返回与小于、小于等于、大于等于、大于给定键的键关联的 Map.Entry 对象,如果不存在这样的键,则返回 null。类似地,方法 lowerKey、floorKey、ceilingKey 和 higherKey 只返回关联的键。所有这些方法是为查找条目而不是遍历条目而设计的。它的方法如下:
Map.Entry<K,V> lowerEntry(K key);
K lowerKey(K key);
Map.Entry<K,V> floorEntry(K key);
K floorKey(K key);
Map.Entry<K,V> ceilingEntry(K key);
Map.Entry<K,V> ceilingEntry(K key);
K higherKey(K key);
Map.Entry<K,V> firstEntry();
Map.Entry<K,V> lastEntry();
Map.Entry<K,V> pollFirstEntry();
Map.Entry<K,V> pollLastEntry();
NavigableMap<K,V> descendingMap();
NavigableSet<K> navigableKeySet();
NavigableSet<K> descendingKeySet();
NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,K toKey, boolean toInclusive);
NavigableMap<K,V> headMap(K toKey, boolean inclusive);
NavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
SortedMap<K,V> subMap(K fromKey, K toKey);
SortedMap<K,V> headMap(K toKey);
SortedMap<K,V> tailMap(K fromKey);
Dictionary的定义及方法
定义如下:
public abstract class Dictionary<K,V> {}
是任何类的抽象父类,例如Hashtable,它将键映射到值。 每个键和每个值都是一个对象。 在任何一个Dictionary 对象中,每个键最多与一个值相关联。 给定Dictionary 和一个键,可以查找关联的元素。 任何非null对象都可以用作键和值。通常,此类的实现应使用equals方法来确定两个键是否相同。
它的方法有:
//返回字典中元素的个数
abstract public int size();
//当且仅当此字典不包含任何条目时,结果为true。
abstract public boolean isEmpty();
//返回此字典中的所有键
abstract public Enumeration<K> keys();
//返回此字典中的所有值
abstract public Enumeration<V> elements();
//返回键在此字典中映射到的值。
abstract public V get(Object key);
//将指定的键映射到此字典中指定的值。键和值都不能是null
abstract public V put(K key, V value);
//从此字典中删除键值对
abstract public V remove(Object key);
好了,本文就分析到这。本文的主旨是了解集合框架中比较重要的接口和类,并对它们所含的方法留有印象。在本文中没有注释的方法的作用,会在之后的其他文章中有所体现。
网友评论