您好,登錄后才能下訂單哦!
這篇文章主要講解了“Java數據結構之ArrayList怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java數據結構之ArrayList怎么使用”吧!
在集合框架中,ArrayList是一個普通的類,實現了List接口,具體框架圖如下:
說明:
ArrayList實現了RandomAccess接口,表明ArrayList支持隨機訪問
ArrayList實現了Cloneable接口,表明ArrayList是可以clone的
ArrayList實現了Serializable接口,表明ArrayList是支持序列化的
和Vector不同,ArrayList不是線程安全的,在單線程下可以使用,在多線程中可以選擇Vector或者CopyOnWriteArrayList
ArrayList底層是一段連續的空間,并且可以動態擴容,是一個動態類型的順序表
方法 | 解釋 |
---|---|
ArrayList() | 無參構造 |
ArrayList(Collection<? extends E> c) | 利用其他 Collection 構建 ArrayList |
ArrayList(int initialCapacity) | 指定順序表初始容量 |
public static void main(String[] args) { // ArrayList創建,推薦寫法 // 構造一個空的列表 List<Integer> list1 = new ArrayList<>(); // 構造一個具有10個容量的列表 List<Integer> list2 = new ArrayList<>(10); list2.add(1); list2.add(2); list2.add(3); // list2.add("hello"); // 編譯失敗,List<Integer>已經限定了,list2中只能存儲整形元素 // list3構造好之后,與list中的元素一致 ArrayList<Integer> list3 = new ArrayList<>(list2); // 避免省略類型,否則:任意類型的元素都可以存放,使用時將是一場災難 List list4 = new ArrayList(); list4.add("111"); list4.add(100); }
方法 | 解釋 |
---|---|
boolean add(E e) | 尾插 e |
void add(int index, E element) | 將 e 插入到 index 位置 |
boolean addAll(Collection<? extends E> c) | 尾插 c 中的元素 |
E remove(int index) | 刪除 index 位置元素 |
boolean remove(Object o) | 刪除遇到的第一個 o |
E get(int index) | 獲取下標 index 位置元素 |
E set(int index, E element) | 將下標 index 位置元素設置為 element |
void clear() | 清空 |
boolean contains(Object o) | 判斷 o 是否在線性表中 |
int indexOf(Object o) | 返回第一個 o 所在下標 |
int lastIndexOf(Object o) | 返回最后一個 o 的下標 |
List subList(int fromIndex, int toIndex) | 截取部分 list |
public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("JavaSE"); list.add("JavaWeb"); list.add("JavaEE"); list.add("JVM"); list.add("測試課程"); System.out.println(list); // 獲取list中有效元素個數 System.out.println(list.size()); // 獲取和設置index位置上的元素,注意index必須介于[0, size)間 System.out.println(list.get(1)); list.set(1, "JavaWEB"); System.out.println(list.get(1)); // 在list的index位置插入指定元素,index及后續的元素統一往后搬移一個位置 list.add(1, "Java數據結構"); System.out.println(list); // 刪除指定元素,找到了就刪除,該元素之后的元素統一往前搬移一個位置 list.remove("JVM"); System.out.println(list); // 刪除list中index位置上的元素,注意index不要超過list中有效元素個數,否則會拋出下標越界異常 list.remove(list.size()-1); System.out.println(list);
//輸出結果:
[JavaSE, JavaWeb, JavaEE, JVM, 測試課程]
5
JavaWeb
JavaWEB
[JavaSE, Java數據結構, JavaWEB, JavaEE, JVM, 測試課程]
[JavaSE, Java數據結構, JavaWEB, JavaEE, 測試課程]
[JavaSE, Java數據結構, JavaWEB, JavaEE]
ArrayList 可以使用三方方式遍歷:for循環+下標、foreach、使用迭代器
public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); // 使用下標+for遍歷 for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i) + " "); } System.out.println(); // 借助foreach遍歷 for (Integer integer : list) { System.out.print(integer + " "); } System.out.println(); Iterator<Integer> it = list.listIterator(); while(it.hasNext()){ System.out.print(it.next() + " "); } System.out.println(); }
//輸出結果:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
ArrayList是一個動態類型的順序表,即:在插入元素的過程中會自動擴容:以下是ArrayList源碼中擴容方式
Object[] elementData; // 存放元素的空間 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默認空間 private static final int DEFAULT_CAPACITY = 10; // 默認容量大小 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } 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 code if (minCapacity - elementData.length > 0) grow(minCapacity); } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private void grow(int minCapacity) { // 獲取舊空間大小 int oldCapacity = elementData.length; // 預計按照1.5倍方式擴容 int newCapacity = oldCapacity + (oldCapacity >> 1); // 如果用戶需要擴容大小 超過 原空間1.5倍,按照用戶所需大小擴容 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; // 如果需要擴容大小超過MAX_ARRAY_SIZE,重新計算容量大小 if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // 調用copyOf擴容 elementData = Arrays.copyOf(elementData, newCapacity); } private static int hugeCapacity(int minCapacity) { // 如果minCapacity小于0,拋出OutOfMemoryError異常 if (minCapacity < 0) throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
檢測是否真正需要擴容,如果是調用grow準備擴容
預估需要庫容的大小
初步預估按照1.5倍大小擴容
如果用戶所需大小超過預估1.5倍大小,則按照用戶所需大小擴容
真正擴容之前檢測是否能擴容成功,防止太大導致擴容失敗
使用copyOf進行擴容
撲克牌:
public class Card { public int rank; // 牌面值 public String suit; // 花色 @Override public String toString() { return String.format("[%s %d]", suit, rank); } }
import java.util.List; import java.util.ArrayList; import java.util.Random; public class CardDemo { public static final String[] SUITS = {"?", "?", "?", "?"}; // 買一副牌 private static List<Card> buyDeck() { List<Card> deck = new ArrayList<>(52); for (int i = 0; i < 4; i++) { for (int j = 1; j <= 13; j++) { String suit = SUITS[i]; int rank = j; Card card = new Card(); card.rank = rank; card.suit = suit; deck.add(card); } } return deck; } private static void swap(List<Card> deck, int i, int j) { Card t = deck.get(i); deck.set(i, deck.get(j)); deck.set(j, t); } private static void shuffle(List<Card> deck) { Random random = new Random(20190905); for (int i = deck.size() - 1; i > 0; i--) { int r = random.nextInt(i); swap(deck, i, r); } } public static void main(String[] args) { List<Card> deck = buyDeck(); System.out.println("剛買回來的牌:"); System.out.println(deck); shuffle(deck); System.out.println("洗過的牌:"); System.out.println(deck); // 三個人,每個人輪流抓 5 張牌 List<List<Card>> hands = new ArrayList<>(); hands.add(new ArrayList<>()); hands.add(new ArrayList<>()); hands.add(new ArrayList<>()); for (int i = 0; i < 5; i++) { for (int j = 0; j < 3; j++) { hands.get(j).add(deck.remove(0)); } } System.out.println("剩余的牌:"); System.out.println(deck); System.out.println("A 手中的牌:"); System.out.println(hands.get(0)); System.out.println("B 手中的牌:"); System.out.println(hands.get(1)); System.out.println("C 手中的牌:"); System.out.println(hands.get(2)); } }
運行結果
剛買回來的牌:
[[♠ 1], [♠ 2], [♠ 3], [♠ 4], [♠ 5], [♠ 6], [♠ 7], [♠ 8], [♠ 9], [♠ 10], [♠ 11], [♠ 12], [♠ 13], [♥ 1], [♥ 2], [♥ 3], [♥ 4], [♥ 5], [♥ 6], [♥ 7],
[♥ 8], [♥ 9], [♥ 10], [♥ 11], [♥ 12], [♥ 13], [♣ 1], [♣ 2], [♣ 3], [♣ 4], [♣ 5], [♣ 6], [♣ 7], [♣ 8], [♣ 9], [♣ 10], [♣ 11], [♣ 12], [♣
13], [♦ 1], [♦ 2], [♦ 3], [♦ 4], [♦ 5], [♦ 6], [♦ 7], [♦ 8], [♦ 9], [♦ 10], [♦ 11], [♦ 12], [♦ 13]]
洗過的牌:
[[♥ 11], [♥ 6], [♣ 13], [♣ 10], [♥ 13], [♠ 2], [♦ 1], [♥ 9], [♥ 12], [♦ 5], [♥ 8], [♠ 6], [♠ 3], [♥ 5], [♥ 1], [♦ 6], [♦ 13], [♣ 12], [♦ 12],
[♣ 5], [♠ 4], [♣ 3], [♥ 7], [♦ 3], [♣ 2], [♠ 1], [♦ 2], [♥ 4], [♦ 8], [♠ 10], [♦ 11], [♥ 10], [♦ 7], [♣ 9], [♦ 4], [♣ 8], [♣ 7], [♠ 8], [♦ 9], [♠
12], [♠ 11], [♣ 11], [♦ 10], [♠ 5], [♠ 13], [♠ 9], [♠ 7], [♣ 6], [♣ 4], [♥ 2], [♣ 1], [♥ 3]]
剩余的牌:
[[♦ 6], [♦ 13], [♣ 12], [♦ 12], [♣ 5], [♠ 4], [♣ 3], [♥ 7], [♦ 3], [♣ 2], [♠ 1], [♦ 2], [♥ 4], [♦ 8], [♠ 10], [♦ 11], [♥ 10], [♦ 7], [♣ 9], [♦
4], [♣ 8], [♣ 7], [♠ 8], [♦ 9], [♠ 12], [♠ 11], [♣ 11], [♦ 10], [♠ 5], [♠ 13], [♠ 9], [♠ 7], [♣ 6], [♣ 4], [♥ 2], [♣ 1], [♥ 3]]
A 手中的牌:
[[♥ 11], [♣ 10], [♦ 1], [♦ 5], [♠ 3]]
B 手中的牌:
[[♥ 6], [♥ 13], [♥ 9], [♥ 8], [♥ 5]]
C 手中的牌:
[[♣ 13], [♠ 2], [♥ 12], [♠ 6], [♥ 1]]
感謝各位的閱讀,以上就是“Java數據結構之ArrayList怎么使用”的內容了,經過本文的學習后,相信大家對Java數據結構之ArrayList怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。