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

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - ArrayList詳解和使用示例_動力節(jié)點Java學(xué)院整理

ArrayList詳解和使用示例_動力節(jié)點Java學(xué)院整理

2020-09-27 15:26動力節(jié)點 Java教程

ArrayList 是一個數(shù)組隊列,相當(dāng)于 動態(tài)數(shù)組。與Java中的數(shù)組相比,它的容量能動態(tài)增長。接下來通過本文給大家介紹arraylist詳解和使用示例代碼,需要的的朋友一起學(xué)習(xí)吧

第1部分 ArrayList介紹

ArrayList簡介

ArrayList 是一個數(shù)組隊列,相當(dāng)于 動態(tài)數(shù)組。與Java中的數(shù)組相比,它的容量能動態(tài)增長。它繼承于AbstractList,實現(xiàn)了List, RandomAccess, Cloneable, java.io.Serializable這些接口。

ArrayList 繼承了AbstractList,實現(xiàn)了List。它是一個數(shù)組隊列,提供了相關(guān)的添加、刪除、修改、遍歷等功能。

ArrayList 實現(xiàn)了RandmoAccess接口,即提供了隨機訪問功能。RandmoAccess是java中用來被List實現(xiàn),為List提供快速訪問功能的。在ArrayList中,我們即可以通過元素的序號快速獲取元素對象;這就是快速隨機訪問。稍后,我們會比較List的“快速隨機訪問”和“通過Iterator迭代器訪問”的效率。

ArrayList 實現(xiàn)了Cloneable接口,即覆蓋了函數(shù)clone(),能被克隆。

ArrayList 實現(xiàn)java.io.Serializable接口,這意味著ArrayList支持序列化,能通過序列化去傳輸。和Vector不同,ArrayList中的操作不是線程安全的!所以,建議在單線程中才使用ArrayList,而在多線程中可以選擇Vector或者CopyOnWriteArrayList。 

ArrayList構(gòu)造函數(shù) 

?
1
2
3
4
5
6
// 默認構(gòu)造函數(shù)
ArrayList()
// capacity是ArrayList的默認容量大小。當(dāng)由于增加數(shù)據(jù)導(dǎo)致容量不足時,容量會添加上一次容量大小的一半。
ArrayList(int capacity)
// 創(chuàng)建一個包含collection的ArrayList
ArrayList(Collection<? extends E> collection)

ArrayList的API 

?
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
// Collection中定義的API
boolean    add(E object)
boolean    addAll(Collection<? extends E> collection)
void    clear()
boolean    contains(Object object)
boolean    containsAll(Collection<?> collection)
boolean    equals(Object object)
int     hashCode()
boolean    isEmpty()
Iterator<E>   iterator()
boolean    remove(Object object)
boolean    removeAll(Collection<?> collection)
boolean    retainAll(Collection<?> collection)
int     size()
<T> T[]    toArray(T[] array)
Object[]   toArray()
// AbstractCollection中定義的API
void    add(int location, E object)
boolean    addAll(int location, Collection<? extends E> collection)
E     get(int location)
int     indexOf(Object object)
int     lastIndexOf(Object object)
ListIterator<E>  listIterator(int location)
ListIterator<E>  listIterator()
E     remove(int location)
E     set(int location, E object)
List<E>    subList(int start, int end)
// ArrayList新增的API
Object    clone()
void     ensureCapacity(int minimumCapacity)
void     trimToSize()
void     removeRange(int fromIndex, int toIndex)

第2部分 ArrayList數(shù)據(jù)結(jié)構(gòu)

ArrayList的繼承關(guān)系

?
1
2
3
4
5
6
java.lang.Object
  java.util.AbstractCollection<E>
  java.util.AbstractList<E>
    java.util.ArrayList<E>
public class ArrayList<E> extends AbstractList<E>
  implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

ArrayList與Collection關(guān)系如下圖:

ArrayList詳解和使用示例_動力節(jié)點Java學(xué)院整理

ArrayList包含了兩個重要的對象:elementData 和 size

(1) elementData 是"Object[]類型的數(shù)組",它保存了添加到ArrayList中的元素。實際上,elementData是個動態(tài)數(shù)組,我們能通過構(gòu)造函數(shù) ArrayList(int initialCapacity)來執(zhí)行它的初始容量為initialCapacity;如果通過不含參數(shù)的構(gòu)造函數(shù)ArrayList()來創(chuàng)建ArrayList,則elementData的容量默認是10。elementData數(shù)組的大小會根據(jù)ArrayList容量的增長而動態(tài)的增長,具體的增長方式,請參考源碼分析中的ensureCapacity()函數(shù)。

(2) size 則是動態(tài)數(shù)組的實際大小。 

第3部分 ArrayList源碼解析(基于JDK1.6.0_45)

為了更了解ArrayList的原理,下面對ArrayList源碼代碼作出分析。ArrayList是通過數(shù)組實現(xiàn)的,源碼比較容易理解。   

?
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
package java.util;
 public class ArrayList<E> extends AbstractList<E>
   implements List<E>, RandomAccess, Cloneable, java.io.Serializable
 {
  // 序列版本號
  private static final long serialVersionUID = 8683452581122892189L;
  // 保存ArrayList中數(shù)據(jù)的數(shù)組
  private transient Object[] elementData;
  // ArrayList中實際數(shù)據(jù)的數(shù)量
  private int size;
  // ArrayList帶容量大小的構(gòu)造函數(shù)。
  public ArrayList(int initialCapacity) {
   super();
   if (initialCapacity < 0)
    throw new IllegalArgumentException("Illegal Capacity: "+
             initialCapacity);
   // 新建一個數(shù)組
   this.elementData = new Object[initialCapacity];
  }
 
  // ArrayList構(gòu)造函數(shù)。默認容量是10。
  public ArrayList() {
   this();
  }
  // 創(chuàng)建一個包含collection的ArrayList
  public ArrayList(Collection<? extends E> c) {
   elementData = c.toArray();
   size = elementData.length;
   // c.toArray might (incorrectly) not return Object[] (see 6260652)
   if (elementData.getClass() != Object[].class)
    elementData = Arrays.copyOf(elementData, size, Object[].class);
  }
  // 將當(dāng)前容量值設(shè)為 =實際元素個數(shù)
  public void trimToSize() {
   modCount++;
   int oldCapacity = elementData.length;
   if (size < oldCapacity) {
    elementData = Arrays.copyOf(elementData, size);
   }
  }
  // 確定ArrarList的容量。
  // 若ArrayList的容量不足以容納當(dāng)前的全部元素,設(shè)置 新的容量=“(原始容量x3)/2 + 1”
  public void ensureCapacity(int minCapacity) {
  // 將“修改統(tǒng)計數(shù)”+1
   modCount++;
   int oldCapacity = elementData.length;
   // 若當(dāng)前容量不足以容納當(dāng)前的元素個數(shù),設(shè)置 新的容量=“(原始容量x3)/2 + 1”
   if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;
    if (newCapacity < minCapacity)
     newCapacity = minCapacity;
    elementData = Arrays.copyOf(elementData, newCapacity);
   }
  }
  // 添加元素e
  public boolean add(E e) {
   // 確定ArrayList的容量大小
   ensureCapacity(size + ); // Increments modCount!!
   // 添加e到ArrayList中
   elementData[size++] = e;
   return true;
  }
  // 返回ArrayList的實際大小
  public int size() {
   return size;
  }
  // 返回ArrayList是否包含Object(o)
  public boolean contains(Object o) {
   return indexOf(o) >= 0;
  }
  // 返回ArrayList是否為空
  public boolean isEmpty() {
   return size == 0;
  }
  // 正向查找,返回元素的索引值
  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;
   }
  // 反向查找,返回元素的索引值
   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;
  }
  // 反向查找(從數(shù)組末尾向開始查找),返回元素(o)的索引值
  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;
  }
  // 返回ArrayList的Object數(shù)組
  public Object[] toArray() {
   return Arrays.copyOf(elementData, size);
  }
  // 返回ArrayList的模板數(shù)組。所謂模板數(shù)組,即可以將T設(shè)為任意的數(shù)據(jù)類型
  public <T> T[] toArray(T[] a) {
   // 若數(shù)組a的大小 < ArrayList的元素個數(shù);
   // 則新建一個T[]數(shù)組,數(shù)組大小是“ArrayList的元素個數(shù)”,并將“ArrayList”全部拷貝到新數(shù)組中
   if (a.length < size)
    return (T[]) Arrays.copyOf(elementData, size, a.getClass());
   // 若數(shù)組a的大小 >= ArrayList的元素個數(shù);
  // 則將ArrayList的全部元素都拷貝到數(shù)組a中。
   System.arraycopy(elementData, 0, a, 0, size);
   if (a.length > size)
    a[size] = null;
   return a;
  }
  // 獲取index位置的元素值
  public E get(int index) {
   RangeCheck(index);
   return (E) elementData[index];
  }
  // 設(shè)置index位置的值為element
  public E set(int index, E element) {
   RangeCheck(index);
   E oldValue = (E) elementData[index];
   elementData[index] = element;
   return oldValue;
  }
  // 將e添加到ArrayList中
  public boolean add(E e) {
   ensureCapacity(size + 1); // Increments modCount!!
   elementData[size++] = e;
   return true;
  }
  // 將e添加到ArrayList的指定位置
  public void add(int index, E element) {
   if (index > size || index < 0)
   throw new IndexOutOfBoundsException(
    "Index: "+index+", Size: "+size);
   ensureCapacity(size+1); // Increments modCount!!
   System.arraycopy(elementData, index, elementData, index + 1,
    size - index);
   elementData[index] = element;
   size++;
  }
  // 刪除ArrayList指定位置的元素
  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+, elementData, index,
     numMoved);
   elementData[--size] = null; // Let gc do its work
   return oldValue;
  }
  // 刪除ArrayList的指定元素
  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;
  }
  // 快速刪除第index個元素
  private void fastRemove(int index) {
   modCount++;
  int numMoved = size - index - 1;
   // 從"index+1"開始,用后面的元素替換前面的元素。
   if (numMoved > 0)
    System.arraycopy(elementData, index+, elementData, index,
        numMoved);
   // 將最后一個元素設(shè)為null
   elementData[--size] = null; // Let gc do its work
  }
  // 刪除元素
  public boolean remove(Object o) {
   if (o == null) {
   for (int index = 0; index < size; index++)
    if (elementData[index] == null) {
     fastRemove(index);
    return true;
    }
   } else {
    // 便利ArrayList,找到“元素o”,則刪除,并返回true。
    for (int index = 0; index < size; index++)
    if (o.equals(elementData[index])) {
     fastRemove(index);
    return true;
    }
   }
   return false;
  }
  // 清空ArrayList,將全部的元素設(shè)為null
  public void clear() {
   modCount++;
   for (int i = ; i < size; i++)
    elementData[i] = null;
 
  size = 0;
  }
  // 將集合c追加到ArrayList中
  public boolean addAll(Collection<? extends E> c) {
   Object[] a = c.toArray();
   int numNew = a.length;
   ensureCapacity(size + numNew); // Increments modCount
   System.arraycopy(a, 0, elementData, size, numNew);
  size += numNew;
   return numNew != 0;
  }
  // 從index位置開始,將集合c添加到ArrayList
 public boolean addAll(int index, Collection<? extends E> c) {
  if (index > size || index < 0)
    throw new IndexOutOfBoundsException(
    "Index: " + index + ", Size: " + size);
   Object[] a = c.toArray();
   int numNew = a.length;
   ensureCapacity(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;
  }
  // 刪除fromIndex到toIndex之間的全部元素。
  protected void removeRange(int fromIndex, int toIndex) {
  modCount++;
  int numMoved = size - toIndex;
   System.arraycopy(elementData, toIndex, elementData, fromIndex,
       numMoved);
  // Let gc do its work
  int newSize = size - (toIndex-fromIndex);
  while (size != newSize)
   elementData[--size] = null;
  }
  private void RangeCheck(int index) {
  if (index >= size)
   throw new IndexOutOfBoundsException(
   "Index: "+index+", Size: "+size);
  }
  // 克隆函數(shù)
  public Object clone() {
   try {
    ArrayList<E> v = (ArrayList<E>) super.clone();
    // 將當(dāng)前ArrayList的全部元素拷貝到v中
    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();
   }
  }
  // java.io.Serializable的寫入函數(shù)
  // 將ArrayList的“容量,所有的元素值”都寫入到輸出流中
  private void writeObject(java.io.ObjectOutputStream s)
   throws java.io.IOException{
  // Write out element count, and any hidden stuff
  int expectedModCount = modCount;
  s.defaultWriteObject();
   // 寫入“數(shù)組的容量”
   s.writeInt(elementData.length);
  // 寫入“數(shù)組的每一個元素”
  for (int i=0; i<size; i++)
    s.writeObject(elementData[i]);
  if (modCount != expectedModCount) {
    throw new ConcurrentModificationException();
   }
  }
  // java.io.Serializable的讀取函數(shù):根據(jù)寫入方式讀出
  // 先將ArrayList的“容量”讀出,然后將“所有的元素值”讀出
  private void readObject(java.io.ObjectInputStream s)
   throws java.io.IOException, ClassNotFoundException {
   // Read in size, and any hidden stuff
   s.defaultReadObject();
   // 從輸入流中讀取ArrayList的“容量”
   int arrayLength = s.readInt();
   Object[] a = elementData = new Object[arrayLength];
   // 從輸入流中將“所有的元素值”讀出
  for (int i=0; i<size; i++)
    a[i] = s.readObject();
  }
 }

總結(jié):

(01) ArrayList 實際上是通過一個數(shù)組去保存數(shù)據(jù)的。當(dāng)我們構(gòu)造ArrayList時;若使用默認構(gòu)造函數(shù),則ArrayList的默認容量大小是10。

(02) 當(dāng)ArrayList容量不足以容納全部元素時,ArrayList會重新設(shè)置容量:新的容量=“(原始容量x3)/2 + 1”。

(03) ArrayList的克隆函數(shù),即是將全部元素克隆到一個數(shù)組中。

(04) ArrayList實現(xiàn)java.io.Serializable的方式。當(dāng)寫入到輸出流時,先寫入“容量”,再依次寫入“每一個元素”;當(dāng)讀出輸入流時,先讀取“容量”,再依次讀取“每一個元素”。

第4部分 ArrayList遍歷方式

ArrayList支持3種遍歷方式

(01) 第一種,通過迭代器遍歷。即通過Iterator去遍歷。

?
1
2
3
4
5
Integer value = null;
Iterator iter = list.iterator();
while (iter.hasNext()) {
 value = (Integer)iter.next();
}

(02) 第二種,隨機訪問,通過索引值去遍歷。

由于ArrayList實現(xiàn)了RandomAccess接口,它支持通過索引值去隨機訪問元素。

?
1
2
3
4
5
Integer value = null;
int size = list.size();
for (int i=0; i<size; i++) {
 value = (Integer)list.get(i); 
}

(03) 第三種,for循環(huán)遍歷。如下:

?
1
2
3
4
Integer value = null;
for (Integer integ:list) {
 value = integ;
}

由此可見,遍歷ArrayList時,使用隨機訪問(即,通過索引序號訪問)效率最高,而使用迭代器的效率最低!

第5部分 toArray()異常

當(dāng)我們調(diào)用ArrayList中的 toArray(),可能遇到過拋出“java.lang.ClassCastException”異常的情況。下面我們說說這是怎么回事。

ArrayList提供了2個toArray()函數(shù):

?
1
2
Object[] toArray()
<T> T[] toArray(T[] contents)

調(diào)用 toArray() 函數(shù)會拋出“java.lang.ClassCastException”異常,但是調(diào)用 toArray(T[] contents) 能正常返回 T[]。
toArray() 會拋出異常是因為 toArray() 返回的是 Object[] 數(shù)組,將 Object[] 轉(zhuǎn)換為其它類型(如如,將Object[]轉(zhuǎn)換為的Integer[])則會拋出“java.lang.ClassCastException”異常,因為Java不支持向下轉(zhuǎn)型。具體的可以參考前面ArrayList.java的源碼介紹部分的toArray()。

解決該問題的辦法是調(diào)用 <T> T[] toArray(T[] contents) , 而不是 Object[] toArray()。

調(diào)用 toArray(T[] contents) 返回T[]的可以通過以下幾種方式實現(xiàn)。
 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// toArray(T[] contents)調(diào)用方式一
public static Integer[] vectorToArray1(ArrayList<Integer> v) {
 Integer[] newText = new Integer[v.size()];
 v.toArray(newText);
 return newText;
}
// toArray(T[] contents)調(diào)用方式二。最常用!
public static Integer[] vectorToArray2(ArrayList<Integer> v) {
 Integer[] newText = (Integer[])v.toArray(new Integer[0]);
 return newText;
}
// toArray(T[] contents)調(diào)用方式三
public static Integer[] vectorToArray3(ArrayList<Integer> v) {
 Integer[] newText = new Integer[v.size()];
 Integer[] newStrings = (Integer[])v.toArray(newText);
 return newStrings;
}

第6部分 ArrayList示例

本文通過一個實例(ArrayListTest.java),介紹 ArrayList 中常用API的用法。   

?
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
import java.util.*;
/*
* @desc ArrayList常用API的測試程序
*
*
*/
public class ArrayListTest {
 public static void main(String[] args) {
  
 // 創(chuàng)建ArrayList
  ArrayList list = new ArrayList();
  // 將“”
  list.add("1");
  list.add("2");
  list.add("3");
 list.add("4");
  // 將下面的元素添加到第1個位置   list.add(0, "5");
 // 獲取第1個元素
  System.out.println("the first element is: "+ list.get(0));
  // 刪除“3”
  list.remove("3");
 // 獲取ArrayList的大小
  System.out.println("Arraylist size=: "+ list.size());
  // 判斷l(xiāng)ist中是否包含"3"
 System.out.println("ArrayList contains 3 is: "+ list.contains(3));
 // 設(shè)置第2個元素為10
 list.set(1, "10");
  // 通過Iterator遍歷ArrayList
  for(Iterator iter = list.iterator(); iter.hasNext(); ) {
   System.out.println("next is: "+ iter.next());
  }
  // 將ArrayList轉(zhuǎn)換為數(shù)組
  String[] arr = (String[])list.toArray(new String[]);
  for (String str:arr)
   System.out.println("str: "+ str);
  // 清空ArrayList
  list.clear();
  // 判斷ArrayList是否為空
  System.out.println("ArrayList is empty: "+ list.isEmpty());
 }
}

運行結(jié)果:

?
1
2
3
4
5
6
7
8
9
10
11
12
the first element is: 5
Arraylist size=: 4
ArrayList contains 3 is: false
next is: 5
next is: 10
next is: 2
next is: 4
str: 5
str: 10
str: 2
str: 4
ArrayList is empty: true

以上所述是小編給大家介紹的ArrayList詳解和使用示例_動力節(jié)點Java學(xué)院整理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜久久久 | 自拍偷拍一区 | 一区二区三区在线视频播放 | 久久久久国产精品免费免费搜索 | 中文字幕亚洲欧美 | 国产精品精品 | 国产精品国产三级国产aⅴ中文 | 日韩a电影| 激情六月婷 | 亚洲精品片| 超碰c| 在线国产一区二区 | 黄色一区二区三区 | 一区二区三区精品 | 精品国产黄a∨片高清在线 欧美一级免费 | 操操日日| 国产高清不卡在线 | 精品自拍视频 | 亚洲人免费视频 | 中国电影黄色一级片免费观看 | av久草 | 欧美激情精品久久久久久 | 久久一区二区视频 | 美女羞羞网站 | 欧美亚洲视频在线观看 | 精品一区二区三区免费毛片爱 | 另类久久| 天天干一干| 69中文字幕 | 久久久久久国产精品 | 亚洲一区在线视频 | 国产成人免费 | 亚洲精品一二区 | 精品视频久久 | 午夜国产在线 | 亚洲高清久久 | 亚洲一区二区精品 | 2级毛片| 第一色网站 | 视频1区2区 | 一区二区三区中文字幕 |