java-Collection類源碼

一、接口的API

1Collection<E>

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 removeAll(Collection<?> c);

boolean retainAll(Collection<?> c);//取交集

void clear();

boolean equals(Object o);

int hashCode();

2、List<E>

boolean addAll(int index, Collection<? extends E> c);

    E get(int index);

    E set(int index, E element);

    void add(int index, E element);

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

List接口繼承與Collection接口。由上可見,List相比於Collection,額外提供的方法均與index有關。即List是一個有序集合,內部的每一個元素都可以通過下標直接定位。

3、Set<E>

Set提供的方法與Collection完全一致。Set規範:元素不可重複。

4、SortedSet<E>

Comparator<? super E> comparator();

    SortedSet<E> subSet(E fromElement, E toElement);

    SortedSet<E> headSet(E toElement);

    SortedSet<E> tailSet(E fromElement);

    E first();

E last();

顧名思義,有序的Set。但與LinkedHashSet不同的是,前者通過Comparator比較元素的大小來進行排序,後者則是維護元素的插入順序。

SortedSet的這種維護是時刻維護的(就跟堆維護堆序一樣),每次插入元素的時候就會根據其大小放入合適的位置。

實現類有TreeSet

5、Queue<E>

boolean add(E e);

    boolean offer(E e);

    E remove();

    E poll();

    E element();

E peek();

隊列:先進先出。注意,這裏的“進”並不一定是按照時間順序來衡量,有可能是按照其他順序來模擬時間上的先後。

 

 

拋出異常

返回特殊值

插入

add(e)

offer(e)

移除

remove()

poll()

檢查

element()

peek()

 

6、Deque<E>

    void addFirst(E e);

    void addLast(E e);

    boolean offerFirst(E e);

    boolean offerLast(E e);

    E removeFirst();

    E removeLast();

    E pollFirst();

    E pollLast();

    E getFirst();

    E getLast();

    E peekFirst();

    E peekLast();

    boolean removeFirstOccurrence(Object o);

    boolean removeLastOccurrence(Object o);

    boolean add(E e);

    boolean offer(E e);

    E remove();

    E poll();

    E element();

    E peek();

    void push(E e);

    E pop();

    boolean remove(Object o);

    boolean contains(Object o);

    public int size();

    Iterator<E> iterator();

Iterator<E> descendingIterator();

繼承於Queue,是一個雙向隊列。


二、實現類

1、ArrayList<E>

public class ArrayList<E> extends AbstractList<E>

        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

 

1、ArrayList存儲元素的數據結構實際上是一個數組,數組本身的大小是不可變的。因此,在向ArrayList中插入元素時,如果滿足觸發條件,會將ArrayList進行擴容。擴容後的數組大小通常滿足:newCapacity = oldCapacity + (oldCapacity >> 1);

2、ArrayList是有最大存儲容量的:

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private static int hugeCapacity(int minCapacity) {

        if (minCapacity < 0) // overflow

            throw new OutOfMemoryError();

        return (minCapacity > MAX_ARRAY_SIZE) ?

            Integer.MAX_VALUE :

            MAX_ARRAY_SIZE;

}

3、modCount??

4、在刪除ArrayList中的元素後,將數組的後邊的元素置爲null,以使GC回收,避免內存泄漏。如:

public void clear() {

         modCount++;

         // clear to let GC do its work

         for (int i = 0; i < size; i++)

             elementData[i] = null;

         size = 0;

}

5、ArrayList中對數組的操作是通過System類的

public static native void arraycopy(Object src,  int  srcPos,

                                        Object dest, int destPos,                                         int length);

執行的。

6、迭代器

7、線程不安全舉例以及解決方案見Vector思考2.

2、LinkedList<E>

public class LinkedList<E>

    extends AbstractSequentialList<E>

    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList實現了Deque接口,是一個雙向隊列。

 

1、LinkedList的實現是建立在內部靜態類

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、LinkedList是有序的,而且是雙向的,可以儲存重複的元素,甚至是多個null

3、學習LinkedList的源碼,發現在向LinkedList中插入、刪除元素時,需時刻注意操作前後相鄰兩個元素關係的維護,避免“鏈子”斷掉。對於每一個節點,不僅要維護自己的next,還要維護自己的prev。同時還要注意當前節點的next或者prev是不是null

4、注意,向LinkedList中插入null時,只代表這個Nodeitem屬性是null,而這個Node卻一定不是null。其實,LinkedList這條由Node串聯起來的“鏈條”根本不存在爲nullNode,但是存在爲Null的元素(元素只是Nodeitem屬性)。

5、LinkedList實現了List接口,因此支持按index進行的元素的操作,但他沒有實現RandomAccess,也就是說它不支持隨機訪問,它的按index操作實際是通過由鏈條的兩端向中間一個一個訪問實現的。

6、LinkedList實現了Deque接口,因此同時具備隊列的特點,支持poll(),offer()等方法。

7、迭代器:實現很簡單,看源碼就行。

3、Vector<E>

public class Vector<E>

    extends AbstractList<E>

    Implements List<E>, RandomAccess, Cloneable, java.io.Serializable

1、VectorArrayList實現的接口完全一致。推斷功能也會類似。

2、Vector的擴容:

int newCapacity = oldCapacity + ((capacityIncrement > 0) ?

                                         capacityIncrement : oldCapacity);

如果沒指定擴容參數,每次自動擴充一倍。

3、Vector的方法大部分被synchronized 修飾,因此Vector是線程安全的。

思考:1ArrayListVector的區別在哪?

Vector是線程安全的,因此性能較低,已逐漸被棄用;而ArrayList是線程不安全的,但性能比Vector高。Vector每次擴容一倍,而ArrayList每次擴容一半。

思考2ArrayList線程不安全舉例,如何解決?

ArrayList線程不安全舉例:

package com.lv.Number;

 

import java.util.ArrayList;

import java.util.List;

 

public class ArrayListInThread implements Runnable {

 

// 線程不安全

private List<String> threadList = new ArrayList<String>();

// 線程安全

// private List<string> threadList = Collections.synchronizedList(new

// ArrayList<string>());

 

@Override

public void run() {

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

// 把當前線程名稱加入list

threadList.add(Thread.currentThread().getName());

}

 

public static void main(String[] args) throws InterruptedException {

ArrayListInThread listThread = new ArrayListInThread();

 

for (int i = 0; i < 100; i++) {

Thread thread = new Thread(listThread, String.valueOf(i));

thread.start();

}

 

// 等待子線程執行完

Thread.sleep(2000);

 

System.out.println(listThread.threadList.size());

// 輸出list中的值

for (int i = 0; i < listThread.threadList.size(); i++) {

if (listThread.threadList.get(i) == null) {

System.out.println();

}

System.out.print(listThread.threadList.get(i) + "  ");

}

}

}

解決方式:private List<string> threadList = Collections.synchronizedList(new

 ArrayList<string>());

public static <T> List<T> synchronizedList(List<T> list) {

        return (list instanceof RandomAccess ?

                new SynchronizedRandomAccessList<>(list) :

                new SynchronizedList<>(list));

    }

4、Stack<E>

public

class Stack<E> extends Vector<E>

基於Vector擴充實現了一個棧(後進先出)的數據結構。同時也具備Vector(動態數組)的功能。

5、HashSet

public class HashSet<E>

    extends AbstractSet<E>

implements Set<E>, Cloneable, java.io.Serializable

基於HashMap類。

6、LinkedHashSet

基於LinkedHashMap類。

7、TreeSet

基於TreeMap類。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章