Java中迭代器的使用


由於Java中數據容器眾多,而對數據容器的操作在很多時候都具有極大的共性,於是Java采用了迭代器為各種容器提供公共的操作接口。

使用Java的迭代器iterator可以使得對容器的遍歷操作完全與其底層相隔離,可以到達極好的解耦效果。

 public interface Iterable<T>

   Iterator<Titerator() 
          Returns an iterator over a set of elements of type T

 

Collection接口拓展了接口Iterable,根據以上的對Iterable接口的定義可以發現,其要求實現其的類都提供一個返回迭代器Iterator<T>對象的方法。

迭代器Iterator<T>接口的的定義為:

Interface Iterator<E>

boolean  hasNext() 
          Returns true if the iteration has more elements.

 E  next() 
          Returns the next element in the iteration.

void  remove() 
          Removes from the underlying collection the last element returned by the iterator (optional operation).

注意:

  從以上的定義中可以發現,似乎Iterable()接口和Iterator()接口完全一致,沒有任何區別。結合剛剛學習的內部類,可以發現這又是一個支持程序多樣化的巧妙設計,充分的支持了多態和解耦。

1、由於所有的Collection類型的對象都被強制要求implements  Iterable 接口,故任何Collection對象都要能返回一個能遍歷其的迭代器Iterator。如果直接 implement iterator接口, Collection會直接要求具有hasNext()等方法。但是這種方法不具備多態性,即設定好了該如何執行hasNext()等操作,而且程序會顯得十分的臃腫和復雜。但是如果采用實施Iterable()接口和返回Iterator對象的方式,則會全然的不同,只要能夠返回Iterator對象,完全可以自己的需要進行遍歷方式上的自由定義。(即針對同一個接口,在其實現類中提供多樣、不同的方法)。

Example:

 

public class TestIterable {
	TestIterable(){
	ScanAppleStore appleTree= new ScanAppleStore();
	
	print("Try normal iterator:");
	for(String str:appleTree)
	{
		print(str);
		
	}
	print("Try reverse iterator:");
	for(String str:appleTree.reverseIterator())
	{
		print(str);
	}
	}
}

class ScanAppleStore implements Iterable<String>
{
	ArrayList<String> appleStore = new ArrayList<String>();
	ScanAppleStore()
	{
		Collections.addAll(appleStore,"Sweet","Sour","Bitter","litter Sweet","litter Sour","litter Bitter");
		print(appleStore);
	}
	public Iterator<String> iterator()
	{
		return new Iterator<String>(){
			private int i=0;
			public boolean hasNext()
			{
				if(i<appleStore.size())
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			public String next()
			{

				return appleStore.get(i++);
			}
			public void remove()
			{
				print("not defined!");
			}
		};
	}
	public Iterable<String> reverseIterator()
	{
		return new Iterable<String>()
		{ 
			public Iterator<String> iterator(){
				return new Iterator<String>(){
			private int i=appleStore.size()-1;
			public boolean hasNext()
			{
				if(i>-1)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			public String next()
			{

				return appleStore.get(i--);
			}
			public void remove()
			{
				print("not defined!");
			}
				};
			}
			};

	}
}

從以上的例子中可以發現,為了實現對ScanAppleStore類對象的遍歷,共定義了兩種迭代器供選擇:

1、public Iterator<String> iterator() :該迭代器被定義為ScanAppleStore implements Iterable接口的方法, 采用常規的順序遍歷方式,for(String str:appleTree) 時自動被轉型調用。

2、public Iterable<String> reverseIterator():該迭代器采用了匿名內部類的方式實現Iterable接口,並返回Iterable對象,采用逆序的遍歷方式,for(String str:appleTree.reverseIterator())時,通過調用appleTree.reverseIterator()方法返回Iterable對象。

!foreach語法的標准形式為:for(T element : Iterable<T> elements)

由於Iterable接口要求實現iterator()方法,iterator()方法要求返回Iterator對象,Iterator定義了hasNext(), next(), remove()三種必須被實現的方法。

故實現Iterable的稍顯拖沓和復雜:

Example:

 

public Iterable<String> reverseIterator()
	{
		return new Iterable<String>()
		{ 
			public Iterator<String> iterator(){
				return new Iterator<String>(){
			private int i=appleStore.size()-1;
			public boolean hasNext()
			{
				if(i>-1)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			public String next()
			{

				return appleStore.get(i--);
			}
			public void remove()
			{
				print("not defined!");
			}
				};
			}
			};

	}
}

此處采用了匿名內部類的方式,結構十分的清晰,此處更是體現出了內部類對於實現接口,強化OOP Java編程能力的重要性。

注意Iterable<T>中強調使用范型,故在定義的時候一定要注意指明類型。

 

 

迭代器接口要求實現其的類必須提供三種方法:

hasNext() :遍歷過程中,判定是否還有下一個元素。(從Collection對象的第一個元素開始)

next() : 遍歷該元素。(即取出下一個元素)

remove(): 移除剛剛遍歷過的元素。

從定義可以發現,該三個方法經常是被搭配使用的。

Examle:

Iteraotr it= arrayList.Iterator();

while(it.hasNext())

{

  print(it.next());

      it.remove();

}

基本思路為:在遍歷下一個元素前,先判斷其是否存在。對於想刪除的元素,必須先遍歷其,故 remove()方法總是接在 next()方法之后。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM