00 30Java高级之集合输出

集合输出实际上从JDK 1.8开始就在Iterable接口之中提供有一个forEach()方法,但是这种方法的输出并不是传统意义上的集合输出形式,并且也很难在实际的开发之中出现,对于集合操作而言,一共有四种输出形式:Iterator迭代输出、ListIterator双向迭代输出、Enumeration枚举输出、foreach输出。

1 Iterator迭代输出

通过Collection接口的继承关系可以发现,从JDK 1.5开始其多继承了一个Iterable父接口,并且在这个接口里面定义有一个Iterator()操作方法,通过此方法可以获取Iterator接口对象(在JDK 1.5之前,这一方法直接定义在Collection接口之中)。
(1)获取Iterator接口对象:Iterator<T> iterator()
在Iterator接口里面定义有如下的方法:
(1)判断是否有数据:boolean hasNext()
(2)取出当前数据:E next()
(3)删除当前数据:default void remove()

在之前使用的java.util.Scanner类就是Iterator接口的子类,所以此时类继承关系如下:

范例:使用Iterator输出

package org.lks.demo;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class JavaReflectDemo {
	public static void main(String[] args) {
		Set<String> set = new HashSet<String>();
		set.add("Hello");
		set.add("World");
		set.add("lks");
		Iterator<String> iter = set.iterator();
		while(iter.hasNext()) {
			String str = iter.next();
			System.out.println(str);
		}
	}

}

但是对于Iterator接口中的remove()方法的使用需要特别注意一下(如果不是必须不要使用)。实际上在Collection接口里面定义有数据的删除操作方法,但是在进行迭代输出的过程里面如果你使用了Collection中的remove()方法会导致迭代失败。
范例:采用Collection集合中的remove()方法删除

package org.lks.demo;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class JavaReflectDemo {
	public static void main(String[] args) {
		Set<String> set = new HashSet<String>();
		set.add("Hello");
		set.add("World");
		set.add("lks");
		Iterator<String> iter = set.iterator();
		while(iter.hasNext()) {
			String str = iter.next();
			if("lks".equals(str)) {
				set.remove(str);
			}else {
				System.out.println(str);
			}
		}
	}

}

程序运行结果:Exception in thread "main" java.util.ConcurrentModificationException

此时无法进行数据的删除处理操作,那么此时就只能够利用Iterator接口中的remove()方法删除。

范例:使用Iterator接口删除方法

package org.lks.demo;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class JavaReflectDemo {
	public static void main(String[] args) {
		Set<String> set = new HashSet<String>();
		set.add("Hello");
		set.add("World");
		set.add("lks");
		Iterator<String> iter = set.iterator();
		while(iter.hasNext()) {
			String str = iter.next();
			if("lks".equals(str)) {
				iter.remove();
			}else {
				System.out.println(str);
			}
		}
	}

}

此时程序执行之后没有出现任何的错误,并且可以成功的删除原始集合中的数据。
面试题:请解释Collection.remove()与Iterator.remove()的区别?
(1)在进行迭代输出的时候如果使用Collection.remove()则会造成并发更新异常,导致程序删除出错,而此时只能利用Iterator接口中remove()方法实现正常的删除处理。

2 ListIterator双向迭代输出

使用Iterator进行的迭代输出操作有一个特点:只允许由前向后实现输出,而如果说你现在需要进行双向迭代处理,那么就必须依靠Iterator的子接口ListIterator来实现。需要注意的是如果要想获得ListIterator接口对象Collection并没有定义相关的处理方法,但是List子接口有,也就是说这个输出接口是专门为List集合准备的。

在ListIterator接口里面中定义有如下的操作方法:
(1)判断是否有前一个元素:boolean hasPrevious()
(2)获取当前元素:E previous()
范例:实现双向迭代

package org.lks.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class JavaReflectDemo {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("Hello");
		list.add("World");
		list.add("lks");
		ListIterator<String> iter = list.listIterator();
		while(iter.hasNext()) {
			String str = iter.next();
			System.out.println(str);
		}
		System.out.println("************");
		while(iter.hasPrevious()) {
			String str = iter.previous();
			System.out.println(str);
		}
	}

}

如果想要实现由后向前的遍历,那么首先要实现的是由前向后实现遍历处理。

3 Enumeration枚举输出

Enumeration是在JDK 1.0的时候就使用的输出接口,这个输出接口主要是为了Vector类提供输出服务的,一直到后续的JDK的发展,Enumeration依然只为Vector一个类服务,如果要想获取Enumeration接口对象,就必须依靠Vector类提供的方法。
(1)获取Enumeration:public Enumeration<E> elements()

在Enumeration定义有两个操作方法:
(1)判断是否有下一个元素:boolean hasMoreElements()
(2)获取当前元素:E nextElement()
范例:使用Enumeration实现输出

package org.lks.demo;

import java.util.Enumeration;
import java.util.Vector;

public class JavaReflectDemo {
	public static void main(String[] args) {
		Vector<String> list = new Vector<String>();
		list.add("Hello");
		list.add("World");
		list.add("lks");
		Enumeration<String> enu = list.elements();
		while(enu.hasMoreElements()) {
			String str = enu.nextElement();
			System.out.println(str);
		}
	}

}

由于该接口出现的时间比较长了,所以在一些比较早的开发过程之中,也有部分的方法只支持Enumeration输出操作,但是随着类方法的不断完善,大部分的操作都直接利用Iterator实现了。

4 foreach输出

除了使用迭代接口实现输出之外,从JDK 1.5开始加强型的for循环也可以实现集合的输出了。这种输出的操作形式与数组的输出操作形式类似。
范例:使用foreach输出

package org.lks.demo;

import java.util.Vector;

public class JavaReflectDemo {
	public static void main(String[] args) {
		Vector<String> list = new Vector<String>();
		list.add("Hello");
		list.add("World");
		list.add("lks");
		for(String str : list) {
			System.out.println(str);
		}
	}
}

这种输出最初出现的时候很多人并不建议使用,因为标准的集合操作还是应该以Iterator为主,但是毕竟JDK 1.5都已经推出十多年了,很多的语法也开始被大部分人习惯。

发布了122 篇原创文章 · 获赞 11 · 访问量 4218

猜你喜欢

转载自blog.csdn.net/weixin_43762330/article/details/104771015
00
今日推荐