1)?容器之Collection
???Java中容器主要分為兩大類:Collection和Map,讓我們來看一下Collection下主要的繼承類和實現(xiàn)類。
???1.1)List:是一個有序的隊列,主要實現(xiàn)類如下圖所示。
???其中,ArrayList基于動態(tài)數(shù)組實現(xiàn),支持隨機訪問,但是增加和刪除需要移動數(shù)據(jù),是線程不安全的;LinkedList是以雙向鏈表實現(xiàn),隨機訪問需要移動指針,增加刪除操作不需要移動數(shù)據(jù),允許重復(fù),是線程不安全的;Vector基于動態(tài)數(shù)組實現(xiàn),是線程安全的。
???1.2)Queue:主要實現(xiàn)類如下圖所示。
???其中,PriorityQueue是基于堆結(jié)構(gòu)實現(xiàn),可以實現(xiàn)優(yōu)先隊列,線程不安全;LinkedList可以實現(xiàn)雙向隊列。
???1.3)Set:是一種不允許數(shù)據(jù)元素重復(fù)的集合,無序,主要實現(xiàn)類及接口如下圖所示。
???其中,HashSet實現(xiàn)Set接口,線程不安全,由哈希表(實際上是一個HashMap的實例)實現(xiàn),底層是一個HashMap來保存HashSet中的所有元素,允許null值;LinkedHashSet繼承HashSet,源碼中其構(gòu)造方法直接調(diào)用父類(HashSet)的構(gòu)造方法,而父類的構(gòu)造方法是HashMap實現(xiàn)所以LinkedHashSet也是HashMap實現(xiàn)的,線程不安全;
???這里要說一下TreeSet,它是AbstractSet接口的一個實現(xiàn)類,它的底層實現(xiàn)是TreeMap,而TreeMap的實現(xiàn)又借助了HashMap,所以,HashMap真的太重要了!TreeSet中元素是有序且不重復(fù)的,線程不安全,這里的有序是指按照關(guān)鍵字大小進行排序,實現(xiàn)原理是使用了比較器,源碼如下:
/**
* Constructs a new, empty tree set, sorted according to the specified
* comparator. All elements inserted into the set must be <i>mutually
* comparable</i> by the specified comparator: {@code comparator.compare(e1,
* e2)} must not throw a {@code ClassCastException} for any elements
* {@code e1} and {@code e2} in the set. If the user attempts to add
* an element to the set that violates this constraint, the
* {@code add} call will throw a {@code ClassCastException}.
*
* @param comparator the comparator that will be used to order this set.
* If {@code null}, the {@linkplain Comparable natural
* ordering} of the elements will be used.
*/
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
???總結(jié)一下ArrayList和LinkedList的異同點:首先,兩者都是線程不安全的;ArrayList是基于動態(tài)數(shù)組實現(xiàn)的,LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu);對于隨機訪問,ArrayList優(yōu)于LinkedList,因為LinkedList要移動指針;對于增加和刪除操作,LinkedList要好一些。
???總結(jié)一下ArrayList和Vector的異同點:ArrayList線程不安全,而Vector是線程安全的;在進行擴容操作時,ArrayList每次resize為當(dāng)前的1.5倍,而Vector每次擴大2倍(如下源碼所示)
???ArrayList擴容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//擴大為原來的1.5倍,因為oldCapacity >> 1 相當(dāng)于 oldCapacity / 2
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
???Vector擴容
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}