陣列列表(ArrayList)
2020-10-20 [email protected] stronglzq
【摘要】針對陣列容量固定無法擴充套件的問題,引入陣列列表(ArrayList)。主要對陣列列表的宣告及基本操作等內容進行介紹,基本操作包括增加元素、插入元素、刪除元素以及元素的訪問與修改。
- 為什麼要引入陣列列表(ArrayList)
- 陣列列表容量為什麼能變動
- 如何宣告陣列列表
- 陣列列表的增加、插入、刪除、修改、訪問操作
- 陣列列表的缺陷
- 如何靈活的擴充套件陣列,又能方便的訪問元素
- 如何降低陣列列表的記憶體消耗 -- 預設列表容量
為什麼要引入陣列列表(ArrayList)
陣列在建立後容量固定,而實際解決問題的過程中,元素的數量是變動的,此時採用陣列來儲存資料難以滿足業務需求,因此引入陣列列表。
陣列列表容量為什麼能變動
在建立陣列時,需確定陣列長度,此時陣列中產生一個個“蘿蔔坑”(有初始值,若為int類元素,初始值為0),增加元素即為往“蘿蔔坑”中放入“蘿蔔”;陣列列表可在宣告時預估容量,或不預估容量,當不預估容量,或者元素超過預估容量時,若增加一個元素,則會自動申請一個新的陣列,將原先陣列列表的內容複製到新陣列中,並在末端放入新元素。
如何宣告陣列列表
陣列列表是具有型別引數(type parameter)的泛型類(genetic class),故需要在宣告陣列列表時,指明元素型別,語法為ArrayList<element type>
。陣列列表的宣告語法有三種:
ArrayList<element type> name = new ArrayList<element type>();
ArrayList<element type> name = new ArrayList<>();
,相對於第一種宣告方法,省略了等號右側陣列列表的元素型別;var name = new ArrayList<element type>();
,使用var則一定不能省略等號右側陣列列表的元素型別。
public class Person{ private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; } } public class ArrayListTest{ // 用陣列列表來儲存Person資料 var person = new ArrayList<Person>(); // ArrayList<Person> person = new ArrayList<Person>(); // ArrayList<Person> person = new ArrayList<>(); person.add(new Person("Peter", 20)); person.add(new Person("Tom", 23)); person.add(new Person("Lucy", 26)); }
陣列列表的增加、插入、刪除、修改、訪問
(1)陣列列表的增加為在列表末端增加元素,使用add()方法;(2)對位置i的元素修改為e,語句為set(i, e)
;(3)訪問位置i的元素,語句為get(i)
;(4)在位置i,插入元素e,則原先位置i及之後的元素均向後移一位,語句為add(i, e)
;(5)刪除位置i的元素,語句為remove(i)
。
注:陣列列表的插入、刪除效率低。
public ArrayListTest{
// 用陣列列表來儲存Person資料
var person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<>();
person.add(new Person("Peter", 20));
person.add(new Person("Tom", 23));
person.add(new Person("Lucy", 26));
// 修改元素
person.set(1, new Person("Peter Long", 25));
// 插入元素
person.add(2, new Person("Jack", 30));
// 刪除元素
person.remove(0);
// 訪問元素
person.get(1);
}
陣列列表的缺陷
使用陣列列表存在兩個缺陷,(1)無法直接通過元素下標來訪問元素,不方便;(2)陣列列表由於每變動一個元素,均需要重新申請一個新的陣列來存放,對記憶體消耗大;(3)陣列列表元素的插入、刪除效率低,解決方案為採用連結串列的資料型別;
如何既靈活的擴充套件陣列,又能方便的訪問陣列元素?
陣列無法靈活的擴充套件,故引入了陣列列表,但陣列列表元素訪問繁瑣,針對各自的問題,有一解決方法:(1)建立一個數組列表,並填充元素;(2)建立一個數組,陣列大小為陣列列表實際元素的數量;(3)使用toArray方法,將陣列列表的元素複製到該陣列中。
public class ArrayListTest{
// 用陣列列表來儲存Person資料
var person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<Person>();
// ArrayList<Person> person = new ArrayList<>();
person.add(new Person("Peter", 20));
person.add(new Person("Tom", 23));
person.add(new Person("Lucy", 26));
// 建立一個數組,大小為陣列列表的大小
Person[] personArray = new Person[person.size()];
// 將陣列列表的元素複製到陣列中
person.toArray(personArray);
}
注:陣列列表的size()方法返回陣列列表實際元素的數量,而陣列的size()方法返回陣列容量。
如何降低陣列列表的記憶體消耗?-- 預設列表容量
針對陣列列表記憶體消耗大的問題,可以預設一個列表容量,在元素數量不超過預設容量時,元素的增加不需要重新分配空間。預設列表容量有兩種方式:(1)在構造陣列列表時,確定列表容量;(2)使用陣列列表的ensureCapcity()方法。
public class ArrayListTest{
// 預設陣列列表的容量為100
var person = new ArrayList<Person>(100);
// 或 var person = new ArrayList<Person>(); person.ensureCapcity(100);
}