Java ArrayList指南

1.概述

在本文中,我們將研究Java Collections Framework中的ArrayList類。我們將討論它的屬性,常見用例以及它的優缺點。

ArrayList駐留在Java Core庫中,因此您不需要任何其他庫。為了使用它,只需添加以下import語句:

import java.util.ArrayList;

列表表示值的有序序列,其中某些值可能會出現多次。

List是構建在數組之上的List實現之一,它可以在添加/刪除元素時動態增長和收縮。通過從零開始的索引可以輕鬆訪問元素。此實現具有以下屬性:

  • 隨機訪問需要O(1) 時間
  • 加元素需要攤銷固定時間*O(1) *
  • 插入/刪除需要*O(n) *時間
  • 搜索需要*O(n)時間來處理未排序的數組,而需要O(log n) *來進行排序的數組

2.創建一個ArrayList

ArrayList有幾個構造函數,我們將在本節中全部介紹它們。

首先,請注意ArrayList是泛型類,因此您可以使用所需的任何類型對其進行參數化,並且編譯器將確保例如,您將無法將Integer值放入String的集合中。同樣,從集合中檢索元素時也不需要強制轉換元素。

其次,優良作法是將通用接口List用作變量類型,因為它會將其與特定實現分離。

2.1。默認無參數搆造函數

List<String> list = new ArrayList<>();
assertTrue(list.isEmpty());

我們只是創建一個空的ArrayList實例

2.2。搆造函數接受初始容量

List<String> list = new ArrayList<>(20);

這裡指定基礎數組的初始長度。這可以幫助您在添加新元素時避免不必要的調整大小

2.3。搆造函數接受集合

Collection<Integer> number 
  = IntStream.range(0, 10).boxed().collect(toSet());

List<Integer> list = new ArrayList<>(numbers);
assertEquals(10, list.size());
assertTrue(numbers.containsAll(list));

注意,Collection實例的元素用於填充list數組。

3.向ArrayList添加元素

可以在末尾或特定位置插入元素:

List<Long> list = new ArrayList<>();

list.add(1L);
list.add(2L);
list.add(1, 3L);

assertThat(Arrays.asList(1L, 3L, 2L), equalTo(list));

也可以同時插入一個集合或多個元素:

List<Long> list = new ArrayList<>(Arrays.asList(1L, 2L, 3L));
LongStream.range(4, 10).boxed()
  .collect(collectingAndThen(toCollection(ArrayList::new), ys -> list.addAll(0, ys)));
assertThat(Arrays.asList(4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L), equalTo(list));

4.遍歷ArrayList

有兩種可用的迭代器:IteratorListIterator
前者使您有機會在一個方向上遍歷該列表,而後者則使您可以在兩個方向上遍歷該列表。

在這裡,我們僅向您顯示ListIterator

List<Integer> list = new ArrayList<>(
  IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new))
);
ListIterator<Integer> it = list.listIterator(list.size());
List<Integer> result = new ArrayList<>(list.size());
while (it.hasPrevious()) {
    result.add(it.previous());
}

Collections.reverse(list);
assertThat(result, equalTo(list));

您也可以使用迭代器搜索,添加或刪除元素。

5.搜索ArrayList

我們將演示如何使用集合進行搜索:

List<String> list = LongStream.range(0, 16)
  .boxed()
  .map(Long::toHexString)
  .collect(toCollection(ArrayList::new));
List<String> stringsToSearch = new ArrayList<>(list);
stringsToSearch.addAll(list);

5.1。搜索未排序列表

為了找到元素,可以使用indexOf()lastIndexOf()方法。它們都接受一個對象並返回int值:

assertEquals(10, stringsToSearch.indexOf("a"));
assertEquals(26, stringsToSearch.lastIndexOf("a"));

如果你想找到滿足Predicate的所有元素,你可以使用Java 8過濾收集流API(閱讀更多關於它在這裡使用)Predicate是這樣的:

Set<String> matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));

List<String> result = stringsToSearch
  .stream()
  .filter(matchingStrings::contains)
  .collect(toCollection(ArrayList::new));

assertEquals(6, result.size());

也可以使用for循環或迭代器:

Iterator<String> it = stringsToSearch.iterator();
Set<String> matchingStrings = new HashSet<>(Arrays.asList("a", "c", "9"));

List<String> result = new ArrayList<>();
while (it.hasNext()) {
    String s = it.next();
    if (matchingStrings.contains(s)) {
        result.add(s);
    }
}

5.2.搜索排序列表

如果您有一個排序數組,則可以使用二進制搜索算法,該算法比線性搜索更快:

List<String> copy = new ArrayList<>(stringsToSearch);
Collections.sort(copy);
int index = Collections.binarySearch(copy, "f");
assertThat(index, not(equalTo(-1)));

注意,如果找不到元素,則返回-1

6.從ArrayList中删除元素

為了刪除元素,您應該找到它的索引,然後才通過remove()方法執行刪除。此方法的重載版本,它接受一個對象,對其進行搜索並刪除第一次出現的equal元素:

List<Integer> list = new ArrayList<>(
  IntStream.range(0, 10).boxed().collect(toCollection(ArrayList::new))
);
Collections.reverse(list);

list.remove(0);
assertThat(list.get(0), equalTo(8));

list.remove(Integer.valueOf(0));
assertFalse(list.contains(0));

但是在使用Boxed類型(例如Integer)時要小心。為了刪除一個特定的元素,您應該首先將int值裝箱,否則,一個元素將被其索引刪除。

您也可以使用前面提到的Stream API刪除多個項目,但是我們這裡不再顯示。為此,我們將使用迭代器:

Set<String> matchingStrings
 = HashSet<>(Arrays.asList("a", "b", "c", "d", "e", "f"));

Iterator<String> it = stringsToSearch.iterator();
while (it.hasNext()) {
    if (matchingStrings.contains(it.next())) {
        it.remove();
    }
}

7.總結

在這篇快速文章中,我們了解了Java中的ArrayList。
我們展示瞭如何創建ArrayList實例,如何使用不同的方法添加,查找或刪除元素。
與往常一樣,您可以找到所有程式碼示例在GitHub上,