Java学习(集合框架,Collection接口,迭代器Iterator)

一.集合框架(单列集合)

1.概述

​ 集合:长度可变;只能存储引用数据类型,即使存储了基本类型,到了集合中也会自动装箱成包装类;集合有很多方法,直接操作元素

2.分类

  • 单列集合:元素只由一部分构成
    • list.add(“abc”)
  • 双列集合:一个元素由两部分构成
    • (key,value) ->(键,值) ->键值对
    • map.put(1,“zsy”);

3.与数组区别

​ 数组定长,集合不定长,都是一次存储多个数据,在数组中添加数据,如果数组长度不够,需要创建新数组,将老数组复制过来,最后添加新元素,很麻烦,而集合直接添加就行

4.集合框架

在这里插入图片描述

二.Collection接口

​ 单列集合顶级接口

创建:
Collection<E> 集合名 = new 实现类对象<E>() <E>:泛型

​ 泛型:规定集合中元素的数据类型,统一类型的;泛型类型只能写引用类型,不能写基本类型,如果不写泛型,默认为Object类型

<String>  元素为字符串
<Integer> 元素为整数
<Person>  元素为Person对象
<Double>  元素为double型小数

常用方法:

1.boolean add(E e) : 将给定的元素添加到当前集合中(一般调add时,不用boolean接收,因为add一定会成功)
2.boolean addAll(Collection<? extends E> c) :将另一个集合元素添加到当前集合中 (集合合并)
3.void clear():清除集合中所有的元素
4.boolean contains(Object o) :判断当前集合中是否包含指定的元素
5.boolean isEmpty() : 判断当前集合中是否有元素->判断集合是否为空
6.boolean remove(Object o):将指定的元素从集合中删除
7.int size() :返回集合中的元素个数。
8.Object[] toArray(): 把集合中的元素,存储到数组中

public class Demo01 {
    public static void main(String[] args) {
        Collection<String> collection1 = new ArrayList<>();
        //add(E e)将给定的元素添加到当前集合中
        collection1.add("张三");
        collection1.add("李四");
        collection1.add("王五");
        collection1.add("赵六");
        collection1.add("刘七");
        collection1.add("陈八");
        System.out.println(collection1);
        //addAll(Collection<? extends E> c)将另一个集合元素添加到当前集合中 (集合合并)
        ArrayList<String> collection2 = new ArrayList<>();
        collection2.addAll(collection1);
        System.out.println(collection2);
        //void clear():清除集合中所有的元素
        collection2.clear();
        System.out.println(collection2);
        //boolean contains(Object o)  :判断当前集合中是否包含指定的元素
        boolean s = collection1.contains("赵六");
        System.out.println(s);
        //boolean isEmpty() : 判断当前集合中是否有元素->判断集合是否为空
        boolean empty = collection1.isEmpty();
        System.out.println(empty);
        //boolean remove(Object o):将指定的元素从集合中删除
        collection1.remove("陈八");
        System.out.println(collection1);
        //int size() :返回集合中的元素个数。
        int size = collection1.size();
        System.out.println(size);
        //Object[] toArray(): 把集合中的元素,存储到数组中
        Object[] arr = collection1.toArray();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

三.迭代器Iterator

1.概述

Iterator接口

获取:

Collection中的方法: -> 只要是Collection的实现类都可以用iterator获取迭代器对象,遍历

Iterator iterator()

方法:

boolean hasNext() -> 判断集合中有没有下一个元素
E next() -> 获取下一个元素

public class Demo02 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        //获取Iterator
        Iterator<String> iterator = list.iterator();

        while(iterator.hasNext()){//判断有没有下一个元素;boolean hasNext()
            String element = iterator.next();//如果有获取下一个元素给element; E next()
            System.out.println(element);
        }
    }
}

注意:在迭代的过程中,不要连续调用多次next方法

如下例子:

public class Demo03 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("田七");
        list.add("王五");
        list.add("李四");
        list.add("赵六");

        //获取iterator
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
            System.out.println(iterator.next());
        }
    }
}

在这里插入图片描述

会出现没有可操作的元素异常NoSuchElementException

2.迭代器迭代过程

3.迭代器底层原理

ArrayList<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();

list.iterator方法调用之后被Iterator接口类型接受了,那么Iterator接受的肯定是实现类对象

例如:使用ArrayList集合做迭代时,Iterator接口接收的是ArrayList的内部类Itr

Iterator指向Itr这个实现类,只有在遍历ArrayList时才是,其他的集合在迭代的时候Iterator接收的是其他的实现类对象,比如HashSet

4.并发修改异常

​ 在使用迭代器的过程中随意修改集合长度,就会报"并发修改异常ConcurrentModificationException

​ 例如:定义一个集合,存储"张三",“李四”,“王五”,“田七”,迭代元素,如果迭代到王五,就添加"赵六"

public class Demo04 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("田七");

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            if ("王五".equals(element)) {
                list.add("赵六");
            }
        }
        System.out.println(list);
    }
}

​ 底层报错原理:实际操作次数和预期操作次数不相等时,抛异常,刚开始,实际操作次数和预期操作次数是相等的,但是我们调用了add方法,add方法底层只给实际操作次数加1了,并没有重新给预期操作次数加1,此时再调用next方法,底层实际操作次数和预期操作次数不相等了,所以抛出了"并发修改异常"

Iterator<String> iterator = list.iterator();

String element = iterator.next();
=================================================
 private class Itr implements Iterator<E> {
        /*
          expectedModCount:预期操作次数
          modCount:实际操作次数
        */
        int expectedModCount = modCount; 
        public E next() {
            checkForComodification(); 
        }  
     
        final void checkForComodification() {
            if (modCount != expectedModCount)//如果实际操作次数和预期操作次数不相等,抛异常
                throw new ConcurrentModificationException();
        }
list.add("赵六");
======================================
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
} 

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
}

解决:ListIterator listIterator()

public class Demo05 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("田七");

        ListIterator<String> stringListIterator = list.listIterator();
        while (stringListIterator.hasNext()) {
            String element = stringListIterator.next();
            if ("王五".equals(element)) {
                stringListIterator.add("赵六");
            }
        }
        System.out.println(list);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值