集合按照其存儲結構可以分爲兩大類,分別是單列集合Collection和雙列集合Map,本文主要介紹Collection
Collection
Collection單列集合類的根接口,用於存儲一系列符合某種規則的元素,它有兩個重要的子接口,分別是java.util.List
和java.util.Set
。
其中,List
的特點是元素有序、元素可重複。List
接口的主要實現類有java.util.ArrayList
和java.util.LinkedList
.
Set
的特點是元素無序,而且不可重複。Set
接口的主要實現類有java.util.HashSet
和java.util.TreeSet
。
List子接口、Set子接口
List子接口
- 有序的集合,存儲和取出順序相同
- 允許存重複元素
- 有索引
Set子接口
- 不允許存重複的元素
- 沒有索引
ArrayList是我們開發中非常常用的數據存儲容器之一,其底層是數組實現的,我們可以在集合中存儲任意類型的數據,ArrayList是線程不安全的,非常適合用於對元素進行查找,效率非常高。
ArrayList優點:
- 因爲其底層是數組,所以修改和查詢效率高。
- 可自動擴容(1.5倍)。
ArrayList缺點:
- 插入和刪除效率不高
- 線程不安全
常用方法
Collection是所有單列集合的父接口,因此在Collection中定義了單列集合(List和Set)通用的一些方法,這些方法可用於操作所有的單列集合。方法如下:
public boolean add(E e)
: 把給定的對象添加到當前集合中 。public void clear()
:清空集合中所有的元素。public boolean remove(E e)
: 把給定的對象在當前集合中刪除。public boolean contains(E e)
: 判斷當前集合中是否包含給定的對象。public boolean isEmpty()
: 判斷當前集合是否爲空。public int size()
: 返回集合中元素的個數。public Object[] toArray()
: 把集合中的元素,存儲到數組中。
遍歷集合:迭代器Iterator
在程序開發中,經常需要遍歷集合中的所有元素。針對這種需求,JDK專門提供了一個接口java.util.Iterator
。Iterator
接口也是Java集合中的一員,但它與Collection
、Map
接口有所不同,Collection
接口與Map
接口主要用於存儲元素,而Iterator
主要用於迭代訪問(即遍歷)Collection
中的元素,因此Iterator
對象也被稱爲迭代器。
想要遍歷Collection集合,那麼就要獲取該集合迭代器完成迭代操作,下面介紹一下獲取迭代器的方法:
public Iterator iterator()
: 獲取集合對應的迭代器,用來遍歷集合中的元素的。
下面介紹一下迭代的概念:
- 迭代:即Collection集合元素的通用獲取方式。在取元素之前先要判斷集合中有沒有元素,如果有,就把這個元素取出來,繼續在判斷,如果還有就再取出出來。一直把集合中的所有元素全部取出。這種取出方式專業術語稱爲迭代。
Iterator接口的常用方法如下:
public E next()
:返回迭代的下一個元素。public boolean hasNext()
:如果仍有元素可以迭代,則返回 true。
遍歷集合or數組:增強foreach
增強for循環(也稱for each循環)是JDK1.5以後出來的一個高級for循環,專門用來遍歷數組和集合的。它的內部原理其實是個Iterator迭代器
,所以在遍歷的過程中,不能對集合中的元素進行增刪操作。
for(元素的數據類型 變量 : Collection集合or數組){
//寫操作代碼
}
tips: 新for循環必須有被遍歷的目標。目標只能是Collection或者是數組。foreach僅僅作爲遍歷操作出現。
迭代器和foreach的遍歷code
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/* 創建集合:遍歷集合的兩種方法
(1)使用迭代器遍歷:
* (2)增強for()循環遍歷集合或者數組:
* */
public class Demo2Iterator{
public static void main(String[] args) {
//(1)創建集合
Collection<String> coll = new ArrayList<>();
coll.add("hello");
coll.add("world");
coll.add("!");
//(2)多態:通過結合對象獲取迭代器對象
Iterator<String> iterator = coll.iterator();
//迭代器遍歷集合
while(iterator.hasNext()){ //判斷 迭代器中是否還有元素
System.out.println(iterator.next()); //有元素則獲取
}
//(3)增強for循環遍歷該集合
for (String s:coll) {
System.out.println(s); //內部原理其實還是一個迭代器
}
}
}
不要在foreach裏面進行元素的remove/add操作:
如果要進行remove
操作,可以調用迭代器的 remove
方法而不是 集合類的 remove
方法。因爲如果列表在任何時間從結構上修改創建迭代器之後,以任何方式除非通過迭代器自身remove/add方法,迭代器都將拋出一個ConcurrentModificationException,這就是單線程狀態下產生的 fail-fast 機制。
fail-fast 機制 :多個線程對 fail-fast 集合進行修改的時,可能會拋出ConcurrentModificationException,單線程下也會出現這種情況,上面已經提到過。