国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java集合框架ArrayList源碼分析(一)

Java集合框架ArrayList源碼分析(一)

2020-06-04 11:25風中程序猿 JAVA教程

這篇文章主要為大家詳細介紹了Java集合框架ArrayList源碼分析,感興趣的小伙伴們可以參考一下

ArrayList底層維護的是一個動態數組,每個ArrayList實例都有一個容量。該容量是指用來存儲列表元素的數組的大小。它總是至少等于列表的大小。隨著向 ArrayList 中不斷添加元素,其容量也自動增長。

 ArrayList不是同步的(也就是說不是線程安全的),如果多個線程同時訪問一個ArrayList實例,而其中至少一個線程從結構上修改了列表,那么它必須保持外部同步,在多線程環境下,可以使用Collections.synchronizedList方法聲明一個線程安全的ArrayList,例如:
List arraylist = Collections.synchronizedList(new ArrayList());
下面通過ArrayList的源碼來分析其原理。
1、ArrayList的構造方法:ArrayList提供了三種不同的構造方法
1) ArrayList(),構造一個初始容量為 10 的空列表。
2) ArrayList(int initialCapacity),構造一個具有指定初始容量的空列表。
3) ArrayList(Collection<? extends E> c),構造一個包含指定 collection 的元素的列表,這些元素是按照該 collection 的迭代器返回它們的順序排列的。

源碼如下: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
private transient Object[] elementData;
 
public ArrayList(int initialCapacity) {
 
  super();
 
  if (initialCapacity < 0)
 
    throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
 
  this.elementData = new Object[initialCapacity]; //生成一個長度為10的Object類型的數組
 
 }
 
 
 
 
 
 public ArrayList() {
 
  this(10); //調用ArrayList(int i)
 
 }<br><br>
 
 public ArrayList(Collection<? extends E> c) {
 
    elementData = c.toArray();  //返回包含此 collection 中所有元素的數組
 
  size = elementData.length;
 
  // c.toArray might (incorrectly) not return Object[] (see 6260652)
 
  if (elementData.getClass() != Object[].class)
 
   elementData = Arrays.copyOf(elementData, size, Object[].class); //復制指定的數組,返回包含相同元素和長度的Object類型的數組
 
 }

當采用不帶參數的構造方法ArrayList()生成一個集合對象時,其實是在底層調用ArrayList(int initialCapacity)這一構造方法生產一個長度為10的Object類型的數組。當采用帶有集合類型參數的構造方法時,在底層生成一個包含相同的元素和長度的Object類型的數組。 

2、add方法:ArrayList提供了兩種添加元素的add方法
1) add(E e),將指定的元素添加到此列表的尾部。
2) add(int index, E e),將指定的元素插入此列表中的指定位置。向右移動當前位于該位置的元素(如果有)以及所有后續元素(將其索引加 1)private int size;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public boolean add(E e) {
 
  ensureCapacity(size + 1); // 擴大數組容量
 
  elementData[size++] = e;  //將元素e添加到下標為size的Object數組中,并且執行size++
 
  return true;
 
  }
 
 
 
 public void add(int index, E element) {
 
  if (index > size || index < 0) //如果指定要插入的數組下標超過數組容量或者指定的下標小于0,拋異常
 
    throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
 
 
 
  ensureCapacity(size+1); // 擴大數組容量
 
  System.arraycopy(elementData, index, elementData, index + 1,size - index); //從指定源數組中復制一個數組,復制從指定的位置開始,到目標數組的指定位置結束。<br>                                          // elementData --- 源數組  index --- 源數組中的起始位置  <br>                                          // elementData --- 目標數組 index+1 --- 目標數組中的起始位置<br>                                          // size - index --- 要復制的數組元素的數量
 
  elementData[index] = element; //將要添加的元素放到指定的數組下標處
 
  size++;
 
  }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void ensureCapacity(int minCapacity) {
 
  modCount++;
 
  int oldCapacity = elementData.length; //原數組的容量
 
  if (minCapacity > oldCapacity) {
 
    Object oldData[] = elementData;
 
    int newCapacity = (oldCapacity * 3)/2 + 1; //定義新數組的容量,為原數組容量的1.5倍+1
 
      if (newCapacity < minCapacity)
 
    newCapacity = minCapacity;
 
      // minCapacity is usually close to size, so this is a win:
 
      elementData = Arrays.copyOf(elementData, newCapacity); //復制指定的數組,返回新數組的容量為newCapacity
 
  }
 
  }

如果集合中添加的元素超過了10個,那么ArrayList底層會新生成一個數組,長度為原數組的1.5倍+1,并將原數組中的元素copy到新數組中,并且后續添加的元素都會放在新數組中,當新數組的長度無法容納新添加的元素時,重復該過程。這就是集合添加元素的實現原理。

3、get方法:
 1) get(int index),返回此列表中指定位置上的元素。

?
1
2
3
4
5
6
7
8
9
10
11
12
public E get(int index) {
  RangeCheck(index); //檢查傳入的指定下標是否合法
 
  return (E) elementData[index]; //返回數組下標為index的數組元素
 
  }
private void RangeCheck(int index) {
  if (index >= size) //如果傳入的下標大于或等于集合的容量,拋異常
    throw new IndexOutOfBoundsException(
    "Index: "+index+", Size: "+size);
 
  }

4、remove方法:
1) E remove(int index),移除此列表中指定位置上的元素。向左移動所有后續元素(將其索引減 1)。
2) boolean remove(Object o),移除此列表中首次出現的指定元素(如果存在)。如果列表不包含此元素,則列表不做改動,返回boolean值。 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public E remove(int index) {
 
  RangeCheck(index); //檢查指定的下標是否合法
 
 
 
  modCount++;
 
  E oldValue = (E) elementData[index]; //獲取指定下標的數組元素
 
 
 
  int numMoved = size - index - 1; //要移動的元素個數
 
  if (numMoved > 0)
 
    System.arraycopy(elementData, index+1, elementData, index, numMoved); //移動數組元素
 
  elementData[--size] = null; // Let gc do its work
 
 
 
  return oldValue;
 
  }
 
 
 
 public boolean remove(Object o) {
 
  if (o == null) { //如果傳入的參數為null
 
      for (int index = 0; index < size; index++)
 
    if (elementData[index] == null) { //移除首次出現的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) { //移除指定位置的元素,實現方法類似remove(int i)
 
    modCount++;
 
    int numMoved = size - index - 1;
 
    if (numMoved > 0)
 
      System.arraycopy(elementData, index+1, elementData, index,
 
               numMoved);
 
    elementData[--size] = null; // Let gc do its work
 
  }

5、clone方法:
1) Object clone(),返回此ArrayList實例的淺表副本(不復制這些元素本身) 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public Object clone() {
  try {
    ArrayList<E> v = (ArrayList<E>) super.clone(); //調用Object類的clone方法返回一個ArrayList對象
    v.elementData = Arrays.copyOf(elementData, size); //復制目標數組
    v.modCount = 0;
    return v;
 
  } catch (CloneNotSupportedException e) {
 
    // this shouldn't happen, since we are Cloneable
 
    throw new InternalError();
 
  }
 
  }

以上通過對ArrayList部分關鍵源碼的分析,知道了ArrayList底層的實現原理,關于ArrayList源碼有以下幾點幾點總結:
 1) ArrayList 底層是基于數組來實現的,可以通過下標準確的找到目標元素,因此查找的效率高;但是添加或刪除元素會涉及到大量元素的位置移動,效率低。
 2) ArrayList提供了三種不同的構造方法,無參數的構造方法默認在底層生成一個長度為10的Object類型的數組,當集合中添加的元素個數大于10,數組會自動進行擴容,即生成一個新的數組,并將原數組的元素放到新數組中。
3) ensureCapacity方法對數組進行擴容,它會生成一個新數組,長度是原數組的1.5倍+1,隨著向ArrayList中不斷添加元素,當數組長度無法滿足需要時,重復該過程。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/fangfuhai/p/5767056.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产一区二区三区在线免费观看 | 自拍偷拍色 | 成人精品国产一区二区4080 | 午夜国产视频 | 免费无遮挡www小视频 | 日本不卡免费新一二三区 | 久久精品一区二区 | 免费一级毛片电影 | 日本激情视频一区二区三区 | 精品福利一区二区三区 | 亚洲精品久久久久久国产精华液 | 女人高潮特级毛片 | 黄色福利视频 | 精品在线一区二区 | 欧美黑人一级爽快片淫片高清 | 亚洲精品乱码久久久久久麻豆不卡 | 国产精品国产三级国产aⅴ中文 | 欧美成人精品一区二区三区 | 在线婷婷| 久久这里只有精品久久 | 国产精品久久久久国产精品 | 色噜噜狠狠狠综合曰曰曰88av | 99久久免费精品国产男女性高好 | 成人中文网| 欧美a在线看 | 精品视频在线免费观看 | 亚洲欧美高清 | 在线中文字幕av | 久久久久久久久久久免费 | 亚洲 欧美 日韩 在线 | 国产精品一区二区不卡 | 操av网| 99精品网站 | 国产性×xxx盗摄xxxx | 国产精品午夜电影 | 日韩免费一区二区 | 日韩在线视频观看免费 | 日本在线视频一区二区三区 | jizz国产| 欧美日韩在线免费观看 | 91国内外精品自在线播放 |