集合(Collection ArrayList LinkedList 泛型) 1

数组对象

数组是容器,即可以存储基本数据类型也可以存储引用数据类型,存储了引用数据类型的数组成为对象数组,如:String【】、Person【】、Student【】

public static void main(String[] args) {
        //创建存储Person对象的数组
        Person[] person = {
                new Person("张三",20),
                new Person("李四",30),
                new Person("王五",28),
        };
        //遍历数组
        for (int i = 0; i <person.length ; i++) {
            Person person = person[i];
            System.out.println(person.getName()+"::"+person.getAge());
        }
    }

数组弊端:

  • 数组长度是固定的,一旦创建不可修改需要
  • 需要添加元素,只能创建新数组,将数组中的元素进行复制

为了解决数组的定长问题,Java语言从JDK1.2后开始出现集合框架

Collection集合

  • 集合:集合是Java中提供的一种容器,可以用来存储多个数据

集合和数组都是容器,有什么区别?

  • 数组的长度是固定的,集合的长度是可变的
  • 数组中存储的是同一类型的元素,可以存储任意类型数据。集合存储的都是引用数据类型,如果想存储基本类型数据需要存储相应的包装类型

集合类的继承关系

Collection:单列集合类的根接口,用于存储一系列符合某种规则的元素,它有两个重要的子接口,分别是 java.util.List java.util.Set 。其中, List 的特点是元素有序、元素可重复。 Set 的特点是元素不可重复。 List 接口的主要实现类有 java.util.ArrayList java.util.LinkedList Set 接口的主要实现类有 java.util.HashSet java.util.LinkedHashSet
         
 
注意 : 这张图只是我们常用的集合有这些,不是说就只有这些集合。
集合本身是一个工具,它存放在 java.util 包中。在 Collection 接口定义着单列集合框架中最最共性的内容。

Collection接口方法

Collection是所有单列集合的父类接口,因此Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。方法如下:

public boolean add(E e):把给定的对象添加到当前集合中 。
public boolean addAll(Collection<? extends E>) 将另一个集合元素添加到当前集合中。
public void clear() : 清空集合中所有的元素。
public boolean remove(E e) : 把给定的对象在当前集合中删除。
public boolean contains(Object obj) : 判断当前集合中是否包含给定的对象。
public boolean isEmpty() : 判断当前集合是否为空。
public int size() : 返回集合中元素的个数。
public Object[] toArray() : 把集合中的元素,存储到数组中。
 

迭代器 Iterator接口

在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口 java.util.Iterator

想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:public Iterator iterator() : 获取集合对应的迭代器,用来遍历集合中的元素的。

 
迭代 :即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
 
Iterator 接口的常用方法如下:
public E next() : 返回迭代的下一个元素。
public boolean hasNext() : 如果仍有元素可以迭代,则返回 true
接下来我们通过案例学习如何使用 Iterator 迭代集合中元素:
public static void main(String[] args) {
        //使用多态方式创建对象
        Collection<String > coll = new ArrayList<String>();
        //添加元素到集合
        coll.add("串串");
        coll.add("脱口秀");
        coll.add("汪汪队");
        //遍历
        //使用迭代器遍历 每个集合对象都有自己的迭代器
        Iterator<String> it = coll.iterator();
        //泛型指的是 迭代出元素的数据类型
        while(it.hasNext()){//判断是否有迭代元素
            String s = it.next();//获取迭代出的元素
            System.out.println(s);
        }
    }

迭代器的实现原理

之前的案例完成了 Iterator 遍历集合的整个过程。当遍历集合时,首先通过调用 t 集合的 iterator()方法获得迭代器对象,然后使用 hashNext() 方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,为了让初学者能更好地理解迭代器的工作原理,接下来通过一个图例来演示 Iterator 对象迭代元素的过程:
           
在调用 Iterator next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next 方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用 next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到 hasNext 方法返回 false,表示到达了集合的末尾,终止对元素的遍历。

并发修改异常

使用迭代器遍历集合中,不能使用集合本身的方法改变集合的长度,一旦被改变将会抛出ConcurrentModificationException并发修改异常。

 public static void main(String[] args) {
        Collection<String> coll = new ArrayList<String >();
        coll.add("hello1");
        coll.add("hello2");
        coll.add("hello3");
        coll.add("hello4");
        Iterator<String> it = coll.iterator();
        while(it.hasNext()){
            String str = it.next();
            if("hello2".equals(str)){
                coll.add("hello5");
            }
        }
    }

运行结果:

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
	at java.util.ArrayList$Itr.next(ArrayList.java:859)
	at wensong.CollectionTest.IteratorException.main(IteratorException.java:16)

Process finished with exit code 1
以上程序,在迭代器遍历过程中,使用了集合 add方法修改集合的长度,这个操作是不允许的,被禁止的,程序中会抛出并发修改异常。
注意 :如果我们使用集合的 remove()方法同样会抛出并发修改异常,但是删除倒数第二个元素则不会抛出异常。
原因:抛出并发修改异常的方法是迭代器的 next() 方法,当删除倒数第二个元素后,本次循环结束,再次执行 while循环时,此时条件为 false ,循环停止,没有再执行 next() 方法,所以没有异常抛出。
 

猜你喜欢

转载自blog.csdn.net/weixin_40959890/article/details/107237522