java collection 集合源码分析(一)

collection 为java集合的接口,collection的接口继承Iterable

public interface Collection<E> extends Iterable<E>

没有自己在画类图了 找到网上有大哥画的关系图如下

上图中有个位置可能错了,AbstrctList应该继承自

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>

一、List(接口)

1、ArrayList

内部持有一个Object[] 数组

 /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;  //默认大小

    /**
     * Shared empty array instance used for empty instances.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {}; //对象数组

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
     * DEFAULT_CAPACITY when the first element is added.
     */
    private transient Object[] elementData;

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size; //数组大小

所有的操作基于这个数组进行组织,一般不轻易对这个数组进行遍历,一般多用system.arraycopy的方式进行操作,删除的动作有时候依赖与gc来回收,如下删除方法:

   /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * @param index the index of the element to be removed
     * @return the element that was removed from the list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);  //通过副本的形式完成操作
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

2、LinkedList

LinkedList,内部持有一系列的Node ,node结构如下

private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

从上可以看出 node中 保存了前一个和后一个的节点信息,和数据,分为三部分

对节点的管理如下:

    transient int size = 0; //有多少节点
   
       /**
     * Pointer to first node.
      * Invariant: (first == null && last == null) ||
      *            (first.prev == null && first.item != null)
      */
     transient Node<E> first; //头节点
 
     /**
      * Pointer to last node.
      * Invariant: (first == null && last == null) ||
      *            (last.next == null && last.item != null)
      */
     transient Node<E> last; //尾节点

所有的操作围绕对节点的增删来操作,看一个添加所有的操作

    /**  
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection‘s
     * iterator.
     *
     * @param  c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public LinkedList(Collection<? extends E> c) { 
        this();
        addAll(c);
    }   //构造
    
        /**
     * Appends all of the elements in the specified collection to the end of
     * this list, in the order that they are returned by the specified
     * collection‘s iterator.  The behavior of this operation is undefined if
     * the specified collection is modified while the operation is in
     * progress.  (Note that this will occur if the specified collection is
     * this list, and it‘s nonempty.)
     *
     * @param c collection containing elements to be added to this list
     * @return {@code true} if this list changed as a result of the call
     * @throws NullPointerException if the specified collection is null
     */
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
    
       /**
     * Inserts all of the elements in the specified collection into this
     * list, starting at the specified position.  Shifts the element
     * currently at that position (if any) and any subsequent elements to
     * the right (increases their indices).  The new elements will appear
     * in the list in the order that they are returned by the
     * specified collection‘s iterator.
     *
     * @param index index at which to insert the first element
     *              from the specified collection
     * @param c collection containing elements to be added to this list
     * @return {@code true} if this list changed as a result of the call
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @throws NullPointerException if the specified collection is null
     */
    public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)
            return false;

        Node<E> pred, succ;
        if (index == size) {
            succ = null;
            pred = last;
        } else {
            succ = node(index);  //返回索引处的特征节点,这个方法会优化从头部还是从尾部查找的过程具体参看源码
            pred = succ.prev;
        }

        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> newNode = new Node<>(pred, e, null);
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            pred = newNode;
        }  //添加过程

        if (succ == null) {
            last = pred;
        } else {
            pred.next = succ;
            succ.prev = pred;
        }

        size += numNew;
        modCount++;
        return true;
    }

3、Vector

arrayList类似,源码多处增加了synchronized 关键字,线程安全

二、Set(接口)

1、HashSet

HashSet内部实际持有的是一个hashmap对象,所有的操作都是通过操作map实现,这个map是无值,只有key,

内部的一个hashmap对象

    private transient HashMap<E,Object> map;

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); //开辟一个比原有集合4/3大小的集合。默认16
        addAll(c);
    }

看一个获取迭代器的方法

    /**
     * Returns an iterator over the elements in this set.  The elements
     * are returned in no particular order.
     *
     * @return an Iterator over the elements in this set
     * @see ConcurrentModificationException
     */
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

2、TreeSet

TreeSet也是通过map来实现

private transient NavigableMap<E,Object> m; //这里使用的是NavigableMap,这个继承自SortedMap接口 since1.6之后

其他的方法都是调用map的实现,在map中在看

三、Map(接口)

Map是一个独立的接口,内部包含一个Entry的接口,用于管理每个节点

public interface Map<K,V>{
    interface Entry<K,V> {
    
    }
}
时间: 2024-08-07 15:31:47

java collection 集合源码分析(一)的相关文章

java collection 集合源码分析(二) map

Map(接口) Map是一个独立的接口,内部包含一个Entry的接口,用于管理每个节点 public interface Map<K,V>{     interface Entry<K,V> {          } } AbstractMap 抽象类实现Map接口,常用的HashMap和TreeMap都继承此类 public abstract class AbstractMap<K,V> implements Map<K,V> 这个类下面提供了一个将Map

java collection 集合源码分析(三) map

TreeMap 首先看下TreeMap的头部声明的两个变量,TreeMap的排序利用红黑树进行     /**      * The comparator used to maintain order in this tree map, or      * null if it uses the natural ordering of its keys.      *      * @serial      */     private final Comparator<? super K> 

Java 集合源码分析(一)HashMap

目录 Java 集合源码分析(一)HashMap 1. 概要 2. JDK 7 的 HashMap 3. JDK 1.8 的 HashMap 4. Hashtable 5. JDK 1.7 的 ConcurrentHashMap 6. JDK 1.8 的 ConcurrentHashMap 7. 最后补充一下 HashMap 中的一些属性和方法 附:更这个系列感觉自己像是又挖了一个坑??,不过趁自己刚好工作不太忙,有空闲期,静下心来研究学习源码也是一件很值得做的事,自己尽量会把这个坑填完??.

Java小白集合源码的学习系列:Vector

目录 Vector源码学习 Vector继承体系 Vector核心源码 基本属性 构造器 扩容机制 Enumeration 概述 源码描述 具体操作 Vector总结 Vector源码学习 前文传送门: Java小白集合源码的学习系列:LinkedList Java小白集合源码的学习系列:ArrayList Vector是JDK1.0中的集合,是集合中的老大哥,其中大部分的方法都被synchronized关键字所修饰,与ArrayList和LinkedList不同,它是线程安全的(关于线程安全,

java.io.BufferedOutputStream 源码分析

BufferedOutputStream  是一个带缓冲区到输出流,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统. 俩个成员变量,一个是存储数据的内部缓冲区,一个是缓冲区中的有效字节数. /** * The internal buffer where data is stored. */ protected byte buf[]; /** * The number of valid bytes in the buffer. This value

Java split方法源码分析

Java split方法源码分析 1 public String[] split(CharSequence input [, int limit]) { 2 int index = 0; // 指针 3 boolean matchLimited = limit > 0; // 是否限制匹配个数 4 ArrayList<String> matchList = new ArrayList<String>(); // 匹配结果队列 5 Matcher m = matcher(inp

【JAVA】ThreadLocal源码分析

ThreadLocal内部是用一张哈希表来存储: 1 static class ThreadLocalMap { 2 static class Entry extends WeakReference<ThreadLocal<?>> { 3 /** The value associated with this ThreadLocal. */ 4 Object value; 5 6 Entry(ThreadLocal<?> k, Object v) { 7 super(k)

Java集合源码分析(四)Vector&lt;E&gt;

Vector<E>简介 Vector也是基于数组实现的,是一个动态数组,其容量能自动增长. Vector是JDK1.0引入了,它的很多实现方法都加入了同步语句,因此是线程安全的(其实也只是相对安全,有些时候还是要加入同步语句来保证线程的安全),可以用于多线程环境. Vector没有丝线Serializable接口,因此它不支持序列化,实现了Cloneable接口,能被克隆,实现了RandomAccess接口,支持快速随机访问. Vector<E>源码 如下(已加入详细注释): /*

Java集合源码分析(二)ArrayList

ArrayList简介 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类. ArrayList实现了Serializable接口,因此它支持序列化,能够通过