Java基础知识之容器(一:容器整体框架探索)
来源:互联网 发布:求淘宝好的国产手办店 编辑:程序博客网 时间:2024/06/05 05:16
本篇博客主要介绍Java容器的框架,我们根据框架重上向下的顺序一个个探究其源码,来达到掌握容器的骨架。至于容器的细节放到下一篇来探讨。
一:基本概念
Java容器类库的用途是保存对象,根据数据结构不同将其划分为两个不同的概念
- Collection,一个独立元素的序列,其中List按照元素的插入顺序保存元素,而set不能有重复元素,Queue按照先进先出(FIFO)的方式来管理数据
- Map,一组键值对(key-value)对象的序列,可以使用key来查找value,其中key是不可以重复的,value可以重复。我们可以称其为字典或者关联数组。其中HashMap是无序的,TreeMap是有序的,WeakHashMap是弱类型的,Hashtable是线程安全的。
二:框架结构图
Collection的List、Set、Queue类图如下:
Map容器的类图如下:
三:源码探索
Iterable接口
import java.util.Iterator;/** * 实现此接口的类的实例可以与增强型for循环一起使用。 * @since 1.5 */public interface Iterable<T> { /** * 返回此对象中元素的迭代器 */ Iterator<T> iterator();}
/** * 一系列对象的迭代器,如集合。 */public interface Iterator<E> { /** * 如果至少有一个元素返回true,否则返回false。 */ public boolean hasNext(); /** * 返回下一个对象并推进迭代器。 */ public E next(); /** * 从集合中删除{@code next}返回的最后一个对象。 * 这种方法只能在每次调用{@code next}之前调用一次。 */ public void remove();}
- Iterator是迭代器类,而Iterable是为了只要实现该接口就可以使用foreach,进行迭代.
- Iterable中封装了Iterator接口,只要实现了Iterable接口的类,就可以使用Iterator迭代器了。
- 集合Collection、List、Set都是Iterable的实现类,所以他们及其他们的子类都可以使用foreach进行迭代。
- Iterator中和核心的方法next(),hasnext(),remove(),都是依赖当前位置,如果这些集合直接实现Iterator,则必须包括当前迭代位置的指针。当集合在方法间进行传递的时候,由于当前位置不可知,所以next()之后的值,也不可知。而当实现Iterable则不然,每次调用都返回一个从头开始的迭代器,各个迭代器之间互不影响。
从上面我们可以看出,Iterable只是为了让集合能够使用迭代器而已
Collection接口
/** * Collection是集合层次结构的根。 它定义了对数据集合的操作以及它们在 Collection的所有实现中将具有的行为。 *Collection的所有直接或间接实现都应该实现至少两个构造函数。 一个没有参数创建一个空集合,另一个参数类型为Collection。 该第二个构造函数可用于创建不同类型的集合作为初始集合,但具有相同的元素。Collection的实现不能强制实现这两个构造函数,但至少在 java.util下的所有实现都是这样的。 * * 如果底层集合不支持该操作,则更改集合内容的方法会抛出 UnsupportedOperationException,尽管在请求的操作不会更改集合的情况下抛出此类Exception并不是强制性的。 在这些情况下,由执行是否引发 UnsupportedOperationException。 * */public interface Collection<E> extends Iterable<E> { /** * 尝试将对象添加到此集合的内容(可选)。 * * 此方法成功完成后,可确保对象包含在集合中。 * * 如果集合被修改,则返回true,如果没有更改,则返回false。 * * Collection的一个实现可能缩小了接受对象的集合,但它必须在文档中指定。 如果要添加的对象不符合此限制,则抛出IllegalArgumentException。 * * 如果集合尚未包含要添加的对象并添加对象失败,则此方法<i>必须</ i>抛出适当的未选中的异常。 在这种情况下,不允许返回false,因为在该方法完成后,它将违反元素将成为集合的一部分的后置条件。 */ public boolean add(E object); /** * 清空集合元素 */ public void clear(); /** * 测试此集合是否包含指定的对象。 如果且仅当此Collection中的至少一个元素元素满足以下要求(object == null?elem == null:object.equals(elem))},则返回true。 */ public boolean contains(Object object); /** * 此集合是否包含指定集合中所有的元素 */ public boolean containsAll(Collection<?> collection); /** * 如果对象与此对象相同,则返回true,如果该对象与此对象不同,则返回false。 */ public boolean equals(Object object); /** * 返回接收器的整数哈希码。 相同的对象为此方法返回相同的值。 */ public int hashCode(); /** * 如果此Collection不包含元素,则返回true */ public boolean isEmpty(); /** * 返回可用于访问此Collection所包含的对象的Iterator实例。 没有定义迭代器返回元素的顺序。 只有当Collection的实例具有定义的顺序时,才能按照该顺序返回元素。 */ public Iterator<E> iterator(); /** * 从此集合中删除指定对象的一个实例 */ public boolean remove(Object object); /** * 删除指定集合(可选)中每个对象的{@code Collection}中的所有事件。 在此方法返回后,该集合中的所有元素都不能在此集合中找到。 */ public boolean removeAll(Collection<?> collection); /** * 从集合中删除在集合中未找到的所有对象(可选)。 在此方法返回后,此集合将只包含可以在传递给此方法的集合中找到的元素。(求交集) */ public boolean retainAll(Collection<?> collection); /** *返回此集合包含多少对象的计数。 */ public int size(); /** * 返回一个包含此集合中包含的所有元素的新数组。 * * 如果实现已经排序了元素,它将以与迭代器返回的顺序相同的顺序返回元素数组。 * * 返回的数组不反映集合的任何更改。 即使底层数据结构已经是一个数组,也创建一个新数组。 */ public Object[] toArray(); /** * 返回包含此集合中包含的所有元素的数组。 如果指定的数组足够大以容纳元素,则使用指定的数组,否则将创建相同类型的数组。 如果使用指定的数组并且大于此集合,则Collection元素之后的数组元素将设置为null。 */ public <T> T[] toArray(T[] array);}
- Collection接口是Java语言中最基本的集合接口,在JDK中没有直接提供Collection接口的具体实现类,Collection的功能实现类主要是对它的三个更具体的子接口List、Set和Queue的具体实现类。但是在Collection接口中定义了一套通用操作的实现方法和命名规则。
- List、Set、Queue接口都继承自Collection并定义了各自不同的方法。
List接口探索
/** * List是维护其元素的排序的集合。 List中的每个元素都有一个索引。 因此,每个元素可以被其索引访问,第一个索引为零。 通常,与集合相比,List允许重复元素,其中元素必须是唯一的。 */ public interface List<E> extends Collection<E> { /**List作为Collection的子接口 * 提供了Collection接口定义的方法 * 这些方法在Collection源码学习中 * 已经分析过了,就不在说明了 * */ int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean addAll(int index, Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); int hashCode(); /**同时List接口定义了一些自己的方法 * 来实现“有序”这一功能特点*/ /** *返回列表中指定索引的元素 *return E *throws IndexOutofBoundException(index<0||index>=size()) * */ E get(int index); /** *设定某个列表索引的值 *throws: *UnsupportedOperationException ClassCastException NullPointerException IllegalArgumentException IndexOutOfBoundsException * */ E set(int index, E element); /** *在指定位置插入元素,当前元素和后续元素后移 *这是可选操作,类似于顺序表的插入操作 */ void add(int index, E element); /** * 删除指定位置的元素(可选操作)*/ E remove(int index); /** * 获得指定对象的最小索引位置, * 没有则返回-1*/ int indexOf(Object o); /**获得指定对象的最大索引位置 * 可以知道的是若集合中无给定元素的重复元素下 * 其和indexOf返回值是一样的*/ int lastIndexOf(Object o); /**一种更加强大的迭代器,支持向前遍历,向后遍历 * 插入删除操作,此处不解释*/ ListIterator<E> listIterator(); ListIterator<E> listIterator(int index); /** * 返回索引fromIndex(包括)和toIndex(不包括) * 之间的视图。*/ List<E> subList(int fromIndex, int toIndex); }
List接口特点
* 内部元素是有序的
* 元素是可以重复的
* List接口有3个常用的实现类,分别是ArrayList、LinkedList、Vector。
* List是基于数组实现的
Set 接口探索
/** * Set是不允许重复元素的数据结构。 */public interface Set<E> extends Collection<E> { /**Set作为Collection的子接口 * 提供了Collection接口定义的方法 * 这些方法在Collection源码学习中 * 已经分析过了,就不在说明了 * */ public boolean add(E object); public boolean addAll(Collection<? extends E> collection); public void clear(); public boolean contains(Object object); public boolean containsAll(Collection<?> collection); public boolean equals(Object object); public int hashCode(); public Iterator<E> iterator(); public boolean remove(Object object); public boolean removeAll(Collection<?> collection); public boolean retainAll(Collection<?> collection); public Object[] toArray(); public <T> T[] toArray(T[] array); public boolean isEmpty(); public int size();}
Set接口特点
* 内部元素是无序的
* 元素是不可以重复的
* Set接口有2个常用的实现类,HashSet、TreeSet。
* Set基于哈希算法实现
Queue 接口探索
public interface Queue<E> extends Collection<E> { /** * 队列插入元素 * * @param e the element to add * @return <tt>true</tt> (as specified by {@link Collection#add}) * @throws IllegalStateException if the element cannot be added at this * time due to capacity restrictions * @throws ClassCastException if the class of the specified element * prevents it from being added to this queue * @throws NullPointerException if the specified element is null and * this queue does not permit null elements * @throws IllegalArgumentException if some property of this element * prevents it from being added to this queue */ boolean add(E e); /** * 队列插入元素 * 插入失败,抛出异常 * @param e the element to add * @return <tt>true</tt> if the element was added to this queue, else * <tt>false</tt> * @throws ClassCastException if the class of the specified element * prevents it from being added to this queue * @throws NullPointerException if the specified element is null and * this queue does not permit null elements * @throws IllegalArgumentException if some property of this element * prevents it from being added to this queue */ boolean offer(E e); /** * 获取队顶元素,并删除该元素 * 空的时候,抛出异常 * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ E remove(); /** * 获取队顶元素,并删除该元素 * 空的时候,返回null * @return the head of this queue, or <tt>null</tt> if this queue is empty */ E poll(); /** * 查看队顶元素,但是不删除该元素、 * 空的时候,抛出异常 * @return the head of this queue * @throws NoSuchElementException if this queue is empty */ E element(); /** * 查看队顶元素,但是不删除该元素、 * 空的时候,返回 null * * @return the head of this queue, or <tt>null</tt> if this queue is empty */ E peek();}
Queue接口特点
- 先进先出的数据结构,即从容器的一端放入对象,从另一端取出,并且对象放入容器的顺序与取出的顺序是相同的。
- 虽然Queue接口继承Collection接口,但是Queue接口中的方法都是独立的,在创建具有Queue功能的实现时,不需要使用Collection方法。
AbstractCollection抽象类探索
/** * AbstractCollection类是Collection接口的抽象实现。 一个子类必须实现抽象方法iterator()和size()来创建一个不可变的集合。 要创建可修改的集合,有必要重写当前抛出UnsupportedOperationException的add()方法。 */public abstract class AbstractCollection<E> implements Collection<E> { protected AbstractCollection() { } /** * 覆盖Collection中的方法,默认是不可变的集合,要创建可修改的集合,有必要重此方法 */ public boolean add(E object) { throw new UnsupportedOperationException(); } /** * 覆盖并实现Collection中的addAll方法 */ public boolean addAll(Collection<? extends E> collection) { boolean result = false; Iterator<? extends E> it = collection.iterator(); while (it.hasNext()) { if (add(it.next())) { result = true; } } return result; } /** * 覆盖并实现Collection中的clear方法 */ public void clear() { Iterator<E> it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } } /** * 覆盖并实现Collection中的contains方法 */ public boolean contains(Object object) { Iterator<E> it = iterator(); if (object != null) { while (it.hasNext()) { if (object.equals(it.next())) { return true; } } } else { while (it.hasNext()) { if (it.next() == null) { return true; } } } return false; } /** * 覆盖并实现Collection中的containsAll方法 */ public boolean containsAll(Collection<?> collection) { Iterator<?> it = collection.iterator(); while (it.hasNext()) { if (!contains(it.next())) { return false; } } return true; } /** * 覆盖并实现Collection中的isEmpty方法 */ public boolean isEmpty() { return size() == 0; } /** * 在这个类中,这个方法被声明为抽象的,必须由具体的Collection实现来实现。 */ public abstract Iterator<E> iterator(); /** * 覆盖并实现Collection中的remove方法 */ public boolean remove(Object object) { Iterator<?> it = iterator(); if (object != null) { while (it.hasNext()) { if (object.equals(it.next())) { it.remove(); return true; } } } else { while (it.hasNext()) { if (it.next() == null) { it.remove(); return true; } } } return false; } /** * 覆盖并实现Collection中的removeAll方法 */ public boolean removeAll(Collection<?> collection) { boolean result = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (collection.contains(it.next())) { it.remove(); result = true; } } return result; } /** * 覆盖并实现Collection中的retainAll方法 */ public boolean retainAll(Collection<?> collection) { boolean result = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (!collection.contains(it.next())) { it.remove(); result = true; } } return result; } /** * 在这个类中,这个方法被声明为抽象的,必须由具体的Collection实现来实现。 */ public abstract int size(); /** * 覆盖并实现Collection中的toArray方法 */ public Object[] toArray() { return toArrayList().toArray(); } /** * 覆盖并实现Collection中的toArray方法 */ public <T> T[] toArray(T[] contents) { return toArrayList().toArray(contents); } /** * 私有方法,供AbstractCollection内部使用 */ @SuppressWarnings("unchecked") private ArrayList<Object> toArrayList() { ArrayList<Object> result = new ArrayList<Object>(size()); for (E entry : this) { result.add(entry); } return result; } /** * 重写超类Object的toString方法,返回此集合的字符串形式 */ @Override public String toString() { if (isEmpty()) { return "[]"; } StringBuilder buffer = new StringBuilder(size() * 16); buffer.append('['); Iterator<?> it = iterator(); while (it.hasNext()) { Object next = it.next(); if (next != this) { buffer.append(next); } else { buffer.append("(this Collection)"); } if (it.hasNext()) { buffer.append(", "); } } buffer.append(']'); return buffer.toString(); }}
AbstractCollection类总结:
- 此类提供了 Collection 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。
- 本类默认是不是可修改的,即不支持add,由于addAll依赖于add,所以addAll也是不支持的,要支持添加功能,就需要重写这个add方法
- size,iterator这两个方法没有实现,所以要编写自己的collection,需要实现这两个方法即可
- 本类没有对equals和hashCode进行重写,但是对toString进行了重写
AbstractList抽象类探索
/** * AbstractList是List接口的抽象实现,针对支持随机访问的后台存储进行了优化。 此实现不支持添加或替换。 一个子类必须实现抽象方法get()和size(),并创建一个可修改的List,这是必要的,以覆盖当前抛出UnsupportedOperationException的add()方法。 */public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { private class SimpleListIterator implements Iterator<E> { } private final class FullListIterator extends SimpleListIterator implements ListIterator<E> { } private static final class SubAbstractListRandomAccess<E> extends SubAbstractList<E> implements RandomAccess { } private static class SubAbstractList<E> extends AbstractList<E> { } /** * 将指定的对象插入到此列表中的指定位置。 该对象被插入指定位置的任何先前元素之前。 如果位置等于此列表的大小,则会在最后添加该对象。 * 希望支持添加功能的具体实现必须覆盖此方法。 */ public void add(int location, E object) { throw new UnsupportedOperationException(); } /** * 添加元素,在尾部添加新的元素 */ @Override public boolean add(E object) { add(size(), object); return true; } /** * 将列表中指定的集合中的对象插入。 这些对象按照从集合的迭代器返回的顺序添加。 */ public boolean addAll(int location, Collection<? extends E> collection) { Iterator<? extends E> it = collection.iterator(); while (it.hasNext()) { add(location++, it.next()); } return !collection.isEmpty(); } /** * Removes all elements from this list, leaving it empty. */ @Override public void clear() { removeRange(0, size()); } /** * 将指定的对象与此列表进行比较,如果相等则返回true。 当两个列表都以相同的顺序包含相同的对象时相等。 */ @Override public boolean equals(Object object) { if (this == object) { return true; } if (object instanceof List) { List<?> list = (List<?>) object; if (list.size() != size()) { return false; } Iterator<?> it1 = iterator(), it2 = list.iterator(); while (it1.hasNext()) { Object e1 = it1.next(), e2 = it2.next(); if (!(e1 == null ? e2 == null : e1.equals(e2))) { return false; } } return true; } return false; } /** * Returns the element at the specified location in this list. * * @param location * the index of the element to return. * @return the element at the specified index. * @throws IndexOutOfBoundsException * if {@code location < 0 || location >= size()} */ public abstract E get(int location); /** * 返回此列表的哈希码。 哈希码是通过考虑每个元素的哈希码来计算的。 */ @Override public int hashCode() { int result = 1; Iterator<?> it = iterator(); while (it.hasNext()) { Object object = it.next(); result = (31 * result) + (object == null ? 0 : object.hashCode()); } return result; } /** * 搜索指定对象的此列表,并返回第一次出现的索引。 */ public int indexOf(Object object) { ListIterator<?> it = listIterator(); if (object != null) { while (it.hasNext()) { if (object.equals(it.next())) { return it.previousIndex(); } } } else { while (it.hasNext()) { if (it.next() == null) { return it.previousIndex(); } } } return -1; } /** * 返回此列表元素的迭代器。 元素按照与列表中相同的顺序进行迭代。 */ @Override public Iterator<E> iterator() { return new SimpleListIterator(); } /** * 在此列表的元素上返回一个ListIterator。 元素以与列表中相同的顺序进行迭代。 */ public ListIterator<E> listIterator() { return listIterator(0); } /** * 返回此列表元素的列表迭代器。 元素按照与列表中相同的顺序进行迭代。 迭代从指定位置开始。 */ public ListIterator<E> listIterator(int location) { return new FullListIterator(location); } public E remove(int location) { throw new UnsupportedOperationException(); } /** * 从开始到结束的索引减去一个指定范围内的对象。 */ protected void removeRange(int start, int end) { Iterator<?> it = listIterator(start); for (int i = start; i < end; i++) { it.next(); it.remove(); } } public E set(int location, E object) { throw new UnsupportedOperationException(); } /** * 返回此列表的连续元素的一部分作为视图。 如果开始等于结束,则返回的视图将为零长度。 在返回的子列表中发生的任何更改都将反映到原始列表中,反之亦然。 所有由原始列表支持的可选操作也将由此子列表支持。 */ public List<E> subList(int start, int end) { if (start >= 0 && end <= size()) { if (start <= end) { if (this instanceof RandomAccess) { return new SubAbstractListRandomAccess<E>(this, start, end); } return new SubAbstractList<E>(this, start, end); } throw new IllegalArgumentException(); } throw new IndexOutOfBoundsException(); }}
阅读全文
0 0
- Java基础知识之容器(一:容器整体框架探索)
- Java基础知识之容器(一)
- Java基础知识之集合(容器)简介
- 黑马程序员——java基础知识之集合框架(容器)
- Spring框架之SpringIoc容器(一)
- Java容器-整体结构
- java之容器学习(一)
- java容器(一)
- java容器(一)
- java容器(一)
- Java容器(一):容器总结
- 实训 Java基础知识---容器
- JAVA 基础知识 容器
- java容器,java框架
- JAVA 容器(一)-----综述
- java容器(一)概述
- 【JAVA之容器】1.集合框架体系
- java容器框架图
- 在Windows上安装安全扫描工具nmap
- 修改tomcat默认的编码方式
- flask web开发创建虚拟博客文章数据bug AttributeError: 'NoneType' object has no attribute 'encode'的解决
- HTTP与HTTPS的区别
- myeclipse安装重启后,preferences里找不到PyDev的问题
- Java基础知识之容器(一:容器整体框架探索)
- 搭建nginx rtmp直播服务器,ffmpeg模拟推流
- 关于Fragment重叠问题(二)
- 判断checkbox是否被选中
- selinux-编写策略
- 操作系统FIFO算法
- windows7下启动mysql服务出现服务名无效的原因及解决方法
- 如何成为大神
- 布隆过滤器