Java集合框架分析(三)——List集合之ArrayList实例和Iterator迭代器源码分析

   继续之前的ArrayList分析,分析完源代码之后我们就实现一点实例来看看ArrayList中常用API的用法,不多说先上代码:

public class ArrayListDemo2 {

	public static void main(String[] args) {
		ArrayList<Object> al = new ArrayList<Object>();
		al.add(new Person("asdf", 25));
		al.add(new Person("asdf1", 32));
		al.add(new Person("asd2f", 44));
		al.add(new Person("asdf3", 12));
		al.add(new Person("asd4f", 54));
		al.add(new Person("asd4f", 54));

		al = singleElement(al);
		Iterator it = al.iterator();
		while (it.hasNext()) {

			Person p = (Person) it.next();

			sop(p.getname() + "...." + p.getage());

		}
		// 说明remove方法的底层也调用了equals方法
		sop(al.remove(new Person("asd2f", 44)));

	}

	public static ArrayList singleElement(ArrayList al) {
		ArrayList<Object> newal = new ArrayList();
		ListIterator it = al.listIterator();
		while (it.hasNext()) {
			Object obj = it.next();
			// contains的实质就是equals方法,想判断自己想要的属性要重写
			if (!newal.contains(obj))
				newal.add(obj);

		}
		return newal;
	}

	private static void sop(Object o) {

		System.out.println(o);

	}

}

class Person {

	private String name;
	private int age;

	Person(String name, int age) {
		this.name = name;
		this.age = age;

	}

	public String getname() {

		return name;
	}

	public int getage() {

		return age;
	}

	// 重写equals的方法来判断我们想要判断的对象
	public boolean equals(Object obj) {
		if (!(obj instanceof Person))
			return false;
		Person p = (Person) obj;
		// 验证判断过程
		System.out.println(this.getname() + "..." + p.name);
		return this.name.equals(p.name) && this.age == p.age;

	}

}

    这个实例中我是先创建一个ArrayList对象,在集合中添加的是Person对象,然后在集合中添加多个Person对象,添加用add方法,删除用remove方法,这些具体方法就不多做 介绍大家可以自己查询API,值得注意的是当我们想遍历元素的时候,就必须要用到Iterator这个迭代器,这个迭代器是如何实现的呢?还是从源码开始分析

public interface Iterator<E> {
   
    boolean hasNext();

   
    E next();

    void remove();
}

 可以看到Iterator是一个接口,其中只有三个方法(用Enumeration<E>枚举类也可以实现,Enumeration<E>里面只有两个方法)遍历的时候注意到这行代码(ListIterator是Iterator的加强版)

ListIterator it = al.listIterator();

我们看到al.iterator();再来看看iterator()方法:

public Iterator<E> iterator() {

return new Itr();

 

    }

很容易知道这个方法返回的是一个Itr对象,看实例代码我们知道一般依赖hasNext()和next()方法就能完成遍历,但是这里我们深入分析下Itr对象,同样来看源码,这里我们将源码分段分析

private class Itr implements Iterator<E> {
	
	int cursor = 0;

	int lastRet = -1;

	int expectedModCount = modCount;
}

 我们可以看到Itr内部类中有三个int变量 cursor表示下一次调用next()游标或者说是指针指向的位置,初始是0,lastRet是上一次的位置(所以总是比cursor少一)。expectedModCount表示期待的modCount值,用来判断在遍历过程中集合是否被修改过。modCount的初始值是0,当集合每被修改一次时(调用add,remove等方法),modCount加1。因此,modCount如果不变,表示集合内容未被修改。

  好了知道了这三个关键变量我们来看看关键代码

 

public boolean hasNext() {
            return cursor != size();
	}

 这里我们知道cursor的值和集合元素的个数决定hasNext()方法的值,即当指针指向最后一个元素后一位的时候就返回false。

 

public E next() {
            checkForComodification();
	    try {
		E next = get(cursor);
		lastRet = cursor++;
		return next;
	    } catch (IndexOutOfBoundsException e) {
		checkForComodification();
		throw new NoSuchElementException();
	    }
	}

 这是next()方法,返回的是索引是cursor的元素对象,并且对cursor和lastRet变量都进行修改。

 

这就是Iterator迭代器的整个流程,所以

while (it.hasNext()) {
			Object obj = it.next();
			// contains的实质就是equals方法,想判断自己想要的属性要重写
			if (!newal.contains(obj))
				newal.add(obj);

		}

这段代码就能完成对集合的遍历过程,不仅如此,迭代器还可以进行remove(),add(),set()方法对集合进行操作。

 

 

 

 

 

你可能感兴趣的:(java,框架)