JavaRush /Java Blog /Random-TW /Java中的ArrayList類

Java中的ArrayList類

在 Random-TW 群組發布
你好!在先前的講座中,我們詳細研究了數組等資料結構,並查看了使用它們的常見範例。但這種資料結構有許多缺點。Java 中 ArrayList 的出現給了他們答案。簡而言之,Java 中的 ArrayList 是一個「升級版」的數組,並且具有許多新功能。ArrayList 類別 - 1

Java Arraylist 與常規陣列有何不同?

一般來說,陣列非常方便,而且正如您已經注意到的,您可以用它們做很多事情:)但是,陣列也有許多缺點。
  • 尺寸有限。您需要在創建數組的階段就知道它應包含多少個單元格。如果您低估了所需的數量,則將沒有足夠的空間。如果你高估了它,數組將保持一半為空,這還不錯。畢竟,事實證明您也會為其分配比必要的更多的記憶體。
  • 數組沒有添加元素的方法。您始終必須明確指定要新增元素的儲存格的索引。如果您不小心指定了某個已佔用的儲存格所需的值,它將被覆寫。
  • 沒有方法可以刪除元素。該值只能“清零”。
public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Hippopotamus");
       cats[2] = new Cat("Philip Markovich");

       cats[1] = null;



       System.out.println(Arrays.toString(cats));
   }

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
結論:

[Cat{name='Томас'}, null, Cat{name='Фorпп Маркович'}]
使用ArrayList 可以消除所有這些缺點。它的創建非常簡單:
ArrayList<Cat> cats = new ArrayList<Cat>();
現在我們已經建立了一個清單來儲存物件Cat注意:我們不指定 ArrayList 的大小,因為它是可自動擴充的。這怎麼可能?容易地。你會感到驚訝,但是 ArrayList 是基於普通數組的:) 是的,裡面有一個數組,裡面儲存了我們的元素。但 ArrayList 有一個特殊的機制來使用它:
  • 當這個內部陣列已滿時,ArrayList 會在其內部建立一個新陣列。它的大小 = (舊數組的大小 * 1.5) +1。
  • 所有資料都從舊數組複製到新數組
  • 舊數組被垃圾收集器刪除。
由於這種機制,ArrayList(與陣列相反)實作了添加新元素的方法。這是一個方法add()
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Hippopotamus"));
}
新元素將添加到列表的末尾。現在不存在溢出的風險,所以這個機制是完全安全的。順便說一句,ArrayList 不僅可以透過索引搜尋對象,反之亦然——它可以透過引用對象來尋找 ArrayList 中對象的索引!為此,它實現了以下方法indexOf():我們向其傳遞一個指向所需對象的鏈接,然後indexOf()它將其索引返回給我們:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
結論:

0
沒錯,物件thomas實際上是存放在cell中的0。數組不僅有缺點,也有無可置疑的優點。其中之一是透過索引搜尋元素。由於我們指向的是索引,也就是記憶體中的特定位址,所以這樣的陣列查找速度非常快。Java中的ArrayList也可以做到這一點!為此,它實作了一個方法get()
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
結論:

Cat{name='Бегемот'}
此外,您還可以輕鬆找出 ArrayList 是否包含特定物件。這是使用以下方法完成的contains()
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   cats.remove(pushok);
   System.out.println(cats.contains(pushok));
}
boolean此方法檢查該元素是否包含在 ArrayList 的內部陣列中,並以-true或 的 形式傳回結果false。結論:

false
關於插入的另一個重要的事情。ArrayList 不僅允許您在陣列末尾插入數據,還可以透過索引插入任何儲存格中。它有兩種方法:
  • add(int index, Cat element)
  • set(int index, Cat element)
對於兩者,您可以傳遞要插入的單元格的索引以及物件本身的連結。不同之處在於貼上set()會覆蓋儲存格中儲存的舊值。插入add()首先會將所有元素從數組開始移動[index]到數組末尾,並將所需的物件添加到生成的空單元格中。這是一個例子:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.set(0, philipp);//Now we have a list of 2 cats. We add the 3rd via set:

   System.out.println(cats.toString());
}
結論:

[[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Бегемот'}]
我們有 2 隻貓的列表,我們透過該方法將另一隻貓插入set()到單元格中0。結果,儲存在該儲存格中的舊值會被新值取代。
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.add(0, philipp);//Now we have a list of 2 cats. Add the 3rd via add

   System.out.println(cats.toString());
}
但它的add()作用不同。他將所有元素向右移動,然後將新值寫入儲存格中0。結論:

[Cat{name='Томас'}, Cat{name='Бегемот'}]
[Cat{name='Фorпп Маркович'}, Cat{name='Томас'}, Cat{name='Бегемот'}]
若要完全清除列表,請使用以下方法clear()
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   cats.clear();

   System.out.println(cats.toString());
}
結論:

[]
所有內容已從清單中刪除。順便說一句,請注意:與陣列不同,在 ArrayList 中,toString() 方法會重寫並立即以字串格式顯示清單。對於數組,我們必須使用 Arrays 類別來實現此目的。由於我們還記得數組:在 Java 中,您可以輕鬆地在數組和 ArrayList 之間“切換”,即將一個數組轉換為另一個數組。Arrays 類別有一個方法可以實現此目的,即 Arrays.asList()。在它的幫助下,我們以列表的形式獲取數組的內容並將其傳遞給 ArrayList 的建構子:
public static void main(String[] args) {

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   Cat[] catsArray = {thomas, behemoth, philipp, pushok};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
結論:

[Cat{name='Томас'}, Cat{name='Бегемот'}, Cat{name='Фorпп Маркович'}, Cat{name='Пушок'}]
您也可以執行相反的操作 - 從 ArrayList 物件取得陣列。為此,請使用 toArray() 方法:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   Cat[] catsArray = cats.toArray(new Cat[0]);

   System.out.println(Arrays.toString(catsArray));
}
請注意:我們將一個空數組傳遞給 toArray() 方法。這不是一個錯誤。在 ArrayList 類別內部,此方法的實作方式是傳遞空數組以提高其效能。現在,請記住這一點以備將來使用(但您也可以傳輸特定大小,它會起作用)。說到尺寸。可以使用以下方法找到清單的目前大小size()
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   System.out.println(cats.size());
}
這裡要理解的是,與length陣列屬性不同,ArrayList.size() 方法傳回的正是元素的數量,而不是初始容量,因為我們在建立 ArrayList 時沒有指定它。順便說一下,通常都可以標明的。ArrayList有一個對應的建構子。但它在添加新元素方面的行為不會改變:
public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>(2);//create an ArrayList with an initial capacity of 2


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Hippopotamus");
   Cat philipp = new Cat("Philip Markovich");
   Cat pushok = new Cat("Fluff");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(philipp);
   cats.add(pushok);

   System.out.println(cats.size());
}
控制台輸出:

4
我們創建了一個包含 2 個元素的列表,但是當我們需要它時,它很容易擴展。另外,如果我們最初建立的清單非常小,那麼它就必須更頻繁地進行擴充操作,這會消耗一定的資源。在本次講座中,我們幾乎沒有涉及從 ArrayList 中刪除元素的過程。當然,這並不是因為健忘。這個主題已被分成一個單獨的講座,您可以進一步閱讀:)
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION