存儲(chǔ)多個(gè)數(shù)據(jù)可以使用數(shù)組,但由于數(shù)組在內(nèi)存中是連續(xù)存儲(chǔ)的,所以會(huì)有一些限制。比如數(shù)組在創(chuàng)建時(shí)就要指定長(zhǎng)度,即可以容納的元素個(gè)數(shù),且指定后無(wú)法更改;數(shù)組在創(chuàng)建時(shí)需要指定元素的類型,并且所有元素都必須是該類型或其子類;添加或刪除數(shù)組中的元素需要?jiǎng)?chuàng)建一個(gè)新數(shù)組再進(jìn)行元素復(fù)制,比較麻煩。下面是 Person 數(shù)組擴(kuò)容的示意代碼。
(資料圖)
// 給 people1 數(shù)組末尾添加一個(gè)元素public class PersonArray { public static void main(String[] args) { Person[] people1 = new Person[1]; people1[0] = new Person(); // 創(chuàng)建新數(shù)組 Person[] people2 = new Person[people1.length + 1]; // 復(fù)制 people1 數(shù)組的元素到 people2 for (int i = 0; i < people1.length; i++) { people2[i] = people1[i]; } // 添加新元素 people2[people2.length - 1] = new Person(); }}
數(shù)組可以通過(guò)索引快速訪問(wèn)和操作元素,在許多場(chǎng)景下仍然是非常有用的,但如果需要?jiǎng)討B(tài)調(diào)整大小或保存不同類型的元素,則可以考慮使用集合類來(lái)代替數(shù)組。集合類還提供了一系列增加、刪除、修改和查找元素的方法。集合框架中還提供了多種優(yōu)化和封裝好的實(shí)現(xiàn)類,通過(guò)使用合適的集合類可以更高效地組織和操作數(shù)據(jù)。
Java 的集合類很多,主要有Collection
和Map
兩個(gè)接口,層次關(guān)系如下圖。
Collection
接口有List
和Set
這兩個(gè)重要的子接口,它們的實(shí)現(xiàn)子類都是單列集合。其中List
接口表示有序的、可以包含重復(fù)元素的集合,常見(jiàn)的實(shí)現(xiàn)類有ArrayList
、LinkedList
和Vector
。Set
接口表示無(wú)序的且不包含重復(fù)元素的集合,常見(jiàn)的實(shí)現(xiàn)類有HashSet
、TreeSet
和LinkedHashSet
。
Map
接口實(shí)現(xiàn)子類是雙列集合,表示一組鍵值對(duì)的映射,其中每個(gè)鍵都是唯一的。常見(jiàn)的實(shí)現(xiàn)類有HashMap
、Hashtable
和Properties
。
public class AddElements() { public static void main(String[] args) { ArrayList
Collection
實(shí)現(xiàn)類(通常通過(guò)其中一個(gè)子接口間接實(shí)現(xiàn)Collection)可以存放多個(gè) Object 類型的元素。有些Collection
接口的實(shí)現(xiàn)類可以存放重復(fù)的元素,有些則不可以。有些Collection
接口的實(shí)現(xiàn)類是有序的(List
),有些是無(wú)序的(Set
)。Collection
接口沒(méi)有直接實(shí)現(xiàn)類,提供了更具體的子接口(如Set
和List
)的實(shí)現(xiàn)。
所有通用的Collection實(shí)現(xiàn)類都會(huì)提供兩個(gè)"標(biāo)準(zhǔn)"構(gòu)造方法:一個(gè)無(wú)參構(gòu)造方法,來(lái)創(chuàng)建一個(gè)空的集合,以及一個(gè)帶有單個(gè)Collection類型參數(shù)的構(gòu)造方法,創(chuàng)建一個(gè)與參數(shù)集合具有相同元素的新集合。實(shí)際上,后一種構(gòu)造方法可以復(fù)制任何集合,生成一個(gè)與參數(shù)集合元素相同的所需類型的集合。
public class CollectionMethod() { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(1); list.add(2); list.add(3); System.out.println(list);// [1, 2, 3] Vector
下面的代碼以其間接實(shí)現(xiàn)類ArrayList
演示Collection
接口的常用方法。
public class CollectionMethod() { public static void main(String[] args) { Collection collection = new ArrayList<>(); // boolean add(E e) // 給集合中添加指定的元素,添加成功則返回 true。 // 如果此集合不允許重復(fù)元素并且已經(jīng)包含了指定的元素,則返回 false。 // 支持此操作的實(shí)現(xiàn)類可能會(huì)對(duì)添加到該集合中的元素進(jìn)行限制。 // 如果一個(gè)集合拒絕添加某個(gè)特定元素的原因不是因?yàn)榧弦呀?jīng)包含該元素, // 會(huì)拋出一個(gè)異常(而不是返回 false)。 collection.add("hello"); collection.add(10); collection.add(true); // 下面一條語(yǔ)句執(zhí)行后輸出:collection = [hello, 10, true] System.out.println("collection = " + collection); // boolean remove(Object o) // 從集合中移除指定元素的一個(gè)實(shí)例。如果集合包含多個(gè)滿足 // (o==null ? e==null : o.equals(e))條件的元素 e, // 則移除第一個(gè)元素 e。移除完成后返回 true。 collection.remove("hello"); // 下面一條語(yǔ)句執(zhí)行后輸出:collection = [10, true]System.out.println("collection = " + collection); // boolean contains(Object o) // 如果此集合包含指定元素,則返回 true。更準(zhǔn)確地說(shuō),當(dāng)且僅當(dāng)此集合包含至少 // 一個(gè)滿足(o==null ? e==null : o.equals(e))條件的元素 e 時(shí),返回 true。 System.out.println(collection.contains(10));// true // int size() // 返回此集合中的元素?cái)?shù)量。 System.out.println(collection.size());// 2 // boolean isEmpty() // 判斷集合是否為空。 System.out.println(collection.isEmpty());// false // void clear() // 清空集合中的元素。 collection.clear(); // 下面一條語(yǔ)句執(zhí)行后輸出:collection = [] System.out.println("collection = " + collection); // boolean addAll(Collection extends E> c) // 將指定集合中的所有元素添加到此集合中。 Collection collection1 = new ArrayList(); collection1.add("Mary"); collection1.add("Luck"); collection.addAll(collection1); // 下面一條語(yǔ)句執(zhí)行后輸出:collection = [Mary, Luck] System.out.println("collection = " + collection); // boolean containsAll(Collection> c) // 判斷此集合是否包含指定集合中的所有元素 System.out.println(collection.containsAll(collection1));// true // boolean removeAll(Collection> c) // 從此集合中移除與指定集合中相同的所有元素。 // 在此調(diào)用返回后,此集合將不包含與指定集合共有的任何元素。 collection.add("King"); collection.removeAll(collection1); // 下面一條語(yǔ)句執(zhí)行后輸出:collection = [King] System.out.println("collection = " + collection); }}
Iterator
接口是集合的迭代器,主要用于遍歷Collection
集合中的元素。所有實(shí)現(xiàn)了Collection
接口的實(shí)現(xiàn)類,都有一個(gè)iterator()
方法,用以返回一個(gè)實(shí)現(xiàn)了Iterator
接口的對(duì)象,即可以返回一個(gè)迭代器。
Iterator
接口的方法:
// 判斷是否還有下一個(gè)元素boolean hasNext() // 返回集合中的下一個(gè)元素E next()// 從底層集合中移除此迭代器返回的最后一個(gè)元素。每次調(diào)用 next() 只能調(diào)用此方法一次。// 如果在調(diào)用此方法之前尚未調(diào)用過(guò) next() 方法,或者在最后一次調(diào)用 next() 方法之后// 已經(jīng)調(diào)用了過(guò)一次 remove() 方法,則拋出 IllegalStateException 異常。default void remove() // 對(duì)剩余的每個(gè)元素執(zhí)行給定的操作,直到所有元素被處理完或操作拋出異常為止。default void forEachRemaining(Consumer super E> action)
迭代器的使用示例代碼:
public class CollectionIterateor() { public static void main(String[] args) { Collection col = new ArrayList(); col.add("紅樓夢(mèng)"); col.add("西游記"); col.add("三國(guó)演義"); col.add("水滸傳"); // 遍歷 col 集合 // 先獲得 col 對(duì)應(yīng)的迭代器 Iterator iterator = col.iterator(); // 使用 while 循環(huán)遍歷 while (iterator.hasNext()) {// 判斷是否還有元素 Object obj = iterator.next(); // 返回下一個(gè)元素,類型是 Object System.out.println("obj = " + obj); } // 當(dāng)退出 while 循環(huán)后,iterator 迭代器指向最后一個(gè)元素 // 此時(shí)再調(diào)用 next() 會(huì)拋出 NoSuchElementException 異常 // iterator.next(); // 如果需要再次遍歷,需要重制迭代器 System.out.println("===第二次遍歷==="); iterator = col.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println("obj = " + obj); } }}
由于當(dāng)?shù)髦胁淮嬖谙乱粋€(gè)元素時(shí),直接調(diào)用 iterator.next() 方法會(huì)拋出 NoSuchElementException 異常,所以調(diào)用 iterator.next() 方法之前需要調(diào)用 iterator.hasNext() 方法。
增強(qiáng) for 循環(huán)是簡(jiǎn)化版的 iterator,本質(zhì)一樣,只能用來(lái)遍歷集合或數(shù)組。基本語(yǔ)法如下:
for(元素類型 元素名 : 集合名或數(shù)組名){訪問(wèn)元素;}
public class EnhancedFor() { public static void main(String[] args) { Collection collection = new ArrayList(); collection.add("mary"); collection.add(true); collection.add(10); for (Object o : collection) { System.out.println("o = " + o); } }}
關(guān)鍵詞: