經過前文的學習,咱們對容器的分類及經常使用容器類的做用有了基本的認識。本文將針對Collection容器的功能與使用進行細緻分析。html
Collection集合抽象出的目的是爲存放獨立元素的序列。java
Collection接口定義的基本操做包含添加,移除,查找,遍歷等。具體API定義以下:數組
abstract boolean add(E e) abstract boolean addAll(Collection<? extends E> c) abstract boolean clear() abstract boolean contains(Object o) abstract boolean containsAll(Collection<? extends E> c) abstract boolean equals(Object o) abstract int hashCode() abstract boolean isEmpty() abstract Iterator<E> iterator() abstract boolean remove(Object o) abstract boolean removeAll(Collection<?> c) abstract boolean retainAll(Collection<?> c) abstract int size() abstract Object[] toArray() abstract <T> T[] toArray(T[] a)
這些操做能夠按照具體做用來劃分,下面咱們結合一些實例來理解。安全
package collection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; public class Adding { public static void main(String[] args) { //構造方法直接添加 Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4)); //使用add方法 collection.add(5); System.out.println(collection); Integer[] Ints = {10, 11, 12}; //使用addAll方法 collection.addAll(Arrays.asList(Ints)); System.out.println(collection); //Collections提供的addAll方法 Collections.addAll(collection, Ints); System.out.println(collection); } }
輸出結果工具
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5, 10, 11, 12] [1, 2, 3, 4, 5, 10, 11, 12, 10, 11, 12]
本例中,Arrays的asList方法可將數組轉換爲List類型,咱們能夠經過構造方法直接初始化Collection實例。若想添加單個元素,直接調用add方法;想要添加一組元素,也可調用addAll方法。另外一種比較高效方式是調用Collections的addAll方法。學習
Collection與Collections同屬於集合類,但卻徹底不一樣。這是Java開發者很是容易混淆的內容。線程
Collection是集合的頂層接口,而Collections則是一個工具類。Collections提供了許多靜態方法,從而可以操做集合,對集合中的元素進行排序,添加以及搜索等操做。例如:code
排序htm
package collections; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class TestCollections1{ public static void main(String[] args){ Integer[] a = {10, 30, 20, 9, 4, 1, 50}; List<Integer> list = new ArrayList<Integer>(); Collections.addAll(list, a); System.out.println(list); Collections.sort(list); System.out.println(list); } }
輸出結果blog
[10, 30, 20, 9, 4, 1, 50] [1, 4, 9, 10, 20, 30, 50]
Collections中實用的方法還有不少,下面列出一些經常使用方法的API,本文就再也不一一贅述。
public static <T> boolean addAll(Collection<? super T> c, T... elements) //二分搜索搜索列表指定元素 public static <T> int binarySearch(List<? extends T>, T key) //將元素從一個列表複製到到另外一個列表 public static <T> void copy(List<? super T> dest, List<? extends T> src); //反轉列表 public static void reverse(List<?> list) //隨機化列表 public static void shuffle(List<T> list) //返回線程安全的collection public static <T> Collection<T> synchronizedCollection(Collection<T> c) public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)
package collection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; public class Removing{ public static void main(String[] args) { String[] arr = {"I'm sorry","I'm coding", "I'm writing", "I'm learning", "I'm thinking"}; Collection<String> collection = new ArrayList<String>(Arrays.asList(arr)); Collection<String> c = new ArrayList<String>(Arrays.asList("I'm learning", "I'm thinking")); System.out.println(collection); //移除元素 collection.remove("I'm writing"); System.out.println(collection); //移除一組元素 collection.removeAll(c); System.out.println(collection); //移除全部元素 collection.clear(); System.out.println(collection); } }
輸出結果
[I'm sorry, I'm coding, I'm writing, I'm learning, I'm thinking] [I'm sorry, I'm coding, I'm learning, I'm thinking] [I'm sorry, I'm coding] []
本例中,調用remove方法刪除集合中單個元素,經過removeAll方法刪除一組包含於collection中的元素,使用clear方法可移除集合全部元素。
觀察Collection定義的API可看出,Collection接口彷佛沒有對訪問指定位置元素,遍歷列表提供合適的方法。contains、equals兩種方法可查找元素,卻也沒法實現迭代,遍歷元素的目的。
這時就須要Iterator(迭代器)來爲咱們幫忙了,Collection中iterator()方法直接返回容器的Iterator,以遍歷整個容器。
迭代器(Iterator)這一律念源自C++的STL(標準模板庫),使用者可直接遍歷容器而無需關心其結構類型,直接使用Iterator便可。Java中,Iterator的限制是只能單向遍歷容器。
Iteraotr提供瞭如下三種方法
boolean hasNext() E next() void remove()
hasNext方法用於肯定容器中是否還有元素,next方法得到容器中下一個元素,remove方法刪除Iterator目前指向的元素。
舉個栗子
package collection; import java.util.*; public class EasyIteration{ public static void main(String[] args){ Integer[] Ints = {1, 2, 3, 8, 5}; Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(Ints)); Iterator<Integer> it = collection.iterator(); //遍歷開始,hasNext控制邊界 while(it.hasNext()){ System.out.print(it.next()+" "); } System.out.println(); it = collection.iterator(); for(int i = 0; i < 2; i++){ it.next(); //刪除元素 it.remove(); } System.out.println(collection); } }
輸出結果
1 2 3 8 5 [3, 8, 5]
本例中,有了Iterator,咱們就能夠對容器中的元素進行訪問和刪除操做,而無需關心容器的具體類型。
UnspportedOperationException拋出的緣由是使用了不當的容器操做。一般是因爲嘗試修改固定長度的容器的緣故,調用Array.asList() 方法會返回這種容器。由於數組顯然是固定長度的容器,使用asList方法轉換爲list也會保持這種屬性。
舉個栗子
package collection; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; public class UnspportedTest{ public static void test(String msg, Collection<Integer> collection){ Integer[] arr = {1, 3, 4}; Collection<Integer> tc = Arrays.asList(arr); //使用會修改容器的操做 System.out.println("****" + msg + "****"); try{ collection.add(5); }catch(Exception e){ e.printStackTrace(); } try{ Collections.addAll(collection, arr); } catch(Exception e){ e.printStackTrace(); } try{ collection.retainAll(tc); } catch(Exception e){ e.printStackTrace(); } try{ collection.remove(1); }catch(Exception e){ e.printStackTrace(); } try{ collection.removeAll(Arrays.asList(arr)); } catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args){ Integer[] arr = {1, 3, 1, 4, 1, 2}; Collection<Integer> c = Arrays.asList(arr); Collection<Integer> c1 = new ArrayList<Integer>(c); test("可修改", c1); test("不可修改", c); test("不可修改", Collections.unmodifiableCollection(c1)); } }
輸出結果
****可修改**** ****不可修改**** java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:148) at java.util.AbstractList.add(AbstractList.java:108) at collection.UnspportedTest.test(UnspportedTest.java:13) at collection.UnspportedTest.main(UnspportedTest.java:47) java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:148) at java.util.AbstractList.add(AbstractList.java:108) at java.util.Collections.addAll(Collections.java:3845) at collection.UnspportedTest.test(UnspportedTest.java:18) at collection.UnspportedTest.main(UnspportedTest.java:47) java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at java.util.AbstractList$Itr.remove(AbstractList.java:374) at java.util.AbstractCollection.remove(AbstractCollection.java:291) at collection.UnspportedTest.test(UnspportedTest.java:30) at collection.UnspportedTest.main(UnspportedTest.java:47) java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:161) at java.util.AbstractList$Itr.remove(AbstractList.java:374) at java.util.AbstractCollection.removeAll(AbstractCollection.java:373) at collection.UnspportedTest.test(UnspportedTest.java:35) at collection.UnspportedTest.main(UnspportedTest.java:47) ****不可修改**** java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection.add(Collections.java:1075) at collection.UnspportedTest.test(UnspportedTest.java:13) at collection.UnspportedTest.main(UnspportedTest.java:48) java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection.add(Collections.java:1075) at java.util.Collections.addAll(Collections.java:3845) at collection.UnspportedTest.test(UnspportedTest.java:18) at collection.UnspportedTest.main(UnspportedTest.java:48) java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection.remove(Collections.java:1078) at collection.UnspportedTest.test(UnspportedTest.java:30) at collection.UnspportedTest.main(UnspportedTest.java:48) java.lang.UnsupportedOperationException at java.util.Collections$UnmodifiableCollection.removeAll(Collections.java:1088) at collection.UnspportedTest.test(UnspportedTest.java:35) at collection.UnspportedTest.main(UnspportedTest.java:48)
本例中,test方法包含了會修改數組長度的方法。爲其傳入固定長度的容器引用,會拋出UnspportedOperationException異常。
從輸出結果可知,若在爲容器分配空間時將asList方法獲得的list經過構造方法初始化,會獲得一個尺寸可調的Collection實例,容許調用全部方法。 若直接將asList生成的list返回給容器實例,就會附加不可修改尺寸的屬性,拋出異常。 最後咱們證實了調用Collections工具類的unmodifiableCollection方法可人爲的給普通容器加上不可修改的特性,一樣會拋出UnspportedOperationException異常。
Collection接口是容器類最上層的接口之一,通常經過向上轉型的方式來實現該接口。本文針對Collection定義的基本操做,功能與用途,與Collections的關係,以及因不當操做而可能拋出的UnspportedOperationException異常進行了深刻的分析。
後續,將繼續和你們討論繼承Collection接口的List,Set,Queue 以及 Map的基本操做與機制。
做者: I'm coding
連接:ACFLOOD
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
若是您以爲本文對您有所幫助,就給俺點個贊吧!