iterator與iterable

用Iterator模式實現遍歷集合
Iterator模式是用于遍歷集合類的標準訪問方法。它可以把訪問邏輯從不同類型的集合類中抽象出來,從而避免向客戶端暴露集合的內部結構。
例如,如果沒有使用Iterator,遍歷一個數組的方法是使用索引:
for(int i=0; i<array.size(); i++) { ... get(i) ... }
而訪問一個鏈表(LinkedList)又必須使用while循環
while((e=e.next())!=null) { ... e.data() ... }
以上兩種方法客戶端都必須事先知道集合的內部結構,訪問代碼和集合本身是緊耦合,無法將訪問邏輯從集合類和客戶端代碼中分離出來,每一種集合對應一種遍歷方法,客戶端代碼無法復用。
更恐怖的是,如果以后需要把ArrayList更換為LinkedList,則原來的客戶端代碼必須全部重寫。

為解決以上問題,Iterator模式總是用同一種邏輯來遍歷集合:
for(Iterator it = c.iterater(); it.hasNext(); ) { ... }
奧秘在于客戶端自身不維護遍歷集合的"指針",所有的內部狀態(如當前元素位置,是否有下一個元素)都由Iterator來維護,而這個Iterator由集合類通過工廠方法生成,因此,它知道如何遍歷整個集合。
客戶端從不直接和集合類打交道,它總是控制Iterator,向它發送"向前","向后","取當前元素"的命令,就可以間接遍歷整個集合
首先看看java.util.Iterator接口的定義:
public interface Iterator { boolean hasNext(); Object next(); void remove(); }
依賴前兩個方法就能完成遍歷,典型的代碼如下:
for(Iterator it = c.iterator(); it.hasNext(); ) { Object o = it.next(); // 對o的操作... }
在JDK1.5中,還對上面的代碼在語法上作了簡化(但是限于只讀,如果需要remove,還是直接使用iterator):
// Type是具體的類型,如String。 for(Type t : c) { // 對t的操作... }
每一種集合類返回的Iterator具體類型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree可能返回TreeIterator,但是它們都實現了Iterator接口,因此,客戶端不關心到底是哪種Iterator,它只需要獲得這個Iterator接口即可,這就是面向對象的威力。

----------------------------------------------------------------

在遍歷的過程中出現java.util.ConcurrentModificationException的問題參http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html

用Iterator模式實現遍歷集合
Iterator模式是用于遍歷集合類的標準訪問方法。它可以把訪問邏輯從不同類型的集合類中抽象出來,從而避免向客戶端暴露集合的內部結構。
例如,如果沒有使用Iterator,遍歷一個數組的方法是使用索引:
for(int i=0; i<array.size(); i++) { ... get(i) ... }
而訪問一個鏈表(LinkedList)又必須使用while循環
while((e=e.next())!=null) { ... e.data() ... }
以上兩種方法客戶端都必須事先知道集合的內部結構,訪問代碼和集合本身是緊耦合,無法將訪問邏輯從集合類和客戶端代碼中分離出來,每一種集合對應一種遍歷方法,客戶端代碼無法復用。
更恐怖的是,如果以后需要把ArrayList更換為LinkedList,則原來的客戶端代碼必須全部重寫。

為解決以上問題,Iterator模式總是用同一種邏輯來遍歷集合:
for(Iterator it = c.iterater(); it.hasNext(); ) { ... }
奧秘在于客戶端自身不維護遍歷集合的"指針",所有的內部狀態(如當前元素位置,是否有下一個元素)都由Iterator來維護,而這個Iterator由集合類通過工廠方法生成,因此,它知道如何遍歷整個集合。
客戶端從不直接和集合類打交道,它總是控制Iterator,向它發送"向前","向后","取當前元素"的命令,就可以間接遍歷整個集合
首先看看java.util.Iterator接口的定義:
public interface Iterator { boolean hasNext(); Object next(); void remove(); }
依賴前兩個方法就能完成遍歷,典型的代碼如下:
for(Iterator it = c.iterator(); it.hasNext(); ) { Object o = it.next(); // 對o的操作... }
在JDK1.5中,還對上面的代碼在語法上作了簡化(但是限于只讀,如果需要remove,還是直接使用iterator):
// Type是具體的類型,如String。 for(Type t : c) { // 對t的操作... }
每 一種集合類返回的Iterator具體類型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree可 能返回TreeIterator,但是它們都實現了Iterator接口,因此,客戶端不關心到底是哪種Iterator,它只需要獲得這個 Iterator接口即可,這就是面向對象的威力。

----------------------------------------------------------------

在遍歷的過程中出現java.util.ConcurrentModificationException的問題參http://www.blogjava.net/EvanLiu/archive/2008/08/31/224453.html

如果想用foreach遍歷自定義類的集合,自定義類通常需要實現implement iterable接口. 該接口定義了Iterator<T> iterator()方法. 有些時候這個iterator方法可以供用類里面的集合屬性.iterator()返回.

示例:

 public class Teacher implements Iterable{  

private String name;
private int age;


public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Iterator iterator() {
return new Itr();
}


public static void main(String[] args) {
Teacher t
= new Teacher();
t.setName(
"aaaaaaa");
t.setAge(
23);
for (Object o : t) {
System.out.println(o.toString());
}
}


private class Itr implements Iterator{
private int cursor=0; // 屬性的索引
private Field[] fields = Teacher.class.getDeclaredFields(); // 屬性的數組

public boolean hasNext() {

return cursor!=(Teacher.class.getDeclaredFields().length);
}

public Object next() {
Object o
=null;
try{
fields[cursor].setAccessible(
true); // 讓內部類可以訪問外部類的私有屬性的值
o = fields[cursor].getName()+" "+fields[cursor].get(Teacher.this);
cursor
++;
}
catch(Exception e){
System.out.println(e);
}

return o;
}

public void remove() {
// TODO Auto-generated method stub

}

}
}

示例2:

import java.util.Iterator;

//測試類
public class Exec {
public static void main(String[] args) throws Exception {
// 創建學生集合類
Students students = new Students(10);

// 通過for each語句迭代循環學生集合類的每個元素
for (Object obj : students) {
Student stu
= (Student) obj;
System.out.println(stu.getSid()
+ ":" + stu.getName());
}
}
}

// 支持for each迭代循環的學生集合類
class Students implements Iterable {
// 存儲所有學生類的數組
private Student[] stus;

// 該構造函數可以生成指定大小的學生類變量數組,并初始化該學生類變量數組
public Students(int size) {
stus
= new Student[size];
for (int i = 0; i < size; i++) {
stus[i]
= new Student(String.valueOf(i), "學生" + String.valueOf(i));
}
}

// 實現Iterable接口的重要方法,返回自定義的迭代類變量
public Iterator iterator() {
return new StudentIterator();
}

// 實現Iterator接口的私有內部類,外界無法直接訪問
private class StudentIterator implements Iterator {
// 當前迭代元素的下標
private int index = 0;

// 判斷是否還有下一個元素,如果迭代到最后一個元素就返回false
public boolean hasNext() {
return index != stus.length;
}

// 返回當前元素數據,并遞增下標
public Object next() {
return stus[index++];
}

// 這里不支持,拋出不支持操作異常
public void remove() {
throw new UnsupportedOperationException();
}
}
}

// 學生類
class Student {
// 學生學號
private String sid;

// 學生姓名
private String name;

// 默認構造函數
public Student() {
}

// 支持屬性值初始化的構造函數
public Student(String sid, String name) {
setSid(sid);
setName(name);
}

// 學生學號的讀取函數
public String getSid() {
return sid;
}

// 學生學號的設置函數
public void setSid(String sid) {
this.sid = sid;
}

// 學生姓名的讀取函數
public String getName() {
return name;
}

// 學生姓名的設置函數
public void setName(String name) {
this.name = name;
}

// 格式化字符信息輸出
public String toString() {
return this.sid + ":" + this.name;
}
}

----------------------------------------------------------------------------

為什么一定要去實現Iterable這個接口呢? 為什么不直接實現Iterator接口呢?

看一下JDK中的集合類,比如List一族或者Set一族,
都是實現了Iterable接口,但并不直接實現Iterator接口。
仔細想一下這么做是有道理的。因為Iterator接口的核心方法next()或者hasNext()
依賴于迭代器的當前迭代位置的。
如果Collection直接實現Iterator接口,勢必導致集合對象中包含當前迭代位置的數據(指針)。
當集合在不同方法間被傳遞時,由于當前迭代位置不可預置,那么next()方法的結果會變成不可預知。
除非再為Iterator接口添加一個reset()方法,用來重置當前迭代位置。
但即時這樣,Collection也只能同時存在一個當前迭代位置。
而Iterable則不然,每次調用都會返回一個從頭開始計數的迭代器。
多個迭代器是互不干擾的。

轉載于:https://www.cnblogs.com/highriver/archive/2011/07/27/2077913.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378294.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378294.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378294.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android中的Touch事件處理流程

1、當觸摸屏幕時&#xff0c;最先執行的是Activity中的 publicbooleandispatchTouchEvent (MotionEvent ev) {if(ev.getAction() MotionEvent. ACTION_DOWN) {onUserInteraction();}if(getWindow().superDispatchTouchEvent(ev)) {returntrue;}returnonTouchEvent(ev);}如果某…

【TensorFlow學習筆記:神經網絡八股】(實現MNIST數據集手寫數字識別分類以及FASHION數據集衣褲識別分類)

課程來源&#xff1a;人工智能實踐:Tensorflow筆記2 文章目錄前言一、搭建網絡八股sequential1.函數介紹2.6步法實現鳶尾花分類二、搭建網絡八股class1.創建自己的神經網絡模板&#xff1a;2.調用自己創建的model對象三、MNIST數據集1.用sequential搭建網絡實現手寫數字識別2.用…

c語言 在執行區域沒有空格,C語言上機操作指導之TurboC.doc

C語言上機操作指導之 -------- Turbo C程序設計是實踐性很強的過程&#xff0c;任何程序都必須在計算機上運行&#xff0c;以檢驗程序的正確與否。因此在學習程序設計中&#xff0c;一定要重視上機實踐環節&#xff0c;通過上機可以加深理解 C語言的有關概念&#xff0c;以鞏固…

java 根據類名示例化類_Java即時類| from()方法與示例

java 根據類名示例化類即時類from()方法 (Instant Class from() method) from() method is available in java.time package. from()方法在java.time包中可用。 from() method is used to return a copy of the Instant from the given TemporalAccessor object. from()方法用于…

第十二章 圖形用戶界面

第十二章 圖形用戶界面 GUI就是包含按鈕、文本框等控件的窗口 Tkinter是事實上的Python標準GUI工具包 創建GUI示例應用程序 初探 導入tkinter import tkinter as tk也可導入這個模塊的所有內容 from tkinter import *要創建GUI&#xff0c;可創建一個將充當主窗口的頂級組…

Sqlserver 2005 配置 數據庫鏡像:數據庫鏡像期間可能出現的故障:鏡像超時機制

數據庫鏡像期間可能出現的故障 SQL Server 2005其他版本更新日期&#xff1a; 2006 年 7 月 17 日 物理故障、操作系統故障或 SQL Server 故障都可能導致數據庫鏡像會話失敗。數據庫鏡像不會定期檢查 Sqlservr.exe 所依賴的組件來驗證組件是在正常運行還是已出現故障。但對于某…

江西理工大學期末試卷c語言,2016年江西理工大學信息工程學院計算機應用技術(加試)之C語言程序設計復試筆試最后押題五套卷...

一、選擇題1&#xff0e; 設有函數定義&#xff1a;( )。A. B. C. D. 答:A則以下對函數sub 的調用語句中&#xff0c;正確的是【解析】函數的參數有兩個&#xff0c;第一個是整型&#xff0c;第二個是字符類型&#xff0c;在調用函數時&#xff0c;實參必須一個是整型&#xff…

第十三章 數據庫支持

第十三章 數據庫支持 本章討論Python數據庫API&#xff08;一種連接到SQL數據庫的標準化方式&#xff09;&#xff0c;并演示如何使用這個API來執行一些基本的SQL。最后&#xff0c;本章將討論其他一些數據庫技術。 關Python支持的數據庫清單 Python數據庫API 標準數據庫API…

【神經網絡八股擴展】:自制數據集

課程來源&#xff1a;人工智能實踐:Tensorflow筆記2 文章目錄前言1、文件一覽2、將load_data()函數替換掉2、調用generateds函數4、效果總結前言 本講目標:自制數據集&#xff0c;解決本領域應用 將我們手中的圖片和標簽信息制作為可以直接導入的npy文件。 1、文件一覽 首先看…

java 批量處理 示例_Java中異常處理的示例

java 批量處理 示例Here, we will analyse some exception handling codes, to better understand the concepts. 在這里&#xff0c;我們將分析一些異常處理代碼 &#xff0c;以更好地理解這些概念。 Try to find the errors in the following code, if any 嘗試在以下代碼中…

hdu 1465 不容易系列之一

http://acm.hdu.edu.cn/showproblem.php?pid1465 今天立神和我們講了錯排&#xff0c;才知道錯排原來很簡單&#xff0c;從第n個推起&#xff1a; 當n個編號元素放在n個編號位置,元素編號與位置編號各不對應的方法數用M(n)表示,那么M(n-1)就表示n-1個編號元素放在n-1個編號位置…

第十四章 網絡編程

第十四章 網絡編程 本章首先概述Python標準庫中的一些網絡模塊。然后討論SocketServer和相關的類&#xff0c;并介紹同時處理多個連接的各種方法。最后&#xff0c;簡單地說一說Twisted&#xff0c;這是一個使用Python編寫網絡程序的框架&#xff0c;功能豐富而成熟。 幾個網…

c語言輸出11258循環,c/c++內存機制(一)(轉)

一&#xff1a;C語言中的內存機制在C語言中&#xff0c;內存主要分為如下5個存儲區&#xff1a;(1)棧(Stack)&#xff1a;位于函數內的局部變量(包括函數實參)&#xff0c;由編譯器負責分配釋放&#xff0c;函數結束&#xff0c;棧變量失效。(2)堆(Heap)&#xff1a;由程序員用…

【神經網絡八股擴展】:數據增強

課程來源&#xff1a;人工智能實踐:Tensorflow筆記2 文章目錄前言TensorFlow2數據增強函數數據增強網絡八股代碼&#xff1a;總結前言 本講目標:數據增強&#xff0c;增大數據量 關于我們為何要使用數據增強以及常用的幾種數據增強的手法&#xff0c;可以看看下面的文章&#…

C++:從C繼承的標準庫

C從C繼承了的標準庫 &#xff0c; 這就意味著 C 中 可以使用的標準庫函數 在C 中都可以使用 &#xff0c; 但是需要注意的是 &#xff0c; 這些標準庫函數在C中不再以 <xxx.h> 命名 &#xff0c; 而是變成了 <cxxx> 。 例如 &#xff1a; 在C中操作字符串的…

分享WCF聊天程序--WCFChat

無意中在一個國外的站點下到了一個利用WCF實現聊天的程序&#xff0c;作者是&#xff1a;Nikola Paljetak。研究了一下&#xff0c;自己做了測試和部分修改&#xff0c;感覺還不錯&#xff0c;分享給大家。先來看下運行效果&#xff1a;開啟服務&#xff1a;客戶端程序&#xf…

c# uri.host_C#| 具有示例的Uri.Equality()運算符

c# uri.hostUri.Equality()運算符 (Uri.Equality() Operator) Uri.Equality() Operator is overloaded which is used to compare two Uri objects. It returns true if two Uri objects contain the same Uri otherwise it returns false. Uri.Equality()運算符已重載&#xf…

第六章至第九章的單元測試

1,?助劑與纖維作用力大于纖維分子之間的作用力,則該助劑最好用作() 纖維增塑膨化劑。 2,助劑擴散速率快,優先占領纖維上的染座,但助劑與纖維之間作用力小于染料與纖維之間作用力,該助劑可以作為() 勻染劑。 3,助劑占領纖維上的染座,但助劑與纖維之間作用力大于染…

【神經網絡擴展】:斷點續訓和參數提取

課程來源&#xff1a;人工智能實踐:Tensorflow筆記2 文章目錄前言斷點續訓主要步驟參數提取主要步驟總結前言 本講目標:斷點續訓&#xff0c;存取最優模型&#xff1b;保存可訓練參數至文本 斷點續訓主要步驟 讀取模型&#xff1a; 先定義出存放模型的路徑和文件名&#xff0…

開發DBA(APPLICATION DBA)的重要性

開發DBA是干什么的&#xff1f; 1. 審核開發人員寫的SQL&#xff0c;并且糾正存在性能問題的SQL ---非常重要 2. 編寫復雜業務邏輯SQL&#xff0c;因為復雜業務邏輯SQL開發人員寫出的SQL基本上都是有性能問題的&#xff0c;與其讓開發人員寫&#xff0c;不如DBA自己寫。---非常…