走进Java中的持有对象(容器类)【二】Collection
概述
通过前文的学习,我们对容器的分类及常用容器类的作用有了基本的认识。本文将针对Collection容器的功能与使用进行细致分析。
基本操作
Collection集合抽象出的目的是为存放独立元素的序列。
Collection接口定义的基本操作包含添加,移除,查找,遍历等。具体API定义如下:
abstract boolean add(E e)
abstract boolean addAll(Collection c)
abstract boolean clear()
abstract boolean contains(Object o)
abstract boolean containsAll(Collection c)
abstract boolean equals(Object o)
abstract int hashCode()
abstract boolean isEmpty()
abstract Iterator
abstract boolean retainAll(Collection<?> c)
abstract int size()
abstract Object[] toArray()
abstract
这些操作可以按照具体作用来划分,下面我们结合一些实例来理解。
添加元素
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
//使用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
Collection与Collections同属于集合类,但却完全不同。这是Java开发者非常容易混淆的内容。
Collection是集合的顶层接口,而Collections则是一个工具类。Collections提供了许多静态方法,从而能够操作集合,对集合中的元素进行排序,添加以及搜索等操作。例如:
排序
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
Collections.addAll(list, a);
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
}
输出结果
[10, 30, 20, 9, 4, 1, 50]
[1, 4, 9, 10, 20, 30, 50]
Collections中实用的方法还有很多,下面列出一些常用方法的API,本文就不再一一赘述。
public static
//随机化列表
public static void shuffle(List
//返回线程安全的collection
public static
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
Collection
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
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异常
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[] arr = {1, 3, 4};
Collection
//使用会修改容器的操作
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
Collection
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
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
如果您觉得本文对您有所帮助,就给俺点个赞吧!


浙公网安备 33010602011771号