Java集合笔记(一):Collection和Iterator接口

Java集合主要分为四种类型:

  • Set(集):集合中的对象没有重复的对象,并且不安特定方式排序;
  • List(列表):集合中的对象按照索引位置排序,可以有重复的对象;
  • Queue(队列):集合中的对象按照先进先出的规则来排序.可以有重复的对象;
  • Map(映射):集合中的每一个元素包含一对键(Key)对象和值(Value)对象,集合中没有重复的键对象,值对象可以重复;

其中set接口与数学中的集合最接近,两者都不允许包含重复的元素.在Java API中,Collection接口表示集合,Set,List,和Queue都是Collection的子接口.而Map接口没有继承Collection接口.下图显示了Java的主要集合类的类框图.
Java的主要集合类的类框图

Collection接口的通用方法

在Collection接口中声明了适用于Java集合的通用方法(只包括Set,List,和Queue)

方法描述
Int size()返回此集合中的元素数
Boolean isEmpty()判断集合是否为空,如果此collection不包含任何元素,则返回true
Boolean contains(Object o)判断在集合中是否含指定的元素,bao则返回true
Iterator iterator()返回一个Iterator对象,可用它来遍历集合中的元素
Object[] toArray()返回一个数组,该数组包含集合中的所有元素
Boolean add(Object o)向集合中添加一个对象的引用
Boolean remove(Object o)从集合中删除一个对象的引用
Iterator iterator()返回一个Iterator对象,可用它来遍历集合中的元素
Boolean equals(Object o)对象比较
boolean containsAll(Collection<?> c)如果此集合包含所有指定集合中的元素,则返回true
boolean addAll(Collection<? extends E> c)添加所有指定集合中的元素到这个集合(可选操作)
boolean removeAll(Collection<?> c)移除所有包含在指定collection中的元素。 此调用返回后,此集合将不包含与指定集合相同的元素。
boolean retainAll(Collection<?> c)仅保留此集合中包含在指定集合中的元素
Void clear()删除集合中的所有对象,即不再持有这些对象的引用

以下为Collection的全部方法
在这里插入图片描述

Collection 的iterator方法和toArray方法都用于获得集合中的所有元素,前者返回一个Iterator对象,后者返回一个包含集合中所有元素的数组.Iterator接口隐藏底层集合的数据结构,提供了遍历各种类型的集合的统一接口,Iterator接口中声明了如下方法:

方法描述
hasNext判断集合中的元素是否遍历完毕,如果没有,则返回false
next()返回下一个元素
remove()从集合中删除由next()方法返回的当前元素

利用Iterator来遍历集合

package com.company;

import java.util.*;

public class Visitor {

    public static void print(Collection<? extends Object> c) {
        Iterator<? extends Object> it = c.iterator();
        //遍历集合中的所有元素
        while (it.hasNext()) {
            System.out.println(it.next());
        }

    }
    //同print()方法一样,都用来遍历集合,区别在于printWithForeach)使用foreach语句,简化了代码
    public static void printWithForeach(Collection<? extends Object> c) {
        for (Object element : c) {
            System.out.println(element);
        }
    }

    public static void main(String[] args) {
        HashSet<String> set = new HashSet<String>();//创建set
        set.add("Tom");
        set.add("Marry");
        set.add("Jack");
        print(set);

        ArrayList<String> list = new ArrayList<String>();//创建list
        list.add("Linda");
        list.add("Mary");
        list.add("Rose");
        print(list);

        ArrayDeque<String> quene = new ArrayDeque<String>();//创建queue
        quene.add("Tom");
        quene.add("Mike");
        quene.add("Jack");
        print(quene);

        //map.entrySet()方法返回一个集合,该集合中存放Map.Entry元素
        //每个Map.Entry元素表示一对键/值
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("M", "男");
        map.put("F", "女");
        print(map.entrySet());
        printWithForeach(set);
        printWithForeach(list);
        printWithForeach(quene);
        printWithForeach(map.entrySet());
    }
}

Tips:如果集合中的元素没有排序.Iterator遍历集合中元素的顺序是任意的,并不一定与集合中加入元素的顺序一直,

当通过Collection集合的iterator()方法得到一个Iterator对象后,如果当前线程或其他线程又通过Collection的一些方法对集合进行了修改操作,接下来访问这个Iterator对象的next()方法会导致java.util.ConcurrentModificationException运行时异常,代码如下

public class ConcurrentTester {
    public static void main(String[] args) {
        //当前线程
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
        arrayList.add("e");
        
        for (String string : arrayList) {
            if ("e".equals(string)) {
                arrayList.remove(string);
            }
        }

       //其他线程
        final int size=1000;
        final HashSet<Integer> set = new HashSet<Integer>();
        for (int i = 0; i < size; i++) {
            set.add(new Integer(i));
        }
        //负责遍历集合的线程
        Thread reader = new Thread(){
            public void run(){
                for (Integer i : set) {
                    System.out.println(i);//抛出ConcurrentModificationException异常
                    yield();//把集合让给别的线程
                }
        }};
        //负责删除集合中元素的线程
        Thread remover = new Thread(){
            public void run(){
                for (int i = 0; i < size; i++) {
                    set.remove(new Integer(i));//删除集合中的元素
                    yield();
                }

            }
        };
        reader.start();
        remover.start();
    }
}

错误信息:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at com.company.ConcurrentTester.main(ConcurrentTester.java:23)

总结:

  • Iterator对象运用了快速失败机制,一旦监测到集合已被修改,就抛出ConcurrentModificationException运行时异常,而不是显示修改后的当前内容,这可以避免潜在的由于共享资源竞争而导致的并发问题 ;
  • 增强for循环用于遍历集合,但不适合对集合进行删除操作;若想在遍历集合时删除元素,可以参阅 https://juejin.im/post/5a992a0d6fb9a028e46e17ef

在本次整理Collection方法时,使用了一个好用API文档工具: Zeal,下载安装参照:https://my.oschina.net/gaoenwei/blog/1793915

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值