1.集合的由来:

  我们学习的是面向对象的语言。而面向对象语言对事物的描述是通过对象体现的。为了方便对多个对象进行操作,我们就必须把多个对象进行存储。而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量。在我们目前所学过的知识里面,有哪些是容器类型的呢?数组和StringBuffer。但是StringBuffer的结果是一个字符串, 不一定符合我们的要求,所以我们只能选择数组,这就是对象数组。而对象数组又不能适应变化的需求。因为数组的长度是固定的。这个时候,为了适应变化的需求,java就提供了集合框架。

2.集合和数组的区别?

  1.长度的区别

    数组的长度固定,而集合的长度可变。

  2.内容不同

    数组存储的是同一种类型的元素,而集合可以存储不同类型的元素。

  3.元素的数据类型

    数组可以存储基本数据类型,也可以存储引用数据类型。

    集合只能存储引用数据类型。

3.集合继承体系的由来

  集合是存储多个元素的,但是,存储多个元素我们也是有不同需求的;比如说,我要这多个元素中不能有相同的元素。再比如说,我要这多个元素按照某种规则排序。针对不同的需求,java就提供了不同的集合类。这样呢,java就提供了很多个集合类,这多个集合类的数据结构不同。结构不同不重要,重要的是能存储数据,并且保证还能够使用这些东西,比如判断,获取等等。既然这样,这多个集合类是有共性的内容,我们把这些集合类的共性内容不断进行抽象,最终就能形成集合的继承体系结构。

4.数据结构解释

  数据的物理结构不同,即数据的存储结构不同。

5.集合继承体系的图解

6.Collection接口概述

  Collection层次结构中的根接口。Collection中存储的对象,称为Collection中的元素。一些Collection允许有重复的元素,而另一些则不允许有重复的元素。一些Collection是有序的,而另外一些则是无序的。

7.Collection的功能概述

添加功能:

  public boolean add(E e):添加一个元素

  public boolean addAll(Collection c):存储一个集合的元素

删除功能:

  public void clear():移除所有元素

  public boolean remove(E e):移除一个元素

  public boolean removeAll(Collection c):移除一个集合的元素

判断功能:

  public boolean contains(E e):判断集合中是否存在指定的元素

  public boolean containsAll(Collection c):判断集合是否包含指定的集合元素

  public boolean isEmpty():判断集合是否为空

获取功能:

  public Iterator<E> iterator():返回在此集合的元素上的迭代的迭代器

交集功能:

  public boolean retainAll(Collection c):两个集合都有的元素

长度功能

  public int size():返回集合中元素的个数

把集合转换为数组

  public Object[] toArray()

package com;import java.util.ArrayList;import java.util.Collection;/** * 集合框架  * 	 * 	集合的由来: * 		我们学习的是面向对象的语言。而面向对象语言对事物的描述是通过对象体现的。为了方便对多个对象进行操作, * 		我们就必须把多个对象进行存储。而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量。 * 		在我们目前所学过的知识里面,有哪些是容器类型的呢?数组和StringBuffer。 * 		但是StringBuffer的结果是一个字符串, 不一定符合我们的要求,所以我们只能选择数组,这就是对象数组。 * 		而对象数组又不能适应变化的需求。因为数组的长度是固定的。这个时候,为了适应变化的需求,java就提供了集合框架。 *   *  集合和数组的区别? *  	1.长度的区别 *  		数组的长度固定,而集合的长度可变。 *      2.内容不同 *          数组存储的是同一种类型的元素,而集合可以存储不同类型的元素。 *      3.元素的数据类型 *      	数组可以存储基本数据类型,也可以存储引用数据类型 *          集合只能存储引用数据类型 *           *  集合是存储多个元素的,但是,存储多个元素我们也是有不同需求的;比如说,我要这多个元素中不能有相同的元素。  *  再比如说,我要这多个元素按照某种规则排序。针对不同的需求,java就提供了不同的集合类。 *  这样呢,java就提供了很多个集合类,这多个集合类的数据结构不同。结构不同不重要,重要的是能存储数据, *  并且保证还能够使用这些东西,比如判断,获取等等。既然这样,这多个集合类是有共性的内容,我们把这些集合类的 *  共性内容不断进行抽象,最终就能形成集合的继承体系结构。 *   *  数据结构:数据的物理结构不同,即数据的存储结构不同。 *   *  Collection的功能概述 *  添加功能: *  	public boolean add(E e):添加一个元素 *  	public boolean addAll(Collection c):存储一个集合的元素 *  删除功能: *  	public void clear():移除所有元素 *  	public boolean remove(E e):移除一个元素 *  	public boolean removeAll(Collection c):移除一个集合的元素 *  判断功能: *  	public boolean contains(E e):判断集合中是否存在指定的元素 *      public boolean containsAll(Collection c):判断集合是否包含指定的集合元素 *  	public boolean isEmpty():判断集合是否为空 *  获取功能: *      public Iterator
 iterator():返回在此集合的元素上的迭代的迭代器 *  交集功能 *   public boolean retainAll(Collection c):两个集合都有的元素 *  长度功能 *   public int size():返回集合中元素的个数 *  把集合转换为数组 *   public Object[] toArray() *   *   *   *  *  */public class CollectionDemo { public static void main(String[] args) { //创建集合对象 Collection c = new ArrayList(); System.out.println(c);//[] //public boolean add(E e):添加一个元素 System.out.println(c.add("hello"));//true System.out.println(c);//[hello] c.add("world"); c.add("java"); System.out.println(c);//[hello, world, java] //public boolean contains(E e):判断集合中是否存在指定的元素 System.out.println(c.contains("hello"));//true //public boolean isEmpty():判断集合是否为空 System.out.println(c.isEmpty());//false  //public int size():返回集合中元素的个数 System.out.println(c.size());//3 //public boolean remove(E e):移除一个元素 c.remove("hello"); System.out.println(c);//[world, java] //public void clear():移除所有元素 c.clear(); System.out.println(c);//[] }}
package com;import java.util.ArrayList;import java.util.Collection;public class CollectionDemo2 {	public static void main(String[] args) {		//创建集合1		Collection c1 = new ArrayList();		c1.add("abc1");		c1.add("abc2");		c1.add("abc3");		c1.add("abc4");				//创建集合2		Collection c2 = new ArrayList();		c2.add("abc4");		c2.add("abc5");		c2.add("abc6");		c2.add("abc7");				System.out.println("c1:"+c1+",c2:"+c2);//c1:[abc1, abc2, abc3, abc4],c2:[abc4, abc5, abc6, abc7]		//public boolean addAll(Collection c)		c1.addAll(c2);		System.out.println("c1:"+c1+",c2:"+c2);//c1:[abc1, abc2, abc3, abc4, abc4, abc5, abc6, abc7],c2:[abc4, abc5, abc6, abc7]					//public boolean removeAll(Collection c) 只要有一个被移除了,就算移除		c1.removeAll(c2);		System.out.println("c1:"+c1+",c2:"+c2);//c1:[abc1, abc2, abc3],c2:[abc4, abc5, abc6, abc7]						//public boolean containsAll(Collection c)		//只有包含所有的元素,才叫包含		System.out.println("containsAll:"+c1.containsAll(c2));//containsAll:false				//public boolean retainAll(Collection c)求交集		//假设有两个集合A,B		//A对B的交集,最终的结果保存在A中,B不变		//返回值表示的是A是否发生变化		System.out.println("retainAll:"+c1.retainAll(c2));//retainAll:true		System.out.println("c1:"+c1);//c1:[]		System.out.println("c2:"+c2);//c2:[abc4, abc5, abc6, abc7]			}}

    

8.集合的遍历

package com;import java.util.ArrayList;import java.util.Collection;/** * 集合的遍历,其实就是一次获取集合章的每一个元素 * 		public Object[] toArray() 把集合转成数组,可以实现集合的遍历 * */public class CollectionDemo3 {	public static void main(String[] args) {		//创建集合对象		Collection
 c = new ArrayList
(); //添加元素 c.add("hello"); c.add("world"); c.add("java"); //遍历 //public Object[] toArray() Object[] array = c.toArray(); for (int i = 0; i < array.length; i++) { String str = (String)array[i]; System.out.print(str+" ");//hello world java  } }}
package com;/** * 学生类  * */public class Student {	private String name;	private int age;		public Student(){}	public Student(String name,int age){		this.name = name;		this.age = age;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	@Override	public String toString() {		return "Student [name=" + name + ", age=" + age + "]";	}		}package com;import java.util.ArrayList;import java.util.Collection;/** * 练习:用集合存储5个学生对象,并把学生对象进行遍历 *  * 分析: * 		1.创建学生类 * 		2.创建集合对象 * 		3.创建学生对象 * 		4.把学生添加到集合 * 		5.把集合转化成数组 * 		6.遍历数组 *	 */public class StudentDemo {	public static void main(String[] args) {		//创建集合对象		Collection
 c = new ArrayList
(); //创建学生对象 Student s1 = new Student("周星驰",35); Student s2 = new Student("风清扬",22); Student s3 = new Student("宋江",58); Student s4 = new Student("武松",63); Student s5 = new Student("马蓉",130); //把学生对象添加到集合中 c.add(s1); c.add(s2); c.add(s3); c.add(s4); c.add(s5); //把集合转换成数组 Object[] obj = c.toArray(); //遍历数组,输出学生信息 for (int i = 0; i < obj.length; i++) { System.out.println(obj[i]); } }}Student [name=周星驰, age=35]Student [name=风清扬, age=22]Student [name=宋江, age=58]Student [name=武松, age=63]Student [name=马蓉, age=130]

9.集合之迭代器

package com;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/** * public Iterator
 iterator() 迭代器,专门用于遍历集合的方式 * */public class CollectionDemo1 { public static void main(String[] args) { //创建集合对象 Collection
 c = new ArrayList
(); //添加元素 c.add("hello"); c.add("world"); c.add("java"); //使用迭代器进行迭代 for (Iterator
  iteraotr = c.iterator(); iteraotr.hasNext(); ) { String value = iteraotr.next(); System.out.println(value); } }}helloworldjava
package com;/** * 学生类  * */public class Student {	private String name;	private int age;		public Student(){}	public Student(String name,int age){		this.name = name;		this.age = age;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	@Override	public String toString() {		return "Student [name=" + name + ", age=" + age + "]";	}		}package com;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/** *	练习:用集合存储5个学生对象,并把学生对象进行遍历,用迭代进行比那里  * */public class CollectionDemo4 {	public static void main(String[] args) {		//创建集合对象		Collection
 c = new ArrayList
(); //创建学生对象 Student s1 = new Student("周星驰",35); Student s2 = new Student("风清扬",22); Student s3 = new Student("宋江",58); Student s4 = new Student("武松",63); Student s5 = new Student("马蓉",130); //把学生对象存储到集合之中 c.add(s1); c.add(s2); c.add(s3); c.add(s4); c.add(s5); //使用迭代器进行迭代 for (Iterator
 iterator = c.iterator();iterator.hasNext(); ) { Student stu = iterator.next(); System.out.println(stu); } }}Student [name=周星驰, age=35]Student [name=风清扬, age=22]Student [name=宋江, age=58]Student [name=武松, age=63]Student [name=马蓉, age=130]

10.迭代器原理

  迭代器,是遍历集合的一种方式。

  迭代器是依赖于集合而存在的。

 集合的使用步骤

    1.创建集合对象

    2.创建元素对象

    3.把元素添加到集合

    4.遍历集合

      4.1通过集合对象获取迭代器对象

      4.2通过迭代器对象的hasNext()方法判断是否有元素

      4.3通过迭代器对象的next()方法获取元素并移动到下一个位置

 为什么迭代器不定义成一个类,而定义成一个接口?

    假设迭代器定义的是一个类,这样我们就可以创建该类的对象,调用该类的方法来实现集合的遍历。但是,我们知道,java提供了很多的集合类,而这些集合类的数据结构是不同的,所以,存储的方式和遍历的方式应该是不同的。进而它们的遍历方式也不一样的,最终,就没有迭代器类。

    而无论你是哪种集合,你都应该具备获取元素的操作,并且,最好有辅助于判断功能。这样,在获取前,先判断。这样就更不容易出错。也就是说,判断和获取功能应该是一个集合遍历所具备,而每个集合的方式又不太一样,所以我们把判断和获取的功能提取出来,兵不提取具体实现,这种方式就是接口。

    那么,真正的具体的实现类在哪里?在真正的具体的子类中。以内部类的方式体现的。

  

  那么我们可以从源代码中来看是否和上面分析的一样呢?欲知后事如何,且看下面分解。

package java.util;import java.util.function.Predicate;import java.util.stream.Stream;import java.util.stream.StreamSupport;public interface Collection
 extends Iterable
 {    int size();    boolean isEmpty();    boolean contains(Object o);    Iterator
 iterator();//获取迭代器接口    Object[] toArray();    
 T[] toArray(T[] a);    boolean add(E e);    boolean remove(Object o);    boolean containsAll(Collection
 c);    boolean addAll(Collection
 c);    boolean removeAll(Collection
 c);    default boolean removeIf(Predicate
 filter) {        Objects.requireNonNull(filter);        boolean removed = false;        final Iterator
 each = iterator();        while (each.hasNext()) {            if (filter.test(each.next())) {                each.remove();                removed = true;            }        }        return removed;    }    boolean retainAll(Collection
 c);    void clear();    boolean equals(Object o);    int hashCode();     @Override    default Spliterator
 spliterator() {        return Spliterators.spliterator(this, 0);    }      default Stream
 stream() {        return StreamSupport.stream(spliterator(), false);    }    default Stream
 parallelStream() {        return StreamSupport.stream(spliterator(), true);    }}

从上面我们知道Collection接口继承了Iterable接口,并且在Collection接口中有获取迭代器接口的方法。

Iterator
 iterator();//获取迭代器接口

因为Collection接口继承了Iterable接口,所以可以推测在Iterable接口中也有一个获取迭代器接口的方法。因为接口是不能有实现方法的。

那么下面我们去看Iterable接口的源码。

package java.lang;import java.util.Iterator;import java.util.Objects;import java.util.Spliterator;import java.util.Spliterators;import java.util.function.Consumer;public interface Iterable
 {    Iterator
 iterator();//获取迭代器的接口的方法    default void forEach(Consumer
 action) {        Objects.requireNonNull(action);        for (T t : this) {            action.accept(t);        }    }    default Spliterator
 spliterator() {        return Spliterators.spliteratorUnknownSize(iterator(), 0);    }}

我们可以看到,在Iterable接口中有获取迭代器接口的方法。

而Iterable接口是没有父接口的,那么现在我们去看一下Iterator接口吧,看看它有什么方法

package java.util;import java.util.function.Consumer;public interface Iterator
 {    boolean hasNext();//判断是否包含下一个元素    E next();//获取下一个元素的值    default void remove() {        throw new UnsupportedOperationException("remove");    }    default void forEachRemaining(Consumer
 action) {        Objects.requireNonNull(action);        while (hasNext())            action.accept(next());    }}

我们可以看出在Iterator接口中有我们经常用的方法,

    boolean hasNext();//判断是否包含下一个元素    E next();//获取下一个元素的值

那么现在我们去看一下Collection的子接口List接口

/* * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.package java.util;public interface List
 extends Collection
 {    int size();    boolean isEmpty();    boolean contains(Object o);    Iterator
 iterator();//获取迭代器接口    Object[] toArray();    
 T[] toArray(T[] a);    boolean add(E e);    boolean remove(Object o);    boolean containsAll(Collection
 c);    boolean addAll(Collection
 c);    boolean addAll(int index, Collection
 c);    boolean removeAll(Collection
 c);    boolean retainAll(Collection
 c);    void clear();    boolean equals(Object o);    int hashCode();    E get(int index);          E set(int index, E element);    void add(int index, E element);    E remove(int index);    int indexOf(Object o);    int lastIndexOf(Object o);    ListIterator
 listIterator();    ListIterator
 listIterator(int index);    List
 subList(int fromIndex, int toIndex);}

那么我们可以看出在List接口中也有一个获取迭代器接口的方法,why?当然因为List接口继承了Collection啦,而Collection接口中就有一个获取迭代器接口的方法。

Iterator
 iterator();//获取迭代器接口

到现在距离我们推测的应该很接近了,下面我们看看List接口的实现类ArrayList吧。看一下是否和我们推测的差不多。

package java.util;public class ArrayList
 extends AbstractList
        implements List
, RandomAccess, Cloneable, java.io.Serializable{    private static final long serialVersionUID = 8683452581122892189L;    private static final int DEFAULT_CAPACITY = 10;    private static final Object[] EMPTY_ELEMENTDATA = {};    private transient Object[] elementData;    private int size;    public ArrayList(int initialCapacity) {        super();        if (initialCapacity < 0)            throw new IllegalArgumentException("Illegal Capacity: "+                                               initialCapacity);        this.elementData = new Object[initialCapacity];    }    public ArrayList() {        super();        this.elementData = EMPTY_ELEMENTDATA;    }    public ArrayList(Collection
 c) {        elementData = c.toArray();        size = elementData.length;        // c.toArray might (incorrectly) not return Object[] (see 6260652)        if (elementData.getClass() != Object[].class)            elementData = Arrays.copyOf(elementData, size, Object[].class);    }    public void trimToSize() {        modCount++;        if (size < elementData.length) {            elementData = Arrays.copyOf(elementData, size);        }    }    public void ensureCapacity(int minCapacity) {        int minExpand = (elementData != EMPTY_ELEMENTDATA)            // any size if real element table            ? 0            // larger than default for empty table. It's already supposed to be            // at default size.            : DEFAULT_CAPACITY;        if (minCapacity > minExpand) {            ensureExplicitCapacity(minCapacity);        }    }    private void ensureCapacityInternal(int minCapacity) {        if (elementData == EMPTY_ELEMENTDATA) {            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);        }        ensureExplicitCapacity(minCapacity);    }    private void ensureExplicitCapacity(int minCapacity) {        modCount++;        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);    }    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;    private void grow(int minCapacity) {        // overflow-conscious code        int oldCapacity = elementData.length;        int newCapacity = oldCapacity + (oldCapacity >> 1);        if (newCapacity - minCapacity < 0)            newCapacity = minCapacity;        if (newCapacity - MAX_ARRAY_SIZE > 0)            newCapacity = hugeCapacity(minCapacity);        // minCapacity is usually close to size, so this is a win:        elementData = Arrays.copyOf(elementData, newCapacity);    }    private static int hugeCapacity(int minCapacity) {        if (minCapacity < 0) // overflow            throw new OutOfMemoryError();        return (minCapacity > MAX_ARRAY_SIZE) ?            Integer.MAX_VALUE :            MAX_ARRAY_SIZE;    }    public int size() {        return size;    }    public boolean isEmpty() {        return size == 0;    }    public boolean contains(Object o) {        return indexOf(o) >= 0;    }    public int indexOf(Object o) {        if (o == null) {            for (int i = 0; i < size; i++)                if (elementData[i]==null)                    return i;        } else {            for (int i = 0; i < size; i++)                if (o.equals(elementData[i]))                    return i;        }        return -1;    }    public int lastIndexOf(Object o) {        if (o == null) {            for (int i = size-1; i >= 0; i--)                if (elementData[i]==null)                    return i;        } else {            for (int i = size-1; i >= 0; i--)                if (o.equals(elementData[i]))                    return i;        }        return -1;    }    public Object clone() {        try {            @SuppressWarnings("unchecked")                ArrayList
 v = (ArrayList
) super.clone();            v.elementData = Arrays.copyOf(elementData, size);            v.modCount = 0;            return v;        } catch (CloneNotSupportedException e) {            // this shouldn't happen, since we are Cloneable            throw new InternalError();        }    }    public Object[] toArray() {        return Arrays.copyOf(elementData, size);    }    @SuppressWarnings("unchecked")    public 
 T[] toArray(T[] a) {        if (a.length < size)            // Make a new array of a's runtime type, but my contents:            return (T[]) Arrays.copyOf(elementData, size, a.getClass());        System.arraycopy(elementData, 0, a, 0, size);        if (a.length > size)            a[size] = null;        return a;    }    @SuppressWarnings("unchecked")    E elementData(int index) {        return (E) elementData[index];    }    public E get(int index) {        rangeCheck(index);        return elementData(index);    }    public E set(int index, E element) {        rangeCheck(index);        E oldValue = elementData(index);        elementData[index] = element;        return oldValue;    }    public boolean add(E e) {        ensureCapacityInternal(size + 1);  // Increments modCount!!        elementData[size++] = e;        return true;    }    public void add(int index, E element) {        rangeCheckForAdd(index);        ensureCapacityInternal(size + 1);  // Increments modCount!!        System.arraycopy(elementData, index, elementData, index + 1,                         size - index);        elementData[index] = element;        size++;    }    public E remove(int index) {        rangeCheck(index);        modCount++;        E oldValue = elementData(index);        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null;         return oldValue;    }    public boolean remove(Object o) {        if (o == null) {            for (int index = 0; index < size; index++)                if (elementData[index] == null) {                    fastRemove(index);                    return true;                }        } else {            for (int index = 0; index < size; index++)                if (o.equals(elementData[index])) {                    fastRemove(index);                    return true;                }        }        return false;    }    private void fastRemove(int index) {        modCount++;        int numMoved = size - index - 1;        if (numMoved > 0)            System.arraycopy(elementData, index+1, elementData, index,                             numMoved);        elementData[--size] = null; // clear to let GC do its work    }    public void clear() {        modCount++;        for (int i = 0; i < size; i++)            elementData[i] = null;        size = 0;    }    public boolean addAll(Collection
 c) {        Object[] a = c.toArray();        int numNew = a.length;        ensureCapacityInternal(size + numNew);  // Increments modCount        System.arraycopy(a, 0, elementData, size, numNew);        size += numNew;        return numNew != 0;    }    public boolean addAll(int index, Collection
 c) {        rangeCheckForAdd(index);        Object[] a = c.toArray();        int numNew = a.length;        ensureCapacityInternal(size + numNew);  // Increments modCount        int numMoved = size - index;        if (numMoved > 0)            System.arraycopy(elementData, index, elementData, index + numNew,                             numMoved);        System.arraycopy(a, 0, elementData, index, numNew);        size += numNew;        return numNew != 0;    }    protected void removeRange(int fromIndex, int toIndex) {        modCount++;        int numMoved = size - toIndex;        System.arraycopy(elementData, toIndex, elementData, fromIndex,                         numMoved);        int newSize = size - (toIndex-fromIndex);        for (int i = newSize; i < size; i++) {            elementData[i] = null;        }        size = newSize;    }    private void rangeCheck(int index) {        if (index >= size)            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }    private void rangeCheckForAdd(int index) {        if (index > size || index < 0)            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));    }    private String outOfBoundsMsg(int index) {        return "Index: "+index+", Size: "+size;    }    public boolean removeAll(Collection
 c) {        return batchRemove(c, false);    }    public boolean retainAll(Collection
 c) {        return batchRemove(c, true);    }    private boolean batchRemove(Collection
 c, boolean complement) {        final Object[] elementData = this.elementData;        int r = 0, w = 0;        boolean modified = false;        try {            for (; r < size; r++)                if (c.contains(elementData[r]) == complement)                    elementData[w++] = elementData[r];        } finally {            // Preserve behavioral compatibility with AbstractCollection,            // even if c.contains() throws.            if (r != size) {                System.arraycopy(elementData, r,                                 elementData, w,                                 size - r);                w += size - r;            }            if (w != size) {                // clear to let GC do its work                for (int i = w; i < size; i++)                    elementData[i] = null;                modCount += size - w;                size = w;                modified = true;            }        }        return modified;    }    private void writeObject(java.io.ObjectOutputStream s)        throws java.io.IOException{        int expectedModCount = modCount;        s.defaultWriteObject();        s.writeInt(size);        for (int i=0; i
 0) {            // be like clone(), allocate array based upon size not capacity            ensureCapacityInternal(size);            Object[] a = elementData;            // Read in all elements in the proper order.            for (int i=0; i
 listIterator(int index) {        if (index < 0 || index > size)            throw new IndexOutOfBoundsException("Index: "+index);        return new ListItr(index);    }    public ListIterator
 listIterator() {        return new ListItr(0);    }    public Iterator
 iterator() {//1.这边就是实现父接口的抽象方法        return new Itr();//2.这边是new的Iterator的子类,那么这个Itr是什么鬼,内部类啊    }    //3.看这里,是不是,内部类实现了Iterator接口,那么就是意味着每个子类,    //比如ArrayList,LinkedList应该都有类似的实现啦,太厉害了,jdk的作者大神,膜拜吧    private class Itr implements Iterator
 {        int cursor;       // index of next element to return        int lastRet = -1; // index of last element returned; -1 if no such        int expectedModCount = modCount;        public boolean hasNext() {            return cursor != size;        }        @SuppressWarnings("unchecked")        public E next() {            checkForComodification();            int i = cursor;            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];        }        public void remove() {            if (lastRet < 0)                throw new IllegalStateException();            checkForComodification();            try {                ArrayList.this.remove(lastRet);                cursor = lastRet;                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }        final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();        }    }    private class ListItr extends Itr implements ListIterator
 {        ListItr(int index) {            super();            cursor = index;        }        public boolean hasPrevious() {            return cursor != 0;        }        public int nextIndex() {            return cursor;        }        public int previousIndex() {            return cursor - 1;        }        @SuppressWarnings("unchecked")        public E previous() {            checkForComodification();            int i = cursor - 1;            if (i < 0)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i;            return (E) elementData[lastRet = i];        }        public void set(E e) {            if (lastRet < 0)                throw new IllegalStateException();            checkForComodification();            try {                ArrayList.this.set(lastRet, e);            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }        public void add(E e) {            checkForComodification();            try {                int i = cursor;                ArrayList.this.add(i, e);                cursor = i + 1;                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }    }       public List
 subList(int fromIndex, int toIndex) {        subListRangeCheck(fromIndex, toIndex, size);        return new SubList(this, 0, fromIndex, toIndex);    }    static void subListRangeCheck(int fromIndex, int toIndex, int size) {        if (fromIndex < 0)            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);        if (toIndex > size)            throw new IndexOutOfBoundsException("toIndex = " + toIndex);        if (fromIndex > toIndex)            throw new IllegalArgumentException("fromIndex(" + fromIndex +                                               ") > toIndex(" + toIndex + ")");    }    private class SubList extends AbstractList
 implements RandomAccess {        private final AbstractList
 parent;        private final int parentOffset;        private final int offset;        int size;        SubList(AbstractList
 parent,                int offset, int fromIndex, int toIndex) {            this.parent = parent;            this.parentOffset = fromIndex;            this.offset = offset + fromIndex;            this.size = toIndex - fromIndex;            this.modCount = ArrayList.this.modCount;        }        public E set(int index, E e) {            rangeCheck(index);            checkForComodification();            E oldValue = ArrayList.this.elementData(offset + index);            ArrayList.this.elementData[offset + index] = e;            return oldValue;        }        public E get(int index) {            rangeCheck(index);            checkForComodification();            return ArrayList.this.elementData(offset + index);        }        public int size() {            checkForComodification();            return this.size;        }        public void add(int index, E e) {            rangeCheckForAdd(index);            checkForComodification();            parent.add(parentOffset + index, e);            this.modCount = parent.modCount;            this.size++;        }        public E remove(int index) {            rangeCheck(index);            checkForComodification();            E result = parent.remove(parentOffset + index);            this.modCount = parent.modCount;            this.size--;            return result;        }        protected void removeRange(int fromIndex, int toIndex) {            checkForComodification();            parent.removeRange(parentOffset + fromIndex,                               parentOffset + toIndex);            this.modCount = parent.modCount;            this.size -= toIndex - fromIndex;        }        public boolean addAll(Collection
 c) {            return addAll(this.size, c);        }        public boolean addAll(int index, Collection
 c) {            rangeCheckForAdd(index);            int cSize = c.size();            if (cSize==0)                return false;            checkForComodification();            parent.addAll(parentOffset + index, c);            this.modCount = parent.modCount;            this.size += cSize;            return true;        }        public Iterator
 iterator() {            return listIterator();        }        public ListIterator
 listIterator(final int index) {            checkForComodification();            rangeCheckForAdd(index);            final int offset = this.offset;            return new ListIterator
() {                int cursor = index;                int lastRet = -1;                int expectedModCount = ArrayList.this.modCount;                public boolean hasNext() {                    return cursor != SubList.this.size;                }                @SuppressWarnings("unchecked")                public E next() {                    checkForComodification();                    int i = cursor;                    if (i >= SubList.this.size)                        throw new NoSuchElementException();                    Object[] elementData = ArrayList.this.elementData;                    if (offset + i >= elementData.length)                        throw new ConcurrentModificationException();                    cursor = i + 1;                    return (E) elementData[offset + (lastRet = i)];                }                public boolean hasPrevious() {                    return cursor != 0;                }                @SuppressWarnings("unchecked")                public E previous() {                    checkForComodification();                    int i = cursor - 1;                    if (i < 0)                        throw new NoSuchElementException();                    Object[] elementData = ArrayList.this.elementData;                    if (offset + i >= elementData.length)                        throw new ConcurrentModificationException();                    cursor = i;                    return (E) elementData[offset + (lastRet = i)];                }                public int nextIndex() {                    return cursor;                }                public int previousIndex() {                    return cursor - 1;                }                public void remove() {                    if (lastRet < 0)                        throw new IllegalStateException();                    checkForComodification();                    try {                        SubList.this.remove(lastRet);                        cursor = lastRet;                        lastRet = -1;                        expectedModCount = ArrayList.this.modCount;                    } catch (IndexOutOfBoundsException ex) {                        throw new ConcurrentModificationException();                    }                }                public void set(E e) {                    if (lastRet < 0)                        throw new IllegalStateException();                    checkForComodification();                    try {                        ArrayList.this.set(offset + lastRet, e);                    } catch (IndexOutOfBoundsException ex) {                        throw new ConcurrentModificationException();                    }                }                public void add(E e) {                    checkForComodification();                    try {                        int i = cursor;                        SubList.this.add(i, e);                        cursor = i + 1;                        lastRet = -1;                        expectedModCount = ArrayList.this.modCount;                    } catch (IndexOutOfBoundsException ex) {                        throw new ConcurrentModificationException();                    }                }                final void checkForComodification() {                    if (expectedModCount != ArrayList.this.modCount)                        throw new ConcurrentModificationException();                }            };        }        public List
 subList(int fromIndex, int toIndex) {            subListRangeCheck(fromIndex, toIndex, size);            return new SubList(this, offset, fromIndex, toIndex);        }        private void rangeCheck(int index) {            if (index < 0 || index >= this.size)                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));        }        private void rangeCheckForAdd(int index) {            if (index < 0 || index > this.size)                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));        }        private String outOfBoundsMsg(int index) {            return "Index: "+index+", Size: "+this.size;        }        private void checkForComodification() {            if (ArrayList.this.modCount != this.modCount)                throw new ConcurrentModificationException();        }    }}

我们可以看到这样的代码

public Iterator
 iterator() {//1.这边就是实现父接口的抽象方法        return new Itr();//2.这边是new的Iterator的子类,那么这个Itr是什么鬼,内部类啊    }    //3.看这里,是不是,内部类实现了Iterator接口,那么就是意味着每个子类,    //比如ArrayList,LinkedList应该都有类似的实现啦,太厉害了,jdk的作者大神,膜拜吧    private class Itr implements Iterator
 {        int cursor;       // index of next element to return        int lastRet = -1; // index of last element returned; -1 if no such        int expectedModCount = modCount;        public boolean hasNext() {            return cursor != size;        }        @SuppressWarnings("unchecked")        public E next() {            checkForComodification();            int i = cursor;            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];        }        public void remove() {            if (lastRet < 0)                throw new IllegalStateException();            checkForComodification();            try {                ArrayList.this.remove(lastRet);                cursor = lastRet;                lastRet = -1;                expectedModCount = modCount;            } catch (IndexOutOfBoundsException ex) {                throw new ConcurrentModificationException();            }        }        final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();        }    }

那么到了这里,就和我们推测的一样了。

那么图解如下所示

11.练习

  11.1存储字符串并遍历

package com;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/** *	需求:存储字符串并遍历 *	分析: *		1.创建集合对象 *      2.创建字符串对象 *      3.把字符串对象添加到集合中 *      4.遍历集合  */public class CollectionTest {	public static void main(String[] args) {		//创建集合对象		Collection
 c = new ArrayList
(); //创建字符串对象 String s1 = "hello"; String s2 = "world"; String s3 = "java"; //把字符串对象添加到集合中 c.add(s1); c.add(s2); c.add(s3); //遍历集合 方式一,将集合转换为数组,再遍历// String[] strs = (String[]) c.toArray();// for (int i = 0; i < strs.length; i++) {// System.out.println(strs[i]);// }// 上面的这种方式是错误的,因为Object[]怎么可以转换成String[]数组呢// 何况在Collection中的toArray()的定义是这样的/** *  Object[] toArray(); */ //所以,只能先将集合转换为Object数组,然后通过for循环将每个元素取出来, //再转换为String Object[] obj = c.toArray(); for (int i = 0; i < obj.length; i++) { String str = (String)obj[i]; System.out.println(str); } //遍历集合方式二:直接通过迭代器的方式输出数组 for (Iterator
 iterator = c.iterator(); iterator.hasNext(); ) { String str = iterator.next(); System.out.println(str); } }}

  11.2存储学生对象并遍历

package com;/** * 学生类  * */public class Student {	private String name;	private int age;		public Student(){}	public Student(String name,int age){		this.name = name;		this.age = age;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	@Override	public String toString() {		return "Student [name=" + name + ", age=" + age + "]";	}		}package com;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;/** * 练习:用集合存储5个学生对象,并把学生对象进行遍历 *  * 分析: * 		1.创建学生类 * 		2.创建集合对象 * 		3.创建学生对象 * 		4.把学生添加到集合 * 		5.把集合转化成数组 * 		6.遍历数组 *	 */public class StudentDemo {	public static void main(String[] args) {		//创建集合对象		Collection
 c = new ArrayList
(); //创建学生对象 Student s1 = new Student("周星驰",35); Student s2 = new Student("风清扬",22); Student s3 = new Student("宋江",58); Student s4 = new Student("武松",63); Student s5 = new Student("马蓉",130); //把学生对象添加到集合中 c.add(s1); c.add(s2); c.add(s3); c.add(s4); c.add(s5); //把集合转换成数组 Object[] obj = c.toArray(); //遍历集合方式一,输出学生信息 for (int i = 0; i < obj.length; i++) { System.out.println(obj[i]); } //遍历集合方式二:通过迭代器 for (Iterator
 iterator = c.iterator(); iterator.hasNext(); ) { Student student = iterator.next(); System.out.println(student); } }}