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都已經推出十多年了,很多的語法也開始被大部分人習慣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章