迭代,在程序中特指對(duì)某集合中各元素逐個(gè)取用的行為。迭代器模式(Iterator)提供了一種機(jī)制來(lái)按順序訪問(wèn)集合中的各元素,而不需要知道集合內(nèi)部的構(gòu)造。換句話講,迭代器滿足了對(duì)集合迭代的需求,并向外部提供了一種統(tǒng)一的迭代方式,而不必暴露集合的內(nèi)部數(shù)據(jù)結(jié)構(gòu)。
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
二、遍歷標(biāo)準(zhǔn)化迭代的過(guò)程是基于一系列數(shù)據(jù)展開(kāi)的,所以集合是不得不提的概念。物以類聚,集合是由一個(gè)或多個(gè)確定的元素構(gòu)成的整體,其實(shí)就是把一系列類似的元素按某種數(shù)據(jù)結(jié)構(gòu)集結(jié)起來(lái),作為一個(gè)整體來(lái)引用,以便于維護(hù)。簡(jiǎn)單來(lái)講,可以把集合理解為“一堆”或者“一群”類似的元素集結(jié)起來(lái)的整體。為了承載不同的數(shù)據(jù)形式,集合類提供了多種多樣的數(shù)據(jù)結(jié)構(gòu),如我們常用的ArrayList、HashSet、HashMap等,
每種集合都有不同的特性,可以滿足對(duì)各種數(shù)據(jù)結(jié)構(gòu)的承載需求。有了集合才會(huì)產(chǎn)生對(duì)其迭代的需求,而每種數(shù)據(jù)結(jié)構(gòu)的迭代方式又不盡相同,所以,定義標(biāo)準(zhǔn)化的迭代器勢(shì)在必行,以提供統(tǒng)一、通用的使用方法。
三、手寫(xiě)迭代器不同的數(shù)據(jù)結(jié)構(gòu)需要不同的集合類,而針對(duì)不同的集合類的迭代方式也不盡相同,如for、foreach、while,甚至Java8引入的流式遍歷等。舉個(gè)例子,我們可以使用傳統(tǒng)的for循環(huán)對(duì)List集合進(jìn)行迭代遍歷,而對(duì)于Set集合,for循環(huán)就無(wú)能為力了,這是因?yàn)镾et本身集合不存在index索引號(hào),所以必須用foreach循環(huán)(迭代器Iterator)進(jìn)行遍歷。難道就沒(méi)有一種通用的迭代標(biāo)準(zhǔn),能讓調(diào)用者使用統(tǒng)一的方式進(jìn)行遍歷嗎?如果我們深究源碼就會(huì)發(fā)現(xiàn),Collection接口中有這樣一個(gè)接口。
Collection接口的一段源碼,可以看到其明確聲明了獲取迭代器的接口iterator(),通過(guò)調(diào)用這個(gè)接口就可以返回標(biāo)準(zhǔn)的迭代器對(duì)象。既然有了這種標(biāo)準(zhǔn),那么Collection這集合類就可以實(shí)現(xiàn)自己的迭代器。而Map集合也可以按照同樣的方式,從其EntrySet中獲取迭代器??梢?jiàn),標(biāo)準(zhǔn)化的迭代器其實(shí)已經(jīng)被各種集合類實(shí)現(xiàn)了,否則用戶就無(wú)法站在Collection接口的抽象高度上對(duì)任何集合進(jìn)行統(tǒng)一遍歷。
1.定義迭代器汽車前擋風(fēng)玻璃上安裝了一臺(tái)行車記錄儀,它最主要的一項(xiàng)功能就是記錄行駛路途中所拍攝的視頻信息,以防發(fā)生交通事故后作為證據(jù)之用。我們知道,行車記錄儀所記錄下來(lái)的視頻文件是比較大的,同時(shí)其存儲(chǔ)空間又是有限的,那么它是怎樣確保一直不間斷地錄制視頻,并且存儲(chǔ)空間不被占滿呢?這就需要我們深究其內(nèi)部數(shù)據(jù)結(jié)構(gòu)了。
其實(shí),行車記錄儀的視頻錄制存盤(pán)操作有循環(huán)覆寫(xiě)的特性,待空間不夠用時(shí),新錄的視頻就會(huì)覆蓋最早的視頻,以首尾相接的環(huán)形結(jié)構(gòu)來(lái)解決存儲(chǔ)空間有限的問(wèn)題。
public interface Iterator{//返回下一個(gè)元素
E next();
//是否還有下一個(gè)元素
boolean hasNext();
}
2.行車記錄儀類public class DrivingRecorder{private int index = -1;//當(dāng)前記錄的位置
private String[] records = new String[10]; //假設(shè)只能記錄10條視頻
public void append(String record){//索引重置,從頭覆蓋
if(index == 9 ){index = 0;
}else {index++;
}
records[index] = record;
}
public Iteratoriterator() {return new Itr();
}
private class Itr implements Iterator{int cursor = index;//迭代器游標(biāo),不破及原始集合索引
int loopCount = 0;
@Override
public String next() {int i = cursor;
if(cursor == 0){cursor = 9;
}else {cursor--;
}
loopCount++;
return records[i];
}
@Override
public boolean hasNext() {return loopCount< 10;
}
}
}
3.客戶端類public class Client {public static void main(String[] args) {DrivingRecorder dr = new DrivingRecorder();
for (int i = 0; i< 12; i++) {dr.append("視頻_" + i);
}
ListuStorage = new ArrayList<>();
Iterator it = dr.iterator();
while (it.hasNext()){String video = (String) it.next();
System.out.println(video);
if("視頻_10".equals(video) || "視頻_8".equals(video)){uStorage.add(video);
}
}
System.out.println("事故證據(jù)" + uStorage);
}
}
輸出結(jié)果:
視頻_11
視頻_10
視頻_9
視頻_8
視頻_7
視頻_6
視頻_5
視頻_4
視頻_3
視頻_2
事故證據(jù)[視頻_10, 視頻_8]
說(shuō)明:
提示:這里對(duì)文章進(jìn)行總結(jié):
為了完成對(duì)各種集合類的遍歷,我們定義了統(tǒng)一的迭代器接口Iterator,基于此我們讓集合以內(nèi)部類的方式實(shí)現(xiàn)其特有的迭代邏輯,再將自己標(biāo)記為Iterable并返回迭代器實(shí)例,以證明自己是具備迭代能力的。具體的集合內(nèi)部結(jié)構(gòu)與迭代邏輯對(duì)于客戶端這個(gè)“局外人”是透明的,客戶端只需要知道這個(gè)集合是可以迭代的,并向集合發(fā)起迭代請(qǐng)求以獲取迭代器即可以進(jìn)行標(biāo)準(zhǔn)方式的遍歷了。
迭代器模式的各角色定義如下:
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧