走进Java中的持有对象(容器类)【二】Collection
2016-06-29 08:53
471 查看
概述
通过前文的学习,我们对容器的分类及常用容器类的作用有了基本的认识。本文将针对Collection容器的功能与使用进行细致分析。基本操作
Collection集合抽象出的目的是为存放独立元素的序列。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
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<Integer> list = new ArrayList<Integer>(); 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 <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异常
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
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
如果您觉得本文对您有所帮助,就给俺点个赞吧!
相关文章推荐
- MyBatis学习总结(五)——实现关联表查询
- MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突
- 提高Java代码可重用性的三个措施
- java.io分类
- 澄清Java语言接口与继承的本质
- Java中异常机制的深入研究
- Dot NET设计模式—反射工厂
- JAVA代码编写的30条建议
- Java基础与案例开发详解の继承和多态
- JavaWeb系列——Hibernate——延迟加载(转)
- JavaWeb--Struts2——OGNL表达式
- Java面向对象概念
- java 操作 excel
- Spring简介--扫盲
- Struts2系列:(16)ActionContext
- Java中equals和==的区别
- 总结java.awt.Robot类
- myeclipse添加server library
- JAVA中GridBagLayout布局管理器应用详解
- JAVA中GridBagLayout布局管理器应用详解