`
linhaoxiang
  • 浏览: 22259 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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()方法对集合进行操作。

 

 

 

 

 

分享到:
评论

相关推荐

    ArrayList.java

    此类的返回的迭代器 iterator和listIterator方法是快速失败的 :如果列表在任何时间从结构上修改创建迭代器之后,以任何方式,除了通过迭代器自身的remove或add方法,迭代器都将抛出ConcurrentModificationException...

    java中set、list和map的使用方法实例

    // java中对象容器主要有Set,List和Map三个接口类。 // 迭代器(Iterator)模式,又叫做游标(Cursor)模式。 // GOF给出的定义为:提供一种方法访问一个容器(container)对象中的各个元素, // 而又不需暴露该...

    JDKAPI18CN(中文版)

    The iterators returned by this class's个 iterator和listIterator方法是快速失败的 :如果列表在任何时间从结构上修改创建迭代器之后,以任何方式除非通过迭代器自身remove种或add方法,迭代器都将抛出一个...

    AIC的Java课程1-6章

     可以使用迭代器Iterator遍历集合的元素。  [*]理解泛型概念,声明和使用带有范型的集合。 第11章 集合 4课时  理解什么是集合以及Java的集合框架。  辨析List,Set和Map接口...

    java 面试题 总结

     Collection是集合类的上级接口,继承与他的接口主要有Set 和List. Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 10、&和&&的区别。 &是位运算符...

    突破程序员基本功的16课.part2

    3.4 Iterator迭代器 迭代时删除指定元素 3.5 小结 第4课 Java的内存回收 4.1 Java引用的种类 4.1.1 对象在内存中状态 4.1.2 强引用 4.1.3 软引用 4.1.4 弱引用 4.1.5 虚引用 4.2 Java的内存泄漏 4.3 垃圾...

    大数据面试题.pdf

    反射有三种获取的⽅式,分别是:forName / getClass / 直接使⽤class⽅式 使⽤反射可以获取类的实例 1-6)列出⾄少五种设计模式 设计⽅式有⼯⼚法,懒加载,观察者模式,静态⼯⼚,迭代器模式,外观模式、、、、 1-...

    超级有影响力霸气的Java面试题大全文档

     Collection是集合类的上级接口,继承与他的接口主要有Set 和List. Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 13、&和&&的区别。 &是位运算符...

    二十三种设计模式【PDF版】

    设计模式之 Iterator(迭代器) 这个模式已经被整合入Java的Collection.在大多数场合下无需自己制造一个Iterator,只要将对象装入Collection中, 直接使用 Iterator 进行对象遍历。 设计模式之 Template(模板方法) ...

    Java学习笔记-个人整理的

    {4.7}集合的迭代(Iterator)}{85}{section.4.7} {4.8}Collections集合工具类}{86}{section.4.8} {4.9}Comparable与Comparator}{86}{section.4.9} {4.9.1}Comparable}{86}{subsection.4.9.1} {4.9.2}Comparator...

Global site tag (gtag.js) - Google Analytics