日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java集合Collection源码系列-ArrayList源码分析

發(fā)布時間:2023/12/15 java 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java集合Collection源码系列-ArrayList源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java集合系列-ArrayList源碼分析

文章目錄

  • Java集合系列-ArrayList源碼分析
  • 前言
  • 一、為什么想去分析ArrayList源碼?
  • 二、源碼分析
    • 1.宏觀上分析List
    • 2.方法匯總
  • 三、ArrayList基本說明
  • 總結


前言

一、為什么想去分析ArrayList源碼?

大家都懂,這個很重要
備注: 源碼分析系列全部基于jdk8

二、源碼分析

1.宏觀上分析List

代碼如下(示例):

public interface List<E> extends Collection<E>

可以看到list其實是一個接口,繼承與Collection.

2.方法匯總

1. 獲取list的大小,最大為Integer.MAX_VALUE個元素:

int size();

2. 判斷集合是否有元素

boolean isEmpty(); //判斷集合是否有元素

3. 判斷一個集合是否包含某一個元素,可能出現。ClassCastException和NullPointerException異常

boolean contains(Object o);

4. 返回一個迭代器

Iterator<E> iterator();

5. 轉換為一個對象數組

Object[] toArray();

6. 集合轉換為一個數組,元素類型根據泛型獲得

<T> T[] toArray(T[] a);

基本使用方法

import java.util.ArrayList; import java.util.Arrays; import java.util.List;public class Demo {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);Integer[] array = list.toArray(new Integer[0]);Arrays.stream(array).forEach(System.out::println);} }

這里的list.toArray(new Integer[0])和list.toArray()是一樣的

7. 向集合中添加一個元素

boolean add(E e)

8. 移除集合中的一個元素,移除的是第一個出現的元素

boolean remove(Object o);

9. 是否包含一個集合

boolean containsAll(Collection<?> c);

10. 向list集合中添加一個集合

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

11. 在指定位置插入集合

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

12. 移除指定的所有集合

boolean removeAll(Collection<?> c);

13. 移除指定的所有集合

boolean retainAll(Collection<?> c);

listA.retainAll(listB);保留 A中包含在集合B中的元素或者說移除A中沒有在B中的元素
15. 用函數接口的返回結果替代原list中的值.

default void replaceAll(UnaryOperator<E> operator) {Objects.requireNonNull(operator);final ListIterator<E> li = this.listIterator();while (li.hasNext()) {li.set(operator.apply(li.next()));}}

參考: replaceAll較為詳細的解釋

16. 排序方法

default void sort(Comparator<? super E> c) {Object[] a = this.toArray();Arrays.sort(a, (Comparator) c);ListIterator<E> i = this.listIterator();for (Object e : a) {i.next();i.set((E) e);}}

參考sort的使用方法

17. 移除list的所有元素

void clear();

18. 判斷兩個list是否相等

In other words, two lists are defined to be equal if they contain the same elements in the same order.

boolean equals(Object o);

19. 獲取list的hash值

int hashCode();

20. 獲取指定位置的元素

E get(int index);

21. 設置指定位置的元素的值

E set(int index, E element);

22. 在指定位置添加值

E set(int index, E element);

23. 移除指定位置的元素

E remove(int index);

24. 獲取指定元素的索引

int indexOf(Object o);

25. 獲取元素最后一次出現的索引值

int lastIndexOf(Object o);

26. 移除指定位置的元素

E remove(int index);

27. 返回一個迭代器,可以雙向遍歷

ListIterator<E> listIterator();

參考listIterator的使用方法
29. 返回一個迭代器,可以雙向遍歷

ListIterator<E> listIterator(int index);

30. 獲取list的一個指定范圍的子集

List<E> subList(int fromIndex, int toIndex);

31. 移除指定位置的元素

default Spliterator<E> spliterator() {return Spliterators.spliterator(this, Spliterator.ORDERED);}

參考spliterator的使用方法


三、ArrayList基本說明

Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface,this class provides methods to manipulate the size of the array that is used internally to store the list. (This class is roughly equivalent to Vector, except that it is c.)

  • ArrayList是list接口的一種實現,是一個可變大小的數組
  • 實現了list所有可選擇的操作,并且允許null元素的存在
  • 除了實現list的接口,這個類提供了操作數組大小的方法,在內部,可以利用這個數組來存儲list
  • ArrayList和Vector是類似的,但是ArrayList是非同步(unsynchronized)的, 其實也就是說ArrayList是非線程安全的,Vector是線程安全的。

The size, isEmpty, get, set iterator, and listIterator operations run in constant time. The add operation runs in amortized constant time,that is, adding n elements requires O(n) time. All of the other operations run in linear time (roughly speaking). The constant factor is low compared to that for the LinkedList implementation.

  • 方法size、isEmpty、get、set、iterator、listIterator都是常數時間
  • 方法add 運行是amortized constant time 分攤常數時間,也就是說,向數組中添加一個元素,時間復雜度為O(n)
  • 所有其他的操作算法時間復雜度都是O(1)
  • 與LinkedList相比較而言,list有更小的常數因子

Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.

  • 每一個ArrayList實例都有一個容量(capacity)
  • 容量具體指的是用來存放列表中元素的數組的大小
  • 隨著元素添加到ArrayList中,其容量是在不斷自動增加的
  • 增加策略的詳細信息并沒有特別指定,除了增加一個元素到ArrayList需要amortized constant time

An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.

  • 在添加大量的元素到arrayList之前,是可以使用ensureCapacity來增加ArrayList的容量大小的
  • 使用ensureCapacity可以減少需要重新分配內存的數量
  • Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently,and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list.

  • 需要注意的是ArrayList并不是線程安全的
  • 在并發(fā)的場景下,如果至少有一個線程來修改list的結構,那么我們需要外部保證必須同步(結構性修改可以是add、delete或者調整backing array數組大小中的任意一個操作;僅僅只是設置list中一個元素的值不是結構性的修改)
  • 典型的實現是,用synchronize修飾某些包裹encapsulate了整個list的對象

If no such object exists, the list should be “wrapped” using the {@link Collections#synchronizedList Collections.synchronizedList} method. This is best done at creation time, to prevent accidental unsynchronized access to the list:

List list = Collections.synchronizedList(new ArrayList(...));
  • (承接上文)如果沒有一個encapsulate了這個list的對象存在,那么應該使用Collections.synchronizedList,來防止對list意外的非同步訪問

The iterators returned by this class's {@link #iterator() iterator} and {@link #listIterator(int) listIterator} methods are fail-fast:if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own {@link ListIterator#remove() remove} or {@link ListIterator#add(Object) add} methods, the iterator will throw a {@link ConcurrentModificationException}. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

  • iterator()和istIterator(int)方法是快速失敗的,并拋出ConcurrentModificationException: 如果這個list在創(chuàng)建了iterator以后,在任意時刻被結構性修改,除了iterator自身調用remove和add方法
  • 因此在并發(fā)修改的場景下,這個迭代器快速失敗而不是在未來一個不確定性的時間冒險專斷或者不確定性行為

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw {@code ConcurrentModificationException} on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

  • 需要注意的是,一般說來,迭代器快速失敗的行為不能做出保證,因為它不可能在出現非同步并發(fā)修改時做出任何保證;基于最大努力,快速失敗的迭代器拋出ConcurrentModificationException異常
  • 因此,寫一個基于這個異常來做修正的代碼是不正確的;迭代器快速失敗的行為應該僅僅被用來檢測bug

# 四、ArrayList基本說明 public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • ArrayList繼承了抽象的list-AbstractList
  • 實現了List、RandomAccess、Cloneable和java.io.Serializable 4個接口
/*** Default initial capacity.*/private static final int DEFAULT_CAPACITY = 10;
  • 默認的初始化容器大小
/*** Shared empty array instance used for empty instances.*/private static final Object[] EMPTY_ELEMENTDATA = {};
  • 共享的空數組實例,用來當作空的實例,容器大小為0
/*** Shared empty array instance used for default sized empty instances. We* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when* first element is added.*/private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
  • 共享的空數組實例,用作默認大小的空實例,容器大小為10
  • 與上面的EMPTY_ELEMENTDATA的區(qū)別在于當第一個元素添加進去的時候,我們知道需要擴多大的容量
/*** 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 == DEFAULTCAPACITY_EMPTY_ELEMENTDATA* will be expanded to DEFAULT_CAPACITY when the first element is added.*/transient Object[] elementData; // non-private to simplify nested class access
  • 作為數組緩存,來存放ArrayList中的元素
  • ArrayList數組容量的大小時這個緩存數組的長度
  • 任何元素為DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空ArrayList,在第一次添加元素時,會擴張為DEFAULT_CAPACITY
/*** The size of the ArrayList (the number of elements it contains).** @serial*/private int size;
  • ArrayList中包含有元素的個數,注意與capacity的區(qū)別
/*** Constructs an empty list with the specified initial capacity.** @param initialCapacity the initial capacity of the list* @throws IllegalArgumentException if the specified initial capacity* is negative*/public ArrayList(int initialCapacity) {if (initialCapacity > 0) {this.elementData = new Object[initialCapacity];} else if (initialCapacity == 0) {this.elementData = EMPTY_ELEMENTDATA;} else {throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);}}
  • 構造器,構造一個指定大小的ArrayList
/*** Constructs an empty list with an initial capacity of ten.*/public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
  • 構造器,構造一個初始化容量大小為10的空ArrayList
/*** 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 ArrayList(Collection<? extends E> c) {elementData = c.toArray();if ((size = elementData.length) != 0) {// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);} else {// replace with empty array.this.elementData = EMPTY_ELEMENTDATA;}}
  • 通過一個集合來構造ArrayList
  • 構造器總結: 三個構造器,1)指定大小 2) 默認大小 3)利用集合
/*** Trims the capacity of this <tt>ArrayList</tt> instance to be the* list's current size. An application can use this operation to minimize* the storage of an <tt>ArrayList</tt> instance.*/public void trimToSize() {modCount++;if (size < elementData.length) {elementData = (size == 0)? EMPTY_ELEMENTDATA: Arrays.copyOf(elementData, size);}}
  • 這個函數是用來調整容器為當前列表所包含的元素的個數(size)
  • modCount,這個參數在講AbstractList內部類迭代器的時候,具體講解,主要是用來記錄list被結構性修改次數的
protected transient int modCount = 0;
  • 另外就是elementData,在上面也講過,它是用來作為一個緩存,來存放ArrayList中的元素的
/*** Increases the capacity of this <tt>ArrayList</tt> instance, if* necessary, to ensure that it can hold at least the number of elements* specified by the minimum capacity argument.** @param minCapacity the desired minimum capacity*/public void ensureCapacity(int minCapacity) {int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)// any size if not default element table? 0// larger than default for default empty table. It's already// supposed to be at default size.: DEFAULT_CAPACITY;if (minCapacity > minExpand) {ensureExplicitCapacity(minCapacity);}}
  • 用來增加當前ArrayList實例的容量大小
  • 確保能夠包含所指定的最小容量大小個數的元素
private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}

如果用來存放list的緩存數組的長度elementData.length小于所設定的最小容量minCapacity,那么就需要進行擴容

private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));} private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity; }
  • grow—擴容相關的代碼
/*** The maximum size of array to allocate.* Some VMs reserve some header words in an array.* Attempts to allocate larger arrays may result in* OutOfMemoryError: Requested array size exceeds VM limit*/private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;/*** Increases the capacity to ensure that it can hold at least the* number of elements specified by the minimum capacity argument.** @param minCapacity the desired minimum capacity*/private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;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);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}
  • MAX_ARRAY_SIZE 表述數組所允許分配的最大大小
  • grow函數用來擴容elementData數組,來確保可以存放所設置的minCapacity個元素
  • 這里擴容的原理:默認是比原來的大小新增0.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    (1) 如果擴容以后的newCapacity比需要的minCapacity小,則直接將newCapacity修改為minCapacity;
    (2)如果擴容以后的newCapacity比需要的minCapacity大,并且比最大值MAX_ARRAY_SIZE都還要大,則需要調用hugeCapacity,比較minCapacity和MAX_ARRAY_SIZE的大小,如果minCapacity大于MAX_ARRAY_SIZE,則將newCapacity設置為Integer.MAX_VALUE,否則設置為MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8),那么這里為什么是MAX.VALUE-8,則是因為數組作為一個對象,需要一定的內存存儲對象頭信息,對象頭信息最大占用內存不可超過8字節(jié)。參考
    (3) 然后將舊數組拷貝到新數組 參考
    elementData = Arrays.copyOf(elementData, newCapacity);
  • 關于這里為什么要調用ensureCapacity:當我們已經確定了要插入的對象的數目(并不是在創(chuàng)建ArrayList之前就知道有多少對象要插入的情況),就應該首先調用ensureCapacity來一次性擴容到可以容得下要插入的對象個數,這樣就避免的多次進行數組拷貝的情況,提高了效率,算是優(yōu)化吧;當然,我們在創(chuàng)建ArrayList之前就知道有多少對象要插入就使用有參構造。參考
/*** Returns the number of elements in this list.** @return the number of elements in this list*/public int size() {return size;}
  • 返回list中的元素個數
/*** Returns <tt>true</tt> if this list contains no elements.** @return <tt>true</tt> if this list contains no elements*/public boolean isEmpty() {return size == 0;}
  • 判斷l(xiāng)ist中是否有元素
/*** Returns <tt>true</tt> if this list contains the specified element.* More formally, returns <tt>true</tt> if and only if this list contains* at least one element <tt>e</tt> such that* <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.** @param o element whose presence in this list is to be tested* @return <tt>true</tt> if this list contains the specified element*/public boolean contains(Object o) {return indexOf(o) >= 0;}
  • 判斷l(xiāng)ist中是否包含某個對象,這里我們在判斷一個list元素為自定義對象的時候,需要重寫equal和hashCode方法,這里才能判斷是否包含某個對象,下面的demo會返回false
public class Demo {public static void main(String[] args) {List<Student> list = new ArrayList<>();Student A = new Student();A.setName("A");A.setAge(1);Student B = new Student();B.setName("B");B.setAge(2);list.add(A);list.add(B);Student C = new Student();C.setName("A");C.setAge(1);System.out.println(list.contains(C));} } /*** Returns the index of the first occurrence of the specified element* in this list, or -1 if this list does not contain the element.* More formally, returns the lowest index <tt>i</tt> such that* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,* or -1 if there is no such index.*/public int indexOf(Object o) {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;}return -1;}
  • 返回list中指定元素第一次出現時的位置,這個位置是在elementData這個數組中的位置,這里需要注意如果需要元素為null時的判斷
/*** Returns the index of the last occurrence of the specified element* in this list, or -1 if this list does not contain the element.* More formally, returns the highest index <tt>i</tt> such that* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,* or -1 if there is no such index.*/public int lastIndexOf(Object o) {if (o == null) {for (int i = size-1; i >= 0; i--)if (elementData[i]==null)return i;} else {for (int i = size-1; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;}
  • 返回list中指定元素最后一次出現時的位置,這里需要注意如果需要元素為null時的判斷
/*** Returns a shallow copy of this <tt>ArrayList</tt> instance. (The* elements themselves are not copied.)** @return a clone of this <tt>ArrayList</tt> instance*/public Object clone() {try {ArrayList<?> v = (ArrayList<?>) super.clone();v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError(e);}}
  • 返回對當前ArrayList實例的一個淺拷貝
/*** Returns an array containing all of the elements in this list* in proper sequence (from first to last element).** <p>The returned array will be "safe" in that no references to it are* maintained by this list. (In other words, this method must allocate* a new array). The caller is thus free to modify the returned array.** <p>This method acts as bridge between array-based and collection-based* APIs.** @return an array containing all of the elements in this list in* proper sequence*/public Object[] toArray() {return Arrays.copyOf(elementData, size);}
  • 將list轉化為數組,這里的數組是重新分配的一個空間,不會和原來的list元素存在任何引用關系,因此調用者可以自由的修改數組中的元素
/*** Returns an array containing all of the elements in this list in proper* sequence (from first to last element); the runtime type of the returned* array is that of the specified array. If the list fits in the* specified array, it is returned therein. Otherwise, a new array is* allocated with the runtime type of the specified array and the size of* this list.** <p>If the list fits in the specified array with room to spare* (i.e., the array has more elements than the list), the element in* the array immediately following the end of the collection is set to* <tt>null</tt>. (This is useful in determining the length of the* list <i>only</i> if the caller knows that the list does not contain* any null elements.)** @param a the array into which the elements of the list are to* be stored, if it is big enough; otherwise, a new array of the* same runtime type is allocated for this purpose.* @return an array containing the elements of the list* @throws ArrayStoreException if the runtime type of the specified array* is not a supertype of the runtime type of every element in* this list* @throws NullPointerException if the specified array is null*/@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {if (a.length < size)// Make a new array of a's runtime type, but my contents:return (T[]) Arrays.copyOf(elementData, size, a.getClass());System.arraycopy(elementData, 0, a, 0, size);if (a.length > size)a[size] = null;return a;}
  • 和上面的方法類似

下面開始講元素操作部分

@SuppressWarnings("unchecked")E elementData(int index) {return (E) elementData[index];}
  • 獲取指定位置index的元素
/*** Returns the element at the specified position in this list.** @param index index of the element to return* @return the element at the specified position in this list* @throws IndexOutOfBoundsException {@inheritDoc}*/public E get(int index) {rangeCheck(index);return elementData(index);}
  • 判斷元素是否在指定范圍內
/*** Checks if the given index is in range. If not, throws an appropriate* runtime exception. This method does *not* check if the index is* negative: It is always used immediately prior to an array access,* which throws an ArrayIndexOutOfBoundsException if index is negative.*/private void rangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}
  • 設置指定位置元素的值
/*** Replaces the element at the specified position in this list with* the specified element.** @param index index of the element to replace* @param element element to be stored at the specified position* @return the element previously at the specified position* @throws IndexOutOfBoundsException {@inheritDoc}*/public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue;}
  • 向list中添加一個元素
/*** Appends the specified element to the end of this list.** @param e element to be appended to this list* @return <tt>true</tt> (as specified by {@link Collection#add})*/public boolean add(E e) {ensureCapacityInternal(size + 1); // Increments modCount!!elementData[size++] = e;return true;}

(1) 添加元素是添加在內部數組的最后一個位置
(2) ensureCapacityInternal方法,add()方法的時候,會導致list發(fā)生結構性的修改,然后需要將modCount進行+1操作

private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity; }private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity); }
  • 在指定位置添加元素的值
/*** Inserts the specified element at the specified position in this* list. Shifts the element currently at that position (if any) and* any subsequent elements to the right (adds one to their indices).** @param index index at which the specified element is to be inserted* @param element element to be inserted* @throws IndexOutOfBoundsException {@inheritDoc}*/public void add(int index, E element) {rangeCheckForAdd(index);ensureCapacityInternal(size + 1); // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++;}

(1) 檢查所要添加的位置是否在合理范圍

/*** A version of rangeCheck used by add and addAll.*/private void rangeCheckForAdd(int index) {if (index > size || index < 0)throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}

(2) 調用ensureCapacityInternal(size + 1),增加修改計數器modCount和判斷是否需要擴容
(3) 移動數組元素,將源數組src的從起始位置srcPos開始的元素 復制到目標數組dest的從destPos開始長度為length的數組位置

public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);

(4) 然后將element賦值到指定位置elementData[index] = element;,最后修改整個list的大小size++

  • 移除指定位置的元素
/*** 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 workreturn oldValue;}

(1) rangeCheck(index); 先檢查需要移除的位置index是否合理
(2) 修改標志修改次數的參數值 modCount++
(3) 調整數組
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
(4) 將數組的最后一個位置置為null,方便gc;然后計算list的大小
(5) 返回所移除的元素

  • 移除指定元素
/*** Removes the first occurrence of the specified element from this list,* if it is present. If the list does not contain the element, it is* unchanged. More formally, removes the element with the lowest index* <tt>i</tt> such that* <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>* (if such an element exists). Returns <tt>true</tt> if this list* contained the specified element (or equivalently, if this list* changed as a result of the call).** @param o element to be removed from this list, if present* @return <tt>true</tt> if this list contained the specified element*/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 remove method that skips bounds checking and does not* return the value removed.*/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}

(1) 快速移除 fastRemove,省去了邊界檢查

  • 清空列表
/*** Removes all of the elements from this list. The list will* be empty after this call returns.*/public void clear() {modCount++;// clear to let GC do its workfor (int i = 0; i < size; i++)elementData[i] = null;size = 0;}
  • 添加集合到list的末尾,這個操作行為的結果是不確定的,如果要添加的集合在添加的過程中被修改
/*** 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. (This implies that the behavior of this call is* undefined if the specified collection is this list, and this* list is nonempty.)** @param c collection containing elements to be added to this list* @return <tt>true</tt> 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) {Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew); // Increments modCountSystem.arraycopy(a, 0, elementData, size, numNew);size += numNew;return numNew != 0;}
  • 插入集合到指定位置
/*** 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 <tt>true</tt> 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) {rangeCheckForAdd(index);Object[] a = c.toArray();int numNew = a.length;ensureCapacityInternal(size + numNew); // Increments modCountint 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;}
  • 移除指定范圍(左閉右開)的元素
/*** Removes from this list all of the elements whose index is between* {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.* Shifts any succeeding elements to the left (reduces their index).* This call shortens the list by {@code (toIndex - fromIndex)} elements.* (If {@code toIndex==fromIndex}, this operation has no effect.)** @throws IndexOutOfBoundsException if {@code fromIndex} or* {@code toIndex} is out of range* ({@code fromIndex < 0 ||* fromIndex >= size() ||* toIndex > size() ||* toIndex < fromIndex})*/protected void removeRange(int fromIndex, int toIndex) {modCount++;int numMoved = size - toIndex;System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);// clear to let GC do its workint newSize = size - (toIndex-fromIndex);for (int i = newSize; i < size; i++) {elementData[i] = null;}size = newSize;}
  • 將集合C中存在與list中的元素移除走
/*** Removes from this list all of its elements that are contained in the* specified collection.** @param c collection containing elements to be removed from this list* @return {@code true} if this list changed as a result of the call* @throws ClassCastException if the class of an element of this list* is incompatible with the specified collection* (<a href="Collection.html#optional-restrictions">optional</a>)* @throws NullPointerException if this list contains a null element and the* specified collection does not permit null elements* (<a href="Collection.html#optional-restrictions">optional</a>),* or if the specified collection is null* @see Collection#contains(Object)*/public boolean removeAll(Collection<?> c) {Objects.requireNonNull(c);return batchRemove(c, false);}private boolean batchRemove(Collection<?> c, boolean complement) {final Object[] elementData = this.elementData;int r = 0, w = 0;boolean modified = false;try {for (; r < size; r++)if (c.contains(elementData[r]) == complement)elementData[w++] = elementData[r];} finally {// Preserve behavioral compatibility with AbstractCollection,// even if c.contains() throws.if (r != size) {System.arraycopy(elementData, r,elementData, w,size - r);w += size - r;}if (w != size) {// clear to let GC do its workfor (int i = w; i < size; i++)elementData[i] = null;modCount += size - w;size = w;modified = true;}}return modified;}

(1) 如果c.contains(elementData[r]) == false,也就是說當前l(fā)ist中位于位置r的元素不在c中,那么就將r位置的元素放到當前l(fā)ist的對應位置為w的地方
(2) 上面的代碼 什么情況下會發(fā)生r != size的情況
(3) 另外這里的removeAll指的是把含在c中的元素從list中移除,而不是如果c中有一個元素不在list中,則不進行移除

  • 將集合C中存在與list中的元素保留下來
/*** Retains only the elements in this list that are contained in the* specified collection. In other words, removes from this list all* of its elements that are not contained in the specified collection.** @param c collection containing elements to be retained in this list* @return {@code true} if this list changed as a result of the call* @throws ClassCastException if the class of an element of this list* is incompatible with the specified collection* (<a href="Collection.html#optional-restrictions">optional</a>)* @throws NullPointerException if this list contains a null element and the* specified collection does not permit null elements* (<a href="Collection.html#optional-restrictions">optional</a>),* or if the specified collection is null* @see Collection#contains(Object)*/public boolean retainAll(Collection<?> c) {Objects.requireNonNull(c);return batchRemove(c, true);}
  • 序列化writeObject和反序列化readObject
/*** Save the state of the <tt>ArrayList</tt> instance to a stream (that* is, serialize it).** @serialData The length of the array backing the <tt>ArrayList</tt>* instance is emitted (int), followed by all of its elements* (each an <tt>Object</tt>) in the proper order.*/private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();// Write out size as capacity for behavioural compatibility with clone()s.writeInt(size);// Write out all elements in the proper order.for (int i=0; i<size; i++) {s.writeObject(elementData[i]);}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}}/*** Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,* deserialize it).*/private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {elementData = EMPTY_ELEMENTDATA;// Read in size, and any hidden stuffs.defaultReadObject();// Read in capacitys.readInt(); // ignoredif (size > 0) {// be like clone(), allocate array based upon size not capacityint capacity = calculateCapacity(elementData, size);SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity);ensureCapacityInternal(size);Object[] a = elementData;// Read in all elements in the proper order.for (int i=0; i<size; i++) {a[i] = s.readObject();}}}

迭代器------Itr

  • 根據當前的list返回一個迭代器Iterator
public Iterator<E> iterator() {return new Itr();}
  • list的內部類 迭代器Itr,是AbstractList的迭代器Itr的一個優(yōu)化版本
*** An optimized version of AbstractList.Itr*/private class Itr implements Iterator<E> {
  • 核心變量
    cursor—下一個元素的索引值
    lastRet—上一次返回元素的索引值
    expectedModCount —期望被修改的次數
int cursor; // index of next element to returnint lastRet = -1; // index of last element returned; -1 if no suchint expectedModCount = modCount;
  • 判斷迭代器是否還有更多的元素,下一個元素的索引cursor是否為list的大小size
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();cursor = i + 1;return (E) elementData[lastRet = i];}

(1) 檢查修改次數 期望修改的次數expectedModCount和實際修改次數是否相同

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

(2) 判斷下一個元素的索引是否超過了list的大小size
(3) 將當前l(fā)ist轉化為數組 Object[] elementData = ArrayList.this.elementData;
(4) 判斷下一個元素的索引值是否超過了當前數組elementData的長度,這里為什么需要做這個判斷
(5) 修改cursor的指,指向當前要返回元素的下一個元素的索引位置 cursor = i + 1;
(6) 返回當前索引值 return (E) elementData[lastRet = i];

  • 移除上一個返回的元素
public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}

移除上一個返回的元素以后:
(1) 下一個元素的索引值cursor為上一個返回元素的索引
(2) 上一個返回元素的索引為-1
(3) 修改期望修改值expectedModCount

  • 為list中剩余的每一個元素執(zhí)行指定的操作
@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 trafficcursor = i;lastRet = i - 1;checkForComodification();}

(1) 先判斷當前迭代器所指向下一個元素的索引是否超過了當前l(fā)ist的大小size
(2) 先判斷當前迭代器所指向下一個元素的索引是否超過了當前緩存數組的長度length
(3) 然后為剩下的每一個元素都執(zhí)行consumer.accept((E) elementData[i++]);
(4) 更新參數 cursor = I; lastRet = i - 1;

內部類 ListItr

/*** An optimized version of AbstractList.ListItr*/private class ListItr extends Itr implements ListIterator<E> { /*** Returns a list iterator over the elements in this list (in proper* sequence), starting at the specified position in the list.* The specified index indicates the first element that would be* returned by an initial call to {@link ListIterator#next next}.* An initial call to {@link ListIterator#previous previous} would* return the element with the specified index minus one.** <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.** @throws IndexOutOfBoundsException {@inheritDoc}*/public ListIterator<E> listIterator(int index) {if (index < 0 || index > size)throw new IndexOutOfBoundsException("Index: "+index);return new ListItr(index);}
  • 返回一個從指定位置開始的list iterator
  • 指定位置表明 第一個元素將是初次調用next方法返回的
  • 初次調用previous方法會返回指定位置-1處的元素
/*** Returns a list iterator over the elements in this list (in proper* sequence).** <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.** @see #listIterator(int)*/public ListIterator<E> listIterator() {return new ListItr(0);}
  • ListItr 繼承Itr, 實現接口ListIterator

接口ListIterator

An iterator for lists that allows the programmer to traverse the list in either direction, modify the list during iteration, and obtain the iterator’s current position in the list. A {@code ListIterator} has no current element; its cursor position always lies between the element that would be returned by a call to {@code previous()} and the element that would be returned by a call to {@code next()}.

  • ListIterator是一個針對lists的迭代器,這個迭代器允許程序以不同的方向去遍歷list、在迭代的過程中修改list和獲取迭代器在list的當前位置
  • ListIterator 沒有當前的元素
  • ListIterator的cursor position總是處于調用者調用previous()所返回的值和調用者調用next()所返回的值之間

An iterator for a list of length {@code n} has {@code n+1} possible cursor positions, as illustrated by the carets ({@code ^}) below:

Element(0) Element(1) Element(2) … Element(n-1)
cursor positions: ^ ^ ^ ^ ^

  • 一個作為長度為n的list的迭代器有n+1個可能的cusor位置

Note that the {@link #remove} and {@link #set(Object)} methods are not defined in terms of the cursor position; they are defined to operate on the last element returned by a call to {@link #next} or {@link #previous()}.

  • 注意remove和set方法并不是使用cursor position 而是使用 調用next或者previous方法返回的上一個元素lastRet
  • ListItr構造器
ListItr(int index) {super();cursor = index;}
  • 利用ListItr反向遍歷list的時候,判斷是否有上一個元素
public boolean hasPrevious() {return cursor != 0; }
  • 針對一系列調用next方法時,返回的元素的索引值
public int nextIndex() {return cursor;}
  • 針對一系列調用previous方法時,返回的元素的索引值
public int previousIndex() {return cursor - 1;} }
  • 獲取cursor所在位置的前面一個位置的值
public E previous() {checkForComodification();int i = cursor - 1;if (i < 0)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i;return (E) elementData[lastRet = i];}
  • 設置上一個返回值的位置的值為元素e
public void set(E e) {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.set(lastRet, e);} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}
  • 在下一個元素的索引位置處設置值e
public void add(E e) {checkForComodification();try {int i = cursor;ArrayList.this.add(i, e);cursor = i + 1;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}} /*** Returns a view of the portion of this list between the specified* {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If* {@code fromIndex} and {@code toIndex} are equal, the returned list is* empty.) The returned list is backed by this list, so non-structural* changes in the returned list are reflected in this list, and vice-versa.* The returned list supports all of the optional list operations.** <p>This method eliminates the need for explicit range operations (of* the sort that commonly exist for arrays). Any operation that expects* a list can be used as a range operation by passing a subList view* instead of a whole list. For example, the following idiom* removes a range of elements from a list:* <pre>* list.subList(from, to).clear();* </pre>* Similar idioms may be constructed for {@link #indexOf(Object)} and* {@link #lastIndexOf(Object)}, and all of the algorithms in the* {@link Collections} class can be applied to a subList.** <p>The semantics of the list returned by this method become undefined if* the backing list (i.e., this list) is <i>structurally modified</i> in* any way other than via the returned list. (Structural modifications are* those that change the size of this list, or otherwise perturb it in such* a fashion that iterations in progress may yield incorrect results.)** @throws IndexOutOfBoundsException {@inheritDoc}* @throws IllegalArgumentException {@inheritDoc}*/public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, 0, fromIndex, toIndex);}static void subListRangeCheck(int fromIndex, int toIndex, int size) {if (fromIndex < 0)throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);if (toIndex > size)throw new IndexOutOfBoundsException("toIndex = " + toIndex);if (fromIndex > toIndex)throw new IllegalArgumentException("fromIndex(" + fromIndex +") > toIndex(" + toIndex + ")");}
  • subList方法將返回當前l(fā)ist在指定范圍(左閉右開區(qū)間范圍)的list元素
  • 如果區(qū)間范圍邊界值fromIndex和toIndex值相同,那么返回的list為空
  • 這個返回的list是和原來的list是有關系的,返回list的結構性改變會引起原list的結構性改變,反過來也一樣。
  • 返回來的這個list是SubList支持list的所有操作,因為繼承了AbstractList, 重寫了對應的方法

內部類 SubList

private class SubList extends AbstractList<E> implements RandomAccess
  • SubList繼承了AbstractList,實現了 RandomAccess

  • RandomAccess 表示list接口的實現類支持快速隨機訪問

Marker interface used by List implementations to indicate that they support fast (generally constant time) random access. The primary purpose of this interface is to allow generic algorithms to alter their behavior to provide good performance when applied to either random or sequential access lists.

  • 內部變量
private final AbstractList<E> parent;private final int parentOffset;private final int offset;int size;
  • 構造器
SubList(AbstractList<E> parent,int offset, int fromIndex, int toIndex) {this.parent = parent;this.parentOffset = fromIndex;this.offset = offset + fromIndex;this.size = toIndex - fromIndex;this.modCount = ArrayList.this.modCount;}
  • 設置指定位置的元素為e
public E set(int index, E e) {rangeCheck(index);checkForComodification();E oldValue = ArrayList.this.elementData(offset + index);ArrayList.this.elementData[offset + index] = e;return oldValue;}

(1)與ArrayList的方法進行比較,多了modCount的比較和設置對應的值時增加了偏移量

public E set(int index, E element) {rangeCheck(index);E oldValue = elementData(index);elementData[index] = element;return oldValue;}
  • 獲取指定位置的元素值
public E get(int index) {rangeCheck(index);checkForComodification();return ArrayList.this.elementData(offset + index);}
  • 獲取大小
public int size() {checkForComodification();return this.size;}
  • 在指定位置添加元素
public void add(int index, E e) {rangeCheckForAdd(index);checkForComodification();parent.add(parentOffset + index, e);this.modCount = parent.modCount;this.size++;}
  • 移除指定位置的元素
public E remove(int index) {rangeCheck(index);checkForComodification();E result = parent.remove(parentOffset + index);this.modCount = parent.modCount;this.size--;return result;}
  • 移除指定范圍的元素
protected void removeRange(int fromIndex, int toIndex) {checkForComodification();parent.removeRange(parentOffset + fromIndex,parentOffset + toIndex);this.modCount = parent.modCount;this.size -= toIndex - fromIndex;}
  • 添加集合
public boolean addAll(Collection<? extends E> c) {return addAll(this.size, c);}
  • 在指定位置添加集合
public boolean addAll(int index, Collection<? extends E> c) {rangeCheckForAdd(index);int cSize = c.size();if (cSize==0)return false;checkForComodification();parent.addAll(parentOffset + index, c);this.modCount = parent.modCount;this.size += cSize;return true;}
  • 返回迭代器
public Iterator<E> iterator() {return listIterator();}
  • 返回可以前后遍歷list的迭代器,里面包含了ListItr相應的方法,比如 next,previous
public ListIterator<E> listIterator(final int index) {checkForComodification();rangeCheckForAdd(index);final int offset = this.offset;return new ListIterator<E>() {int cursor = index;int lastRet = -1;int expectedModCount = ArrayList.this.modCount;public boolean hasNext() {return cursor != SubList.this.size;}@SuppressWarnings("unchecked")public E next() {checkForComodification();int i = cursor;if (i >= SubList.this.size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[offset + (lastRet = i)];}public boolean hasPrevious() {return cursor != 0;}@SuppressWarnings("unchecked")public E previous() {checkForComodification();int i = cursor - 1;if (i < 0)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length)throw new ConcurrentModificationException();cursor = i;return (E) elementData[offset + (lastRet = i)];}@SuppressWarnings("unchecked")public void forEachRemaining(Consumer<? super E> consumer) {Objects.requireNonNull(consumer);final int size = SubList.this.size;int i = cursor;if (i >= size) {return;}final Object[] elementData = ArrayList.this.elementData;if (offset + i >= elementData.length) {throw new ConcurrentModificationException();}while (i != size && modCount == expectedModCount) {consumer.accept((E) elementData[offset + (i++)]);}// update once at end of iteration to reduce heap write trafficlastRet = cursor = i;checkForComodification();}public int nextIndex() {return cursor;}public int previousIndex() {return cursor - 1;}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {SubList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = ArrayList.this.modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}public void set(E e) {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.set(offset + lastRet, e);} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}public void add(E e) {checkForComodification();try {int i = cursor;SubList.this.add(i, e);cursor = i + 1;lastRet = -1;expectedModCount = ArrayList.this.modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}final void checkForComodification() {if (expectedModCount != ArrayList.this.modCount)throw new ConcurrentModificationException();}};}
  • SubList類也包含了sublist方法
public List<E> subList(int fromIndex, int toIndex) {subListRangeCheck(fromIndex, toIndex, size);return new SubList(this, offset, fromIndex, toIndex);}
  • spliterator()方法,這里涉及到內部類ArrayListSpliterator,后面會詳細講這個類的作用
public Spliterator<E> spliterator() {checkForComodification();return new ArrayListSpliterator<E>(ArrayList.this, offset,offset + this.size, this.modCount);}

至此,SubList的所有方法就講完了,現在來繼續(xù)講解ArrayList的剩余方法

  • 為list中每一個元素執(zhí)行相同的操作
@Overridepublic void forEach(Consumer<? super E> action) {Objects.requireNonNull(action);final int expectedModCount = modCount;@SuppressWarnings("unchecked")final E[] elementData = (E[]) this.elementData;final int size = this.size;for (int i=0; modCount == expectedModCount && i < size; i++) {action.accept(elementData[i]);}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}}
  • List item
/*** Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>* and <em>fail-fast</em> {@link Spliterator} over the elements in this* list.** <p>The {@code Spliterator} reports {@link Spliterator#SIZED},* {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.* Overriding implementations should document the reporting of additional* characteristic values.** @return a {@code Spliterator} over the elements in this list* @since 1.8*/@Overridepublic Spliterator<E> spliterator() {return new ArrayListSpliterator<>(this, 0, -1, 0);}

內部類 ArrayListSpliterator

/** Index-based split-by-two, lazily initialized Spliterator */static final class ArrayListSpliterator<E> implements Spliterator<E>
  • 基于索引
  • 一分為二
  • 延遲初始化的可拆分的迭代器 參考
  • 該對象可以使用trySplit進行迭代器拆分,每次拆分后的迭代器接近上一次的二分之一。
    這是官方對于大數據量數組多線程遍歷加工的一種趨勢性指引。參考

If ArrayLists were immutable, or structurally immutable (no adds, removes, etc), we could implement their spliterators with Arrays.spliterator. Instead we detect as much interference during traversal as practical without sacrificing much performance. We rely primarily on modCounts. These are not guaranteed to detect concurrency violations, and are sometimes overly conservative about within-thread interference, but detect enough problems to be worthwhile in practice. To carry this out, we (1) lazily initialize fence and expectedModCount until the latest point that we need to commit to the state we are checking against; thus improving precision. (This doesn’t apply to SubLists, that create spliterators with current non-lazy values). (2) We perform only a single ConcurrentModificationException check at the end of forEach (the most performance-sensitive method). When using forEach (as opposed to iterators), we can normally only detect interference after actions, not before. Further CME-triggering checks apply to all other possible violations of assumptions for example null or too-small elementData array given its size(), that could only have occurred due to interference. This allows the inner loop of forEach to run without any further checks, and simplifies lambda-resolution. While this does entail a number of checks, note that in the common case of list.stream().forEach(a), no checks or other computation occur anywhere other than inside forEach itself. The other less-often-used methods cannot take advantage of most of these streamlinings.

  • 局部變量
private final ArrayList<E> list;private int index; // current index, modified on advance/splitprivate int fence; // -1 until used; then one past last indexprivate int expectedModCount; // initialized when fence set

(1) index 當前索引,在遍歷或者拆分的時候被修改
(2) fence 沒使用的時候默認為-1,最后指向最后一個索引

  • 構造器
/** Create new spliterator covering the given range */ArrayListSpliterator(ArrayList<E> list, int origin, int fence,int expectedModCount) {this.list = list; // OK if null unless traversedthis.index = origin;this.fence = fence;this.expectedModCount = expectedModCount;}
  • 初始化變量fence,在第一次使用的初始化fence到list的大小
private int getFence() { // initialize fence to size on first useint hi; // (a specialized variant appears in method forEach)ArrayList<E> lst;if ((hi = fence) < 0) {if ((lst = list) == null)hi = fence = 0;else {expectedModCount = lst.modCount;hi = fence = lst.size;}}return hi;}
  • 拆分ArrayList
public ArrayListSpliterator<E> trySplit() {int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;return (lo >= mid) ? null : // divide range in half unless too smallnew ArrayListSpliterator<E>(list, lo, index = mid,expectedModCount);}
  • 當前元素執(zhí)行action
public boolean tryAdvance(Consumer<? super E> action) {if (action == null)throw new NullPointerException();int hi = getFence(), i = index;if (i < hi) {index = i + 1;@SuppressWarnings("unchecked") E e = (E)list.elementData[i];action.accept(e);if (list.modCount != expectedModCount)throw new ConcurrentModificationException();return true;}return false;}
  • 剩下的元素執(zhí)行相同的操作
public void forEachRemaining(Consumer<? super E> action) {int i, hi, mc; // hoist accesses and checks from loopArrayList<E> lst; Object[] a;if (action == null)throw new NullPointerException();if ((lst = list) != null && (a = lst.elementData) != null) {if ((hi = fence) < 0) {mc = lst.modCount;hi = lst.size;}elsemc = expectedModCount;if ((i = index) >= 0 && (index = hi) <= a.length) {for (; i < hi; ++i) {@SuppressWarnings("unchecked") E e = (E) a[i];action.accept(e);}if (lst.modCount == mc)return;}}throw new ConcurrentModificationException();}
  • 估計大小
public long estimateSize() {return (long) (getFence() - index);}
  • 返回這個拆分迭代器和里面元素的特征
public int characteristics() {return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;}
  • 按照一定規(guī)則過濾集合中的元素
@Overridepublic boolean removeIf(Predicate<? super E> filter) {Objects.requireNonNull(filter);// figure out which elements are to be removed// any exception thrown from the filter predicate at this stage// will leave the collection unmodifiedint removeCount = 0;final BitSet removeSet = new BitSet(size);final int expectedModCount = modCount;final int size = this.size;for (int i=0; modCount == expectedModCount && i < size; i++) {@SuppressWarnings("unchecked")final E element = (E) elementData[i];if (filter.test(element)) {removeSet.set(i);removeCount++;}}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}// shift surviving elements left over the spaces left by removed elementsfinal boolean anyToRemove = removeCount > 0;if (anyToRemove) {final int newSize = size - removeCount;for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {i = removeSet.nextClearBit(i);elementData[j] = elementData[i];}for (int k=newSize; k < size; k++) {elementData[k] = null; // Let gc do its work}this.size = newSize;if (modCount != expectedModCount) {throw new ConcurrentModificationException();}modCount++;}return anyToRemove;}
  • 用于將給定的操作內容替換掉數組中每一個元素。
@Override@SuppressWarnings("unchecked")public void replaceAll(UnaryOperator<E> operator) {Objects.requireNonNull(operator);final int expectedModCount = modCount;final int size = this.size;for (int i=0; modCount == expectedModCount && i < size; i++) {elementData[i] = operator.apply((E) elementData[i]);}if (modCount != expectedModCount) {throw new ConcurrentModificationException();}modCount++;}
  • List 排序
@Override@SuppressWarnings("unchecked")public void sort(Comparator<? super E> c) {final int expectedModCount = modCount;Arrays.sort((E[]) elementData, 0, size, c);if (modCount != expectedModCount) {throw new ConcurrentModificationException();}modCount++;}

ArrayList的整體框架 參考

總結

總結

以上是生活随笔為你收集整理的Java集合Collection源码系列-ArrayList源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

日韩国产精品一区 | 国产精品淫片 | 日本久久中文字幕 | 99精品视频在线观看 | 精品久久美女 | 色五丁香 | 国产黄色成人av | 久久久久久久久久久久久9999 | 999久久精品 | 免费黄色av| 久久精品免费看 | 五月婷婷在线观看视频 | 综合网天天射 | 在线免费观看黄网站 | 色在线网| 国产高清视频在线播放 | 一本一本久久a久久精品牛牛影视 | 毛片网在线观看 | 国产成人久 | 三上悠亚在线免费 | 丁香花中文在线免费观看 | 国产无遮挡猛进猛出免费软件 | 96亚洲精品久久久蜜桃 | 亚洲婷婷在线 | 日韩一区二区三 | 国产精品原创视频 | 日日干 天天干 | 国产精品一码二码三码在线 | 久久综合导航 | 天天干亚洲 | 国产免费视频在线 | 人人精品久久 | 日日成人网| 91九色成人蝌蚪首页 | 99人成在线观看视频 | 天天操网站 | 久久成熟 | 国产精品初高中精品久久 | av最新资源 | 国偷自产中文字幕亚洲手机在线 | 黄色av一级 | 国产在线a视频 | 久久精品99国产精品 | 欧美国产日韩一区二区三区 | 午夜电影 电影 | 97在线超碰| 欧美成人一区二区 | 欧美另类重口 | 精品一区二区影视 | 久久一区精品 | 狠狠色伊人亚洲综合网站野外 | 亚洲精品视频免费 | 天天干天天操天天搞 | 1000部18岁以下禁看视频 | 看av免费网站| 97精品久久人人爽人人爽 | 亚洲综合成人婷婷小说 | 毛片区 | 欧美一区成人 | 少妇av片 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 国产精品久久嫩一区二区免费 | 国产精品毛片久久久久久久 | 午夜精品久久久久久久久久久 | 亚洲男女精品 | 日韩欧美视频在线免费观看 | 国产系列在线观看 | www视频免费在线观看 | 国产一区视频导航 | 午夜丁香视频在线观看 | 91九色视频在线观看 | 国产91大片 | 四虎永久免费 | 午夜.dj高清免费观看视频 | 十八岁以下禁止观看的1000个网站 | 91视频大全 | 五月婷丁香 | 久草免费在线观看视频 | 综合久久久| 精品久久一二三区 | 天天操天天添天天吹 | 激情五月六月婷婷 | 精品国产一区二区三区在线观看 | 天天激情综合 | 四虎在线免费观看视频 | 中文字幕在线播放视频 | 91麻豆免费视频 | 国产一区欧美在线 | 欧美成人区 | 超碰97成人 | 国产成年免费视频 | 精品福利在线观看 | 久久国语露脸国产精品电影 | 中文字幕成人一区 | 日韩在线播放av | 在线观看视频免费播放 | 欧美色黄 | 午夜视频久久久 | 久久久久久久久国产 | 欧美一二三四在线 | 日韩免费大片 | 亚洲最新精品 | 91观看视频 | www色婷婷com| 日韩欧美第二页 | 一区二区欧美日韩 | 激情中文字幕 | 丁香婷婷综合激情五月色 | 国产精品高清av | 婷婷综合 | 国产精品久久久久三级 | 亚洲精品视频偷拍 | 狠狠操狠狠插 | 超碰日韩在线 | 成人免费网站在线观看 | 五月天亚洲综合小说网 | 激情视频一区二区三区 | 国产五月色婷婷六月丁香视频 | 午夜视频在线观看一区二区三区 | 91麻豆高清视频 | 久久久黄色av| 黄色av免费电影 | www.天天色| 色综合久久久久综合体桃花网 | 黄色在线免费观看网站 | 免费在线黄 | 国色天香av | 日本不卡久久 | 在线观看免费色 | 亚洲爽爽网 | 四虎精品成人免费网站 | 色婷婷综合五月 | 人人爽网站| 天天射天天操天天干 | 国产小视频在线免费观看 | 亚洲精品欧美专区 | 国产原创av在线 | 中文字幕免费在线 | 国内精品久久影院 | 精品在线播放 | 国产第一页福利影院 | 中文字幕成人在线观看 | 中文在线亚洲 | 天天色天天射综合网 | 日韩最新av在线 | 在线观看国产区 | 五月激情av | 日韩黄色在线电影 | 久爱精品在线 | av黄色大片 | 亚洲aaa级 | av免费电影网站 | 91香蕉视频在线下载 | av免费在线看网站 | 午夜精品一区二区三区可下载 | 三级av片 | 丁香花在线观看免费完整版视频 | 亚洲综合欧美日韩狠狠色 | 超碰人人在线观看 | 日韩视频a| 成年人免费在线观看网站 | 日日摸日日 | 欧美日韩一区二区三区在线免费观看 | 99久热| 国产精品久久三 | 一区二区日韩av | 婷婷色综合网 | 麻豆一级视频 | 国产理论一区二区三区 | 黄色在线观看污 | 国产伦理精品一区二区 | 国产亚洲精品久久久久久久久久 | 久久精品免视看 | 日韩在线视频免费播放 | 欧美a√大片| 一区二区av | 91人人澡| 免费成人黄色片 | 国产三级午夜理伦三级 | 亚洲国产精品电影在线观看 | 一区二区三区在线视频观看58 | 亚洲精品国 | 国产精品毛片一区二区在线 | 蜜桃视频在线视频 | 青春草免费在线视频 | 日韩三级视频 | 日韩a在线| 国产激情久久久 | 激情黄色一级片 | 国产精品免费不卡 | 亚洲五月综合 | 欧美日韩精品在线播放 | 高潮毛片无遮挡高清免费 | 国产在线播放一区二区 | 日韩精品网址 | 国产96在线| 97超碰成人在线 | 国产 欧美 日产久久 | 免费成人看片 | 欧美日韩精品综合 | 婷婷综合成人 | a亚洲视频 | 美女黄频视频大全 | 91桃色国产在线播放 | 免费看污黄网站 | 亚洲国产精品激情在线观看 | 日韩av片免费在线观看 | 99久久婷婷国产一区二区三区 | 国产视频一区二区在线观看 | 月丁香婷婷 | 亚洲japanese制服美女 | 久久激情小说 | 一级黄网 | 久久99视频精品 | 97超碰人人澡人人 | 午夜精品99久久免费 | 国产精品成人av在线 | 国产男男gay做爰 | 国产精品一区二区久久国产 | 7777精品伊人久久久大香线蕉 | 黄色片免费在线 | 日av免费| 欧美天堂久久 | 久久人人爽av | 色多多污污在线观看 | 国产 日韩 在线 亚洲 字幕 中文 | 中文字幕在线观看不卡 | 欧美精品免费在线 | 999国产在线| av中文字幕在线播放 | 久久精品中文 | 久久久久久久久久免费视频 | 亚洲精品美女久久久久网站 | 午夜在线观看一区 | 日韩在线中文字幕 | 国产精品一区二区在线免费观看 | av短片在线观看 | 亚洲精品国产精品久久99 | 欧美国产日韩一区 | 色吧av色av| 亚洲精品国产电影 | 亚洲涩涩涩涩涩涩 | 免费网站黄 | 欧美成人999| 欧美资源在线观看 | 国产精品麻豆91 | 91在线中字| 久久大片网站 | 亚洲午夜在线视频 | 国产一级片观看 | 天堂av一区二区 | 成人午夜精品福利免费 | 98超碰在线观看 | 91久久爱热色涩涩 | 婷婷激情综合五月天 | 国产在线视频一区二区 | 亚洲精品久久久久久久不卡四虎 | 玖玖视频免费在线 | 亚州av一区 | 天天射天天操天天干 | 国产大片黄色 | 狠狠ri| 久久久久女人精品毛片 | 一区二区伦理 | 国产在线观看,日本 | 国产成人精品一区二区三区在线 | 91九色视频 | h视频在线看 | 免费黄色网止 | 国产精品视频免费在线观看 | 丁香婷婷综合五月 | 91亚洲国产 | 国产精品视频你懂的 | 欧美日韩亚洲在线 | 国产香蕉视频 | 久在线观看视频 | 久久久av免费 | 日本黄色免费看 | 天天干,天天插 | 中文av网站 | 极品中文字幕 | 国产日产精品久久久久快鸭 | 亚洲精品视频在线观看免费视频 | 国产成人精品一区二区三区在线观看 | 国产一区二区免费在线观看 | 又黄又爽的免费高潮视频 | 香蕉视频在线免费 | 91视频久久久久久 | 日韩视频中文字幕在线观看 | 夜夜操天天干 | 在线 日韩 av | 国产一区二区在线免费播放 | 国产高清第一页 | 久草视频观看 | 日本中文字幕在线 | 国产精品av免费在线观看 | 丝袜美女在线 | 色婷婷啪啪免费在线电影观看 | 国产精品手机播放 | 五月婷婷综合网 | 日韩在线视频网 | 夜夜骑日日操 | 丁香婷婷综合色啪 | 免费av网址在线观看 | 911在线 | 91chinesexxx| 免费精品在线视频 | 丁香高清视频在线看看 | 一级α片| 懂色av懂色av粉嫩av分享吧 | 日本中文字幕在线一区 | 国产一区免费在线 | 亚洲精品午夜aaa久久久 | 日日操天天操夜夜操 | 国产一区二区网址 | 国产 日韩 在线 亚洲 字幕 中文 | 国产精品二区在线 | 91精品国产乱码在线观看 | 亚洲一级片在线看 | 中文字幕在线视频网站 | 四虎在线观看 | 麻豆成人在线观看 | 99久久99视频只有精品 | 国产又粗又猛又黄又爽的视频 | 午夜精品区 | 久久久国产精品视频 | 干 操 插 | 粉嫩av一区二区三区免费 | 国产这里只有精品 | 黄色免费看片网站 | 人人玩人人爽 | 岛国av在线| 亚洲尺码电影av久久 | 国产亚洲午夜高清国产拍精品 | 天天色视频| 欧美日韩二区三区 | 视频91在线 | 国产专区视频 | 少妇bbb搡bbbb搡bbbb | 麻豆视频免费入口 | 精品国产综合区久久久久久 | 日韩精品久久久久久中文字幕8 | 一区电影| 欧美性猛片 | 久久国产成人午夜av影院宅 | 91亚瑟视频 | 狠狠综合| 国产色一区 | 激情网第四色 | 天天射天天搞 | 综合久久久久久 | 日本久久久久 | 毛片二区 | 久久精品久久久久久久 | 久久综合亚洲鲁鲁五月久久 | 日韩精选在线 | 中文字幕视频一区 | 久久嗨 | www天天干com | 永久免费视频国产 | 久久69av| 中文字幕久久亚洲 | 久久亚洲福利视频 | 欧美粗又大| 91pony九色丨交换 | 色偷偷av男人天堂 | 99热这里只有精品国产首页 | 最新日韩在线观看 | 黄色片免费在线 | 夜夜夜草 | 特级a老妇做爰全过程 | 久久国产精品免费看 | 狠狠插天天干 | 国产人成一区二区三区影院 | 精品国模一区二区 | 一区二区精品在线 | 黄网av在线 | 久久免费99 | 久草综合视频 | 香蕉影院在线播放 | 日日夜夜综合网 | 中文字幕精品视频 | 色射色| 久草视频免费 | 伊人久久国产精品 | 久久综合久久伊人 | 成人免费xxxxxx视频 | 国产不卡网站 | 精品国产一区二区久久 | 免费a现在观看 | 狠狠狠色丁香婷婷综合久久五月 | www.色的| 日韩精品视频在线观看免费 | 九九视频热 | 亚洲少妇影院 | www.天堂av| 一级片在线 | 在线观看第一页 | 美女国内精品自产拍在线播放 | 欧美一区二区日韩一区二区 | 国产精品高清在线观看 | 青草草在线视频 | 国产精品激情在线观看 | 免费的黄色av | 天天草天天爽 | 欧美性生活大片 | 中文国产成人精品久久一 | 美女黄频视频大全 | 天天操狠狠操夜夜操 | 久久在线视频精品 | 精品99视频 | 麻豆影视网站 | 色综合婷婷 | 在线激情av电影 | 久久久久久久久亚洲精品 | 天堂av在线网 | 亚洲成a人片在线www | 亚洲精品美女免费 | 超碰人人在线观看 | 日韩欧美在线高清 | 亚洲无毛专区 | 亚洲 中文 欧美 日韩vr 在线 | 99精品视频免费在线观看 | 91成人黄色| 亚洲精品在线观看的 | 久久久精品国产一区二区电影四季 | 久久9999久久免费精品国产 | 超碰免费成人 | 在线一级片 | 江苏妇搡bbbb搡bbbb | 久草在线视频免赞 | 久久影院中文字幕 | 久久久久久亚洲精品 | 日批在线观看 | 亚洲精品久久久久中文字幕二区 | 欧美一二区在线 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 337p日本大胆噜噜噜噜 | 国产黄色在线观看 | 久久久久五月天 | 欧美日高清视频 | 久久午夜电影院 | 日韩中文字幕在线 | 欧美视频在线二区 | 国产特级毛片aaaaaaa高清 | 久操97 | 亚洲片在线观看 | 亚洲 欧美 日韩 综合 | av在线影视| 97超碰伊人 | 国产无遮挡又黄又爽在线观看 | 久久综合狠狠综合久久激情 | 97在线看片| 操操操日日日干干干 | 日韩一区二区三区视频在线 | 中文字幕国产在线 | 伊人天天操 | 成人app在线免费观看 | 日本爱爱片 | 81国产精品久久久久久久久久 | 国产精品久久中文字幕 | 国产精品久久久久久999 | 91九色视频观看 | 欧美日韩激情视频8区 | www.久久爱.cn | 7777xxxx| 国产精品门事件 | 玖玖在线看 | 久久久久久久网 | 在线观看免费91 | 一区二区三区精品在线视频 | 国产精品综合久久久久久 | 国产高清精品在线观看 | 亚洲一区欧美精品 | 国产九九精品视频 | 麻豆一区在线观看 | 国产精品99久久久精品免费观看 | 91视频高清免费 | 99看视频在线观看 | 亚洲一区二区三区在线看 | av片子在线观看 | 中文一二区 | 中文字幕一区二区三区四区 | 伊人天天综合 | 日韩欧美在线第一页 | 国产香蕉av | 日日操日日插 | 日韩高清免费在线观看 | 亚洲禁18久人片 | 免费看黄色毛片 | 成人久久毛片 | av电影av在线 | 日韩免费视频一区二区 | 婷婷六月色| 黄色特级片 | 操夜夜操 | 九九热免费精品视频 | 国产精品乱码久久久 | 欧美黑吊大战白妞欧美 | 美女网站视频久久 | 久久久久久网址 | 一级黄色视屏 | 亚洲一区二区精品 | 99精品久久久久久久 | 女人18片毛片90分钟 | 天天做天天射 | 高清中文字幕av | 天天射网站| 亚洲一级二级三级 | 国产99视频在线观看 | 狠狠躁天天躁 | 黄a在线看| 国产精品久久久久四虎 | 丁香花五月 | 免费黄色av. | 亚洲另类视频在线观看 | av福利第一导航 | 国产精品乱码在线 | 久久福利综合 | 亚洲视频999 | 国产精品麻豆免费版 | 国产精品自产拍在线观看网站 | 91亚洲网 | 中文字幕网站视频在线 | 国产精品99久久久久久久久久久久 | 在线视频精品 | 丁香六月国产 | 国产视频一| 亚洲第一久久久 | av看片网址| 欧美激情视频久久 | 欧美日韩精品免费观看视频 | 免费观看黄色12片一级视频 | 欧美日韩网址 | 国产在线观看国语版免费 | 精品久久久久国产免费第一页 | 91色影院| 日韩中文在线观看 | 激情动态 | 日韩电影精品一区 | 久爱精品在线 | 国产中文字幕免费 | 久草久热| 欧美一级大片在线观看 | 国产综合在线视频 | av网站免费线看精品 | 国产视频亚洲精品 | 亚洲天堂在线观看完整版 | 日韩精品视| 91av视频在线播放 | 六月久久婷婷 | av福利第一导航 | 日韩一区二区久久 | 在线免费观看视频一区二区三区 | 欧美日韩不卡在线视频 | 日本动漫做毛片一区二区 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 欧美一级在线看 | 毛片.com| 中日韩免费视频 | 丁香久久激情 | 91中文字幕视频 | 国产自制av | 精品亚洲欧美一区 | 亚洲一区免费在线 | 国产亚洲久一区二区 | 婷婷六月激情 | 国产精品免费观看在线 | 久久国产一区二区 | 国产综合视频在线观看 | 天天射天天爱天天干 | 最近高清中文在线字幕在线观看 | 久久九九免费 | 日本黄色免费播放 | 蜜臀av性久久久久蜜臀av | 国产精品美女免费视频 | 免费黄色小网站 | 日韩电影中文字幕在线 | 国产精品igao视频网网址 | 奇米影视777影音先锋 | 色婷婷 亚洲 | 天天草天天插 | 国产美女无遮挡永久免费 | 国产成人精品免费在线观看 | 麻豆系列在线观看 | 欧美日韩另类在线观看 | 国产精品麻豆视频 | 国产99久久精品一区二区永久免费 | 国产一级性生活 | 国产精品免费久久久久 | 狠狠狠操 | 国产中文字幕视频在线观看 | 91成人看片 | 日韩久久久 | 国产精品自产拍在线观看 | 国产99久久99热这里精品5 | 久久国产精品精品国产色婷婷 | 欧美一区三区四区 | 色资源在线 | 伊人久久电影网 | 91最新网址在线观看 | 五月婷婷丁香激情 | 很黄很污的视频网站 | 成人免费在线观看电影 | 免费在线看成人av | 午夜av免费观看 | 91麻豆国产 | 国产永久免费高清在线观看视频 | 精品国产乱码久久久久久浪潮 | 成人亚洲欧美 | a电影免费看 | 欧美成人在线网站 | 久久影视一区 | 91精品国产92久久久久 | 精品专区 | 91麻豆精品国产91久久久久久 | 国产视频在线观看一区二区 | 中文字幕电影一区 | 在线视频日韩 | 久久久久在线观看 | 久久精品欧美日韩精品 | 美女网站色在线观看 | 国产又粗又硬又长又爽的视频 | 色www免费视频 | 国产在线精品一区二区不卡了 | 婷婷视频在线播放 | 久久久久久影视 | 性色xxxxhd| 国产精品久久一区二区无卡 | 亚洲国产片| 一区二区三区高清在线观看 | 国产免码va在线观看免费 | 综合久久2023 | 日韩欧美一级二级 | 狠狠干网站| 久久国产午夜精品理论片最新版本 | 久久五月激情 | 国产看片网站 | 99精品久久只有精品 | 美女黄久久 | 久久久久这里只有精品 | 三级动图 | 手机在线看片日韩 | 午夜国产福利在线观看 | 97视频免费在线 | 一级片视频在线 | 日韩一级电影网站 | 91新人在线观看 | 在线天堂中文www视软件 | 久草在线最新免费 | 99这里都是精品 | 在线国产黄色 | 国产资源在线观看 | 欧美久久久影院 | 国产伦精品一区二区三区照片91 | 99re中文字幕 | 久久精品国产亚洲精品 | 亚洲成人av在线 | 天天摸天天舔 | 91最新网址 | 91精品久久久久久久久 | 久久精品国产精品 | 国产午夜在线观看视频 | 久久99日韩 | 亚洲精品永久免费视频 | a在线免费| 日本夜夜草视频网站 | 欧美午夜久久久 | 国产精品久久婷婷六月丁香 | 欧美激情视频一二区 | 久久国产精品一区二区 | 国产精品女同一区二区三区久久夜 | 97视频在线免费 | 911精品视频 | 国模一二三区 | 欧美一级视频免费 | 亚洲黄色免费在线看 | 中文字幕国产在线 | 91九色视频网站 | 成年人视频免费在线播放 | 99久免费精品视频在线观看 | 97在线播放| 久久精品系列 | 911国产在线观看 | 成年人免费在线观看网站 | 麻豆视频免费入口 | 96精品视频 | 欧美日韩亚洲第一页 | 国产亚州精品视频 | 国产日韩中文字幕 | 激情久久久久 | 欧美精品久久久久久久久老牛影院 | 免费又黄又爽视频 | 亚洲二区精品 | 91最新地址永久入口 | 免费日韩一区二区 | 欧美射射射 | 国产成人精品在线 | 五月av在线 | 中文字幕色在线视频 | 久久久久久久久久久久久9999 | 在线91色 | 欧美日韩国产免费视频 | 三级小视频在线观看 | www.com.日本一级 | 在线观看免费高清视频大全追剧 | 高清一区二区三区 | 国内精品在线看 | 国产探花在线看 | 91亚州| 五月婷婷六月丁香激情 | 91高清免费看 | 蜜臀av性久久久久蜜臀aⅴ四虎 | av网站大全免费 | 91在线看黄 | 麻豆传媒在线视频 | 在线观看国产v片 | 国产日本在线播放 | 色妞色视频一区二区三区四区 | 91福利国产在线观看 | 中文字幕免费高 | 手机成人在线电影 | 欧美成年人在线视频 | 日韩久久在线 | 欧美日韩中文在线观看 | 欧美日韩一区二区在线观看 | 日韩黄色中文字幕 | 久久久久国产免费免费 | 日韩性xxxx| 欧美精品中文在线免费观看 | 热re99久久精品国产99热 | 午夜影院先 | 亚洲精品一区二区三区新线路 | 黄色网址中文字幕 | 日本女人的性生活视频 | 免费不卡中文字幕视频 | 久久久精品欧美一区二区免费 | avove黑丝 | 国产一区二区久久久久 | 超碰人在线 | 天天色天天综合 | 久久久免费观看完整版 | 91在线免费观看国产 | 国产一级三级 | 久久久久久久久久久网 | 美女天天操 | 大胆欧美gogo免费视频一二区 | 国产成人精品一区二区在线 | 69国产成人综合久久精品欧美 | 日本美女xx| 天天干,天天操,天天射 | 人人澡人人澡人人 | 成人av免费电影 | 操操色| 久久综合色天天久久综合图片 | 日韩理论片在线 | 日本色小说视频 | 精品国产电影一区二区 | 四虎精品成人免费网站 | 91桃色免费观看 | 成年人电影毛片 | 国产精品网站一区二区三区 | 999久久| 天堂在线成人 | 亚洲更新最快 | 午夜久久福利影院 | 日韩精品视频免费看 | 欧美精品一区二区性色 | 欧美日韩精品在线视频 | 精品人人人 | 欧美精品一区二区在线播放 | 麻豆免费看片 | 精品久久久久久久久久久久久久久久久久 | 中文字幕在线不卡国产视频 | 欧美日韩伦理在线 | 麻豆视频免费在线 | 国产精品 中文在线 | av福利在线导航 | 日韩欧美亚洲 | 久久亚洲综合国产精品99麻豆的功能介绍 | 亚洲综合激情网 | 9草在线| 天堂在线视频免费观看 | 丰满少妇麻豆av | 日韩av播放在线 | 黄色免费看片网站 | 色综合天天 | 色视频 在线 | 人人要人人澡人人爽人人dvd | 特级a老妇做爰全过程 | 亚洲另类视频 | 在线亚洲午夜片av大片 | www.色婷婷.com | 日韩精品在线看 | 欧美aⅴ在线观看 | 国产精品普通话 | 成人97人人超碰人人99 | 99久久精品一区二区成人 | 美女国内精品自产拍在线播放 | 亚洲精品视频在线观看免费 | 激情五月婷婷综合网 | 在线播放国产一区二区三区 | 国产成人1区 | 亚洲欧美成人网 | 国产一区高清在线 | 999超碰 | www国产亚洲精品久久麻豆 | 国产成人精品在线观看 | 99久久99久久精品国产片果冰 | 九九九毛片 | 亚洲婷婷综合色高清在线 | 中文字幕专区高清在线观看 | 国产欧美精品在线观看 | 一区二区三区精品久久久 | 99在线视频精品 | 国产91精品一区二区麻豆网站 | 激情视频一区二区三区 | 91精品久久久久久综合五月天 | 国产97碰免费视频 | 成人av免费电影 | 蜜桃视频日本 | 国产五月天婷婷 | 久久久精华网 | 久久深夜福利免费观看 | 免费av的网站 | 色综合天天狠狠 | 99免费精品视频 | 欧美在线1区 | 日韩理论片中文字幕 | www.超碰 | 人人射人人插 | 五月天综合网 | 中文在线资源 | 九九热精品视频在线观看 | 国产精品激情在线观看 | 97av免费视频 | 久久伊人八月婷婷综合激情 | 免费av的网站 | 2019中文字幕第一页 | 久久任你操| 91精品视频免费在线观看 | 午夜久久久影院 | 亚洲欧美视频在线播放 | 久草在线视频在线观看 | 国产传媒一区在线 | 永久免费观看视频 | 亚洲欧美视频一区二区三区 | 日韩av在线免费看 | 中文字幕久久久精品 | 18国产精品福利片久久婷 | 91亚洲精品久久久久图片蜜桃 | 99精品一级欧美片免费播放 | 欧美成人性网 | 免费精品| 在线视频 日韩 | 免费在线观看污网站 | 国产.精品.日韩.另类.中文.在线.播放 | 狠狠精品| 2019中文| 国产色综合| 91成人黄色| 欧美日产在线观看 | 91大神视频网站 | 亚洲黄色app| 亚洲国产网址 | 国产黄色视 | 激情开心 | 中文字幕在线观看完整版 | 国产剧情一区 | 亚洲精品mv在线观看 | 中文字幕一区二区三区视频 | 欧洲亚洲精品 | 99久久精品免费一区 | 一区在线免费观看 | 日韩在线精品一区 | 国内精品国产三级国产aⅴ久 | 久久理伦片 | 婷婷综合在线 | 欧美日韩免费一区 | 国产精品美女久久久久久 | 亚洲视频专区在线 | 久久观看免费视频 | av九九九 | 99婷婷狠狠成为人免费视频 | 久久精品久久精品 | 黄色软件在线观看 | 日日夜夜中文字幕 | 午夜免费视频网站 | 91精品婷婷国产综合久久蝌蚪 | av免费网站观看 | 亚洲成人av在线播放 | 视频福利在线观看 | 麻豆传媒视频在线播放 | 狠狠躁夜夜躁人人爽超碰91 | 99re国产| 中文字幕在线观看视频一区二区三区 | 99精品视频免费全部在线 | 亚洲黄色av网址 | 免费看日韩 | 国产精品欧美一区二区三区不卡 | 91一区二区三区在线观看 | 99国产一区二区三精品乱码 | 国产视频一二区 | 中文字幕中文字幕在线中文字幕三区 | 亚洲va欧美va人人爽春色影视 | 97在线视频免费观看 | 91精品国自产在线观看 | 在线精品在线 | 又粗又长又大又爽又黄少妇毛片 | 99av国产精品欲麻豆 | 精品一区二区三区在线播放 | 韩国在线一区 | 9999亚洲| 激情视频久久 | 亚洲精品在线国产 | 亚洲黄色精品 | 日韩综合一区二区三区 | 日日久视频 | 国产精品二区在线观看 | 青青草国产精品 | 亚洲午夜精品一区 | 日本中文字幕网址 | 精品一区二区三区电影 | 国产精品久久久久久久久久久免费看 | 精品亚洲网 | 91精品视频免费在线观看 | 天天综合成人网 | 狠狠色丁香婷婷综合基地 | 91在线操 | 精品国产午夜 | 国产精品久久久久久欧美 | 天无日天天操天天干 | 欧美 亚洲 另类 激情 另类 | 久久超级碰视频 | av在线播放观看 | 精品国产一区二区三区av性色 | 亚洲经典在线 | 国产成人在线免费观看 | 午夜精品一区二区三区在线 | 日韩有码在线播放 | 国产电影一区二区三区四区 | 五月婷在线观看 | 97超碰资源| 国产生活一级片 | 亚洲精品视频网站在线观看 | www.色婷婷 | 亚洲成人av一区二区 | 久久国产精品视频观看 | 国产在线观看免费 | 韩日电影在线观看 | 久久国产精品电影 | 丁香视频在线观看 | 久久久.com | 天天操婷婷| 中文字幕免费一区二区 | 九九爱免费视频在线观看 | av在线网站大全 | 视频在线91| 免费视频97 | 中文字幕在线视频一区二区三区 | 国产成人精品亚洲a | 四虎成人免费观看 | 日韩免费区 | 亚洲男人天堂a | 久久只精品99品免费久23小说 | 天天久久综合 | 中文字幕在线观看一区 | 欧美日韩另类在线 | 91超碰免费在线 | 黄色一级免费 | 国产视| 国产这里只有精品 | 中文av不卡 | 在线性视频日韩欧美 | 久久看视频| 久久国产免费 | 六月丁香婷婷在线 | av网址aaa| av高清一区二区三区 | 人人爽人人乐 | 日韩精品一区二区三区高清免费 | 久草免费手机视频 | 中文字幕4 | 国产精品私拍 | 久久久私人影院 | 免费高清无人区完整版 | 97成人啪啪网 | 国产在线免费观看 | 国产成人免费网站 | 日日夜夜精品视频天天综合网 | 国产美女久久 | 在线观看视频国产一区 | 天天色天天综合 | 91大神在线观看视频 | 国产高清福利在线 | 日韩视频免费 | 久久久久亚洲精品成人网小说 | 九九免费精品视频在线观看 |