zoukankan      html  css  js  c++  java
  • 走进Java中的持有对象(容器类)【二】Collection

    概述


    通过前文的学习,我们对容器的分类常用容器类的作用有了基本的认识。本文将针对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接口似乎没有对访问指定位置元素,遍历列表提供合适的方法。containsequals两种方法可查找元素,却也无法实现迭代,遍历元素的目的。

    这时就需要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

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    如果您觉得本文对您有所帮助,就给俺点个赞吧!

  • 相关阅读:
    background image position问题
    yii 验证器和验证码
    laravel 模板 blade
    tbody添加垂直滚动条
    转:jquery选择器总结
    jquery ajax传递数组给php
    jquery serialize()、serializearray()已经$.param方法
    php stdClass Object 问题
    Codeforces Round #274 (Div. 2) E. Riding in a Lift(DP)
    HTTP协议具体解释
  • 原文地址:https://www.cnblogs.com/ACFLOOD/p/5625647.html
Copyright © 2011-2022 走看看