java集合源码

集合源码

1.ArrayList

1.默认属性

private static final long serialVersionUID = 8683452581122892189L;
	//默认的容量
    private static final int DEFAULT_CAPACITY = 10;
	//共享的空数组实例,供有参构造器使用,将其与无参构造器区分开来
    private static final Object[] EMPTY_ELEMENTDATA = {};
	//共享的空数组实例,供无参构造器使用,将其与其他构造器区分开来
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
	//用来存储数据的数组
	//transient表示序列化时忽略改数组
    transient Object[] elementData; // non-private to simplify nested class access
	维护大小
    private int size;

2.构造方法

//指定一初始化容量,创建一个长度指定的object集合 
public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            //如果初始化长度为0复制给一个空数组
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            //否否则就抛出异常
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
//无参构造初始化一个空数组
public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
//传如一个集合 
public ArrayList(Collection<? extends E> c) {
    	//先将集合转换为数组
        Object[] a = c.toArray();
    	//如果集合的长度不为0
        if ((size = a.length) != 0) {
            //如果该集合是arrlist结合直接复制给子类.原因是因为有的有的集合tochar返回的不是ocject类型的数组
            if (c.getClass() == ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            // 否则就赋值给一个空的数字
            elementData = EMPTY_ELEMENTDATA;
        }
    }

2.常用方法

1.add方法

//添加元素e
public boolean add(E e) {
    	//确认是否需要扩容
        ensureCapacityInternal(size + 1);  // size+1表示需要的最小长度
        elementData[size++] = e;//进行赋值
        return true;
    }

ensureCapacityInternal()源码

private void ensureCapacityInternal(int minCapacity) {
    //先调用calculateCapacity()方法再调用 ensureExplicitCapacity()方法
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

calculateCapacity()源码

 private static int calculateCapacity(Object[] elementData, int minCapacity) {
     //如果当前数组为空数组,最小长度则为DEFAULT_CAPACITY=10;(也就是添加的时候会初始化数组长度为10)
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
     //否则就返回最小容量
        return minCapacity;
    }

calculateCapacity()返回了现在所需的最小长度

ensureExplicitCapacity()源码

  private void ensureExplicitCapacity(int minCapacity) {
       //保证线程安全
        modCount++;

        // 如果最小长度大于先在数组的长度,调用grow方法
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

grow()的源码

 private void grow(int minCapacity) {
        // 记录旧的数组长度
        int oldCapacity = elementData.length;
     	//新的长度为元长度的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
     //如果新的长度还是小于最小长度,那么新长度就为最小长度
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
     //如果新长度大于数组的最大长度 MAX_ARRAY_SIZE= Integer.MAX_VALUE - 8;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            //调用hugeCapacity()计算新的大小
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
     	//使用copy复制一个新的数组
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

分析一下hugeCapacity()源码

 private static int hugeCapacity(int minCapacity) {
     //如果最小长度 < 0 抛出 OutOfMemoryError()异常
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
     //返回minCapacity和MAX_ARRAY_SIZE 比较如果 minCapacity>MAX_ARRAY_SIZE
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

2.添加到指定位置add(int index, E element)

//将元素添加到指定位置 
public void add(int index, E element) {
    //调用该方法判断下标
        rangeCheckForAdd(index);
    //再次确认新的容量
        ensureCapacityInternal(size + 1);  // Increments modCount!!
    //调用copy方法,将元素index后面的元素后移
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
    //将index位置的元素赋值
        elementData[index] = element;
    //大小++
        size++;
    }

分析 rangeCheckForAdd();源码

//如果index<0或者index > size 抛出  IndexOutOfBoundsException异常
private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

3.添加所有addAll(Collection<? extends E> c)

 public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
     	//确定新的容量
        ensureCapacityInternal(size + numNew);  // Increments modCount
     //将两个数组融合
        System.arraycopy(a, 0, elementData, size, numNew);
     //更新长度
        size += numNew;
        return numNew != 0;
    }

4.添加到指定位置addAll(int index, Collection<? extends E> c)

public boolean addAll(int index, Collection<? extends E> c) {
    //检查下标情况
        rangeCheckForAdd(index);

        Object[] a = c.toArray();
        int numNew = a.length;
    //确认新的容量
        ensureCapacityInternal(size + numNew);  // Increments modCount
    //确定需要后移的数量
        int numMoved = size - index;
    //如果不是最后一位位移
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);

    //融合    
    System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }

5. 删除指定索引元素 E remove(int index)。

 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;
    }
 private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
//ArrayList私有的方法 
private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // 下次gc机制回收
    }

6.根据元素值删除某个元素

public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
 private void fastRemove(int index) {
        modCount++;
        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
    }

7.获取单个元素

public E get(int index) {
    //检查index的范围(如果index>=size)抛出异常
        rangeCheck(index);
        return elementData(index);
    }

8.遍历元素

public Iterator<E> iterator() {
    return new Itr();
  }

itr是arraylist的一个私有内部类

 private class Itr implements Iterator<E> {
    
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        Itr() {}
     //判断是否相等
        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            //检查在遍历的时候是否被修改
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            //+1指向下一个元素
            cursor = i + 1;
            //记录当前元素的下标
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                //删除后cur回到上一个位置
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        @Override
        @SuppressWarnings("unchecked")
        public void forEachRemaining(Consumer<? super E> consumer) {
            Objects.requireNonNull(consumer);
            final int size = ArrayList.this.size;
            int i = cursor;
            if (i >= size) {
                return;
            }
            final Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length) {
                throw new ConcurrentModificationException();
            }
            while (i != size && modCount == expectedModCount) {
                consumer.accept((E) elementData[i++]);
            }
            // update once at end of iteration to reduce heap write traffic
            cursor = i;
            lastRet = i - 1;
            checkForComodification();
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

9.设置元素set(int index, E element)

  public E set(int index, E element) {
      //检查边界
        rangeCheck(index);
      //老的元素
        E oldValue = elementData(index);
      //修改为新的元素
        elementData[index] = element;
      //返回老的元素
        return oldValue;
    }

10 判断元素是否存在

public boolean contains(Object o) {
    //调用index方法
        return indexOf(o) >= 0;
    }
  public int indexOf(Object o) {
      //如果为null
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            //使用遍历比较
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
      //否则返回-1
        return -1;
    }

2.LinkedList

LinkedList 的特点:

  • 底层实现了双向链表双队列特点
  • 可以添加任意元素(元素可重复),包括 null
  • 线程不安全,没有实现同步

1.默认属性

transient int size = 0;
//使用node节点来存储元素,使用的是双向链表

    transient Node<E> first;
  
    transient Node<E> last;

    public LinkedList() {
    }

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;
        }
    }

2.构造方法

//无参构造
public LinkedList() {
    }

    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

addALL(方法源码

//这里也调用了addAll()方法,接着向下看
public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
public boolean addAll(int index, Collection<? extends E> c) {
    //检查索引(index >= 0 && index <= size;)
        checkPositionIndex(index);
   //转化为数组
        Object[] a = c.toArray();
    	//得到a的长度
        int numNew = a.length;
    	//如果为0则直接返回
        if (numNew == 0)
            return false;
		//声明两个节点
        Node<E> pred, succ;
    	//如果index=size(用来进行追加)
        if (index == size) {
            succ = null;
            pred = last;
        } else {
            //从某个位置进行插入
            succ = node(index);
            pred = succ.prev;
        }
    /*
    node的源码(可以看到是用来寻找要插入的位置的节点的节点)
     Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
    */
    
		//遍历数组
        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> newNode = new Node<>(pred, e, null);//创建个数组pre指向pred
            if (pred == null)//如何前一个为空
                first = newNode;//首节点就为该节点
            else
                pred.next = newNode; //否则pred的next就等于该节点
            pred = newNode;
        }
    //succ为空
        if (succ == null) {
            
            last = pred; //将最后节点指向该节点
        } else {
            pred.next = succ; //否则关联本来的节点
            succ.prev = pred;
        }
        size += numNew;
        modCount++;
        return true;
    }

3.添加方法

public boolean add(E e) {
        linkLast(e);
    /*
    void linkLast(E e) {
    //创建个节点指向last
        final Node<E> l = last;
        //创建个新的节点pre指向last
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;//更新last
        if (l == null)
        //如果为空fis指向该节点
            first = newNode;
        else
        //否则
            l.next = newNode;
        size++;
        modCount++;
    }
    */
        return true;
    }

批量添加

//这个是上面构造方法调用的方法
public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }

4.删除方法

public boolean remove(Object o) {
    //如果为空
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    /*
                    
                     E unlink(Node<E> x) {
                        // assert x != null;
                        //复制一份当前元素
                        final E element = x.item;
                        //得到上一个和下一个元素
                        final Node<E> next = x.next;
                        final Node<E> prev = x.prev;
                        //如果上一个为空,则x为头结点,first指向x的下一个
                        if (prev == null) {
                            first = next;
                        } else {
                        //删除操作
                            prev.next = next;
                            x.prev = null;
                        }
                        //如果x为空表明x为为尾节点
                        if (next == null) {
                            last = prev;
                        } else {
                        //否则操作
                            next.prev = prev;
                            x.next = null;
                        }
                        x.item = null;
                        size--;
                        modCount++;
                        return element;
   				 }
                               
                    */
                    return true;
                }
            }
            //相同操作
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
//调用的是removeFirst()方法
public E remove() {
        return removeFirst();
    }

removeFirst()源码

 public E removeFirst() {
     //赋值第一个元素
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
     //调用unlinkFirst()
        return unlinkFirst(f);
     /*
     private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        //清空
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        //使得转移
        first = next;
        //如果只有一个节点的情况
        if (next == null)
            last = null;
        else
        //清空next的pre
            next.prev = null;
        size--;
        modCount++;
        return element;
    }
     */
    }

removeLast()源码

//和removeLast()方法相同
public E removeLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return unlinkLast(l);
    }

根据下标移除

public E remove(int index) {
    //检查index
        checkElementIndex(index);
    //同样调用unlink方法node()方法获得index位置的节点,调用unlinked方法删除节点
        return unlink(node(index));
    }

删除链表中第一次出现的元素

  public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }

remove方法

 public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

删除最后一个出现的指定元素

  public boolean removeLastOccurrence(Object o) {
      //使用后续遍历和删除第一个元素的原理相同
        if (o == null) {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = last; x != null; x = x.prev) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }

5.添加方法

//获取指定下标元素 
public E get(int index) {
        checkElementIndex(index);
     //调用node()方法获取当前节点
        return node(index).item;
    }

获取第一个和最后一个元素的值的方法相同

 
public E getFirst() {
        final Node<E> f = first;
        if (f == null)
            throw new NoSuchElementException();
        return f.item;
    }
    public E getLast() {
        final Node<E> l = last;
        if (l == null)
            throw new NoSuchElementException();
        return l.item;
    }

根据元素获取下标

//使用遍历找到第一个发现的元素
public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }

6.修改方法

 public E set(int index, E element) {
     //检查下标
        checkElementIndex(index);
     //获取当前位置的元素
        Node<E> x = node(index);
     //得到当前元素的值
        E oldVal = x.item;
     //修改当前元素的值
        x.item = element;
        return oldVal;
    }

7.栈的相关操作

//调用的是addFirst()方法
public void push(E e) {
        addFirst(e);
    }
//调用removeFirst() 
public E pop() {
        return removeFirst();
    }
//如果头结点为空,就返回空.否则则返回头结点的值 
public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }

8.队列相关的操纵

public boolean offer(E e) {
    //在末尾添加元素调用课linkLast()方法
        return add(e);
    }
 public E poll() {
     //删除第一个节点
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

9.遍历器

//继承了父类的方法 
private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1;
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor-1;
        }

        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                AbstractList.this.set(lastRet, e);
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                AbstractList.this.add(i, e);
                lastRet = -1;
                cursor = i + 1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

3.Vector

1.默认属性

 	protected Object[] elementData; //存储数据的数组

    protected int elementCount; //元素数量

    protected int capacityIncrement; //容量增长系数(每次vector容量增加的增加值)

    private static final long serialVersionUID = -2767605614048989439L; //序列化版本号

2.构造函数

//无参构造方法 
public Vector() {
    //默认容量为10
        this(10);
    }
//初始化容量构造方法
public Vector(int initialCapacity) {
    //这里调用的是那另有个构造方法(增长系数为0)
        this(initialCapacity, 0);
    }
//指定容量和增长系数的方法
 public Vector(int initialCapacity, int capacityIncrement) {
        super();
     //如果容量<0则抛出异常
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
     //初始化数组容量
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }
//传递集合的构造方法(和前面arraylist的实现原理相同)
public Vector(Collection<? extends E> c) {
        Object[] a = c.toArray();
        elementCount = a.length;
        if (c.getClass() == ArrayList.class) {
            elementData = a;
        } else {
            elementData = Arrays.copyOf(a, elementCount, Object[].class);
        }
    }

3.添加方法

public synchronized boolean add(E e) {
        modCount++;
    //调用ensureCapacityHelper()方法
        ensureCapacityHelper(elementCount + 1);
  
        elementData[elementCount++] = e;
        return true;
    }

ensureCapacityHelper()源码分析

 private void ensureCapacityHelper(int minCapacity) {
        //如果最小值 > 容量
        if (minCapacity - elementData.length > 0)
            //调用grow方法
            grow(minCapacity);
    }

grow源码分析

 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
     //如果增长系数>0扩容机制就是老的容量+增长系数如果增长系数<0那就是2倍扩容
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
     //二倍扩容还是不够的话容量及时现在所需要的最小容量  
     if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
     //如果新的容量>数组最大长度,则会调用hugeCapacity()方法
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

hugeCapacity()源码分析

//这和arraylist是一样的 
private static int hugeCapacity(int minCapacity) {
     //如果最小容量一溢出则抛出异常
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
     //否则
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
//将元素添加到指定位置
public void add(int index, E element) {
        insertElementAt(element, index);
    }
/*
public synchronized void insertElementAt(E obj, int index) {
        modCount++;
        //如果大于元素数量抛出异常
        if (index > elementCount) {
            throw new ArrayIndexOutOfBoundsException(index
                                                     + " > " + elementCount);
        }
        //判断是否需要扩容
        ensureCapacityHelper(elementCount + 1);
        //调用copy方法来实现位移
        System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
      	//给元赋值
      	elementData[index] = obj;
        elementCount++;
    }
*/
public synchronized boolean addAll(int index, Collection<? extends E> c) {
        modCount++;
   //检查下标
        if (index < 0 || index > elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        Object[] a = c.toArray();
        int numNew = a.length;
    //是否扩容
        ensureCapacityHelper(elementCount + numNew);
    //移动
        int numMoved = elementCount - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);
    //赋值

        System.arraycopy(a, 0, elementData, index, numNew);
        elementCount += numNew;
        return numNew != 0;
    }
//和add方法相同但是没有返回值 
public synchronized void addElement(E obj) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = obj;
    }

4.删除元素

 public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        E oldValue = elementData(index);

        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--elementCount] = null; // Let gc do its work

        return oldValue;
    }
public synchronized boolean removeElement(Object obj) {
        modCount++;
    //计算出元素下标
        int i = indexOf(obj);
    /*
    public synchronized int indexOf(Object o, int index) {
        if (o == null) {
            for (int i = index ; i < elementCount ; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = index ; i < elementCount ; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }
    */
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    }

5.修改元素

//和arraylist相同 
public synchronized E set(int index, E element) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

6.获取元素

public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    /*
    E elementData(int index) {
        return (E) elementData[index];
    }
    */
    }

获取第一个元素

public synchronized E firstElement() {
    if (elementCount == 0) {
        throw new NoSuchElementException();
    }
    return elementData(0);
}

2、lastElement()

获取最后一个元素

public synchronized E lastElement() {
    if (elementCount == 0) {
        throw new NoSuchElementException();
    }
    return elementData(elementCount - 1);
}

HashSet源码

1.存储结构
HashSet 的底层是利用HashMap(邻接表结构)进行存储的。

hashSet 将存入的元素作为 hashMap的key,而所有key对应的value都是一个用static final 修饰的,

名为PRESENT的Object 类对象(此对象有地址引用,但是实际内容为空)。

可以存放null但是只能有一个空值

不能有重复的元素

基础属性

static final long serialVersionUID = -5024744406713321676L;
	//使用hashmap来存储
    private transient HashMap<E,Object> map;

    // 定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final
    private static final Object PRESENT = new Object();

1.构造方法

//无参构造创建一个map集合
public HashSet() {
        map = new HashMap<>();
    }
/*构造包含指定集合中所有元素的新集合。
     * 创建的HashMap带有默认负载因子(0.75)和初始容量,
     * 初始容量足以包含指定集合中的元素。
     */

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }
 //后台的HashMap实例具有指定的初始容量和指定的负载因子

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
	//指定初始化容量构造
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
	//改用linkedHashMap存储
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

2.添加方法

//这里调用了map的put()方法
public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

map.put()源码

 public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

hash()的源码

 static final int hash(Object key) {
        int h;
     //如果key是0则为0,否则将hashcode值
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

putVal()源码

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
    //声明一个存储node节点的数组,和一个node节点,int n,i
        Node<K,V>[] tab; Node<K,V> p; int n, i;
    	//如果map的table为空或者tab.length=0;
        if ((tab = table) == null || (n = tab.length) == 0)
            //重新修改tab的大小
            n = (tab = resize()).length;
    		//(n - 1) & hash计算出存放的索引存放将对应的元素赋值给P
        if ((p = tab[i = (n - 1) & hash]) == null)
            //如果为空的话,就存放进去
            tab[i] = newNode(hash, key, value, null);
        else {//如果不为null并且存在元素
            //申明辅助变量
            Node<K,V> e; K k;
            //如果当前索引对应的链表的第一个元素和添加的元素的hash值形同并且key的内容和p指定的node节点的key是同一个对象
            //将p赋值给e
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            //判断p是不是一个红黑树
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {//hash值相同但是第一个key不相同,看看链表后面有没有相同的值,如果没有直接添加
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        //添加到最后一个元素
                        p.next = newNode(hash, key, value, null);
                        //如果需要转为红黑树(是否达到8个节点,在转成红黑树时还要判断是否当前长度小于64,则会进行扩容)
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    //相同的判断
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            //如果e!=null代表改key已经存在
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
    //检查现在的大小是否达到平衡负载达到的话就扩容
        if (++size > threshold)
            resize();
    //该方法为空方法(为了让子类来重写发方法)
    /*
    void afterNodeAccess(Node<K,V> p) { }
    */
        afterNodeInsertion(evict);
        return null;
    }

resize()源码(扩容机制)

 final Node<K,V>[] resize() {
        Node<K,V>[] oldTab = table;
        int oldCap = (oldTab == null) ? 0 : oldTab.length;
        int oldThr = threshold;
        int newCap, newThr = 0;
        if (oldCap > 0) {
            //如果当前容量大于最大容量
            if (oldCap >= MAXIMUM_CAPACITY) {
                threshold = Integer.MAX_VALUE;
                return oldTab;
            }
            //如果新的容量小于最大容量,并且老的容量大于默认容量
            else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                     oldCap >= DEFAULT_INITIAL_CAPACITY)
                newThr = oldThr << 1; // 临界值变为上个临界值的2倍
        }
        else if (oldThr > 0) // initial capacity was placed in threshold
            newCap = oldThr;
        else {              
            //如果数组为空的情况计算新的大小容量默认值16,负载因子:扩容的临界值(0.75*容量)16*0.75=12
            newCap = DEFAULT_INITIAL_CAPACITY;
            newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
        }
        if (newThr == 0) {
            float ft = (float)newCap * loadFactor;
            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                      (int)ft : Integer.MAX_VALUE);
        }
        threshold = newThr;
        @SuppressWarnings({"rawtypes","unchecked"})
     //创建一个新的数组
        Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
        table = newTab;
        if (oldTab != null) {
            for (int j = 0; j < oldCap; ++j) {
                Node<K,V> e;
                if ((e = oldTab[j]) != null) {
                    oldTab[j] = null;
                    if (e.next == null)
                        newTab[e.hash & (newCap - 1)] = e;
                    else if (e instanceof TreeNode)
                        ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
                    else { // preserve order
                        Node<K,V> loHead = null, loTail = null;
                        Node<K,V> hiHead = null, hiTail = null;
                        Node<K,V> next;
                        do {
                            next = e.next;
                            if ((e.hash & oldCap) == 0) {
                                if (loTail == null)
                                    loHead = e;
                                else
                                    loTail.next = e;
                                loTail = e;
                            }
                            else {
                                if (hiTail == null)
                                    hiHead = e;
                                else
                                    hiTail.next = e;
                                hiTail = e;
                            }
                        } while ((e = next) != null);
                        if (loTail != null) {
                            loTail.next = null;
                            newTab[j] = loHead;
                        }
                        if (hiTail != null) {
                            hiTail.next = null;
                            newTab[j + oldCap] = hiHead;
                        }
                    }
                }
            }
        }
        return newTab;
    }

3.删除方法

 public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }
//调用的map的删除方法

4.遍历器

public Iterator<E> iterator() {
        return map.keySet().iterator();
    } //使用map的keyset()的遍历器

LinkedHashSet

1.基础属性

LinkedHashSet继承了HashSet

2.构造方法

public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }


    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    
    public LinkedHashSet() {
        super(16, .75f, true);
    }

 
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        //这里调用了addAll()方法
        addAll(c);
    }

addAll()源码

public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            //这里的add()是hashset里面的add()方法
            if (add(e))
                modified = true;
        return modified;
    }

3.添加方法

ll) {
loTail.next = null;
newTab[j] = loHead;
}
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
}
}
}
}
return newTab;
}


### 3.删除方法

```java
 public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }
//调用的map的删除方法

4.遍历器

public Iterator<E> iterator() {
        return map.keySet().iterator();
    } //使用map的keyset()的遍历器

LinkedHashSet

1.基础属性

LinkedHashSet继承了HashSet

2.构造方法

public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }


    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    
    public LinkedHashSet() {
        super(16, .75f, true);
    }

 
    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        //这里调用了addAll()方法
        addAll(c);
    }

addAll()源码

public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            //这里的add()是hashset里面的add()方法
            if (add(e))
                modified = true;
        return modified;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值