java中迭代器要導包嗎_java 中迭代器的使用方法詳解

java 中迭代器的使用方法詳解

前言:

迭代器模式將一個集合給封裝起來,主要是為用戶提供了一種遍歷其內部元素的方式。迭代器模式有兩個優點:①提供給用戶一個遍歷的方式,而沒有暴露其內部實現細節;②把元素之間游走的責任交給迭代器,而不是聚合對象,實現了用戶與聚合對象之間的解耦。

迭代器模式主要是通過Iterator接口來管理一個聚合對象的,而用戶使用的時候只需要拿到一個Iterator類型的對象即可完成對該聚合對象的遍歷。這里的聚合對象一般是指ArrayList,LinkedList和底層實現為數組等擁有一組相同或相似特性的對象。通過迭代器模式對聚合對象的遍歷主要是通過Iterator接口的next(),hasNext()方法進行的,這里next()方法將返回當前遍歷點的元素值,而hasNext()方法則表征當前遍歷點之后還有沒有元素。Iterator接口中還有一個remove()方法,該方法將移除當前遍歷點的元素。在一般情況下不需要使用該方法,一些特殊的情況可以調用該方法,如果當前聚合對象的遍歷不支持該操作,那么可以在該方法中跑出UnSupportedOperationException。

這里我們以如下例子來對迭代器模式進行說明。現有兩個餐廳的兩套菜單,一套菜單是使用數組實現的,而另外一套菜單是使用ArrayList實現的。現在由于兩個餐廳的合并而需要將兩套菜單進行整合,由于雙方的廚師都已經習慣了各自的菜單組裝方式,因而都希望各自繼續維護各自的菜單樣式。但是,對于服務員來說,其為顧客提供菜單的時候則必須根據兩套菜單進行兩種不同方式的處理,這必然會增加服務員的工作難度,而且,如果后期有新的餐廳合并進來,比如其使用的菜單種類為HashMap,那么服務員將又會維護這一套菜單,這也不利于擴展。根據服務員的需求,其需要的是一個菜單列表,如果其面向的是各個不同的菜單類,那么勢必會增加其工作難度,并且各個不同的菜單類中所提供的方法也不一定是服務員所需要的,因而,根據服務員的需求,這里需要制定一個菜單的規范,以實現服務員能夠按照同一種方式對其進行遍歷。這里就可以使用到迭代器模式,服務員只需要面向迭代器接口進行遍歷,而各個廚師所擁有的菜單只需要實現該迭代器即可,其依然可以按照各自的方式維護其菜單項。這樣就實現了不同的菜單與服務員的解耦。以下是使用迭代器模式解決該問題的具體代碼。

菜單接口(主要包含創建迭代器的方法):

public interface Menu {

Iterator createIterator();

}

菜單項:

public class MenuItem {

private String name;

private String description;

private boolean vegetarian;

private double price;

public MenuItem(String name, String description, boolean vegetarian, double price) {

this.name = name;

this.description = description;

this.vegetarian = vegetarian;

this.price = price;

}

public String getName() {

return name;

}

public String getDescription() {

return description;

}

public boolean isVegetarian() {

return vegetarian;

}

public double getPrice() {

return price;

}

}

菜單類(菜單項的組裝方式):

public class DinerMenu implements Menu {

private static final int MAX_ITEMS = 6;

private int numberOfItems = 0;

private MenuItem[] menuItems;

public DinerMenu() {

menuItems = new MenuItem[MAX_ITEMS];

addItem("Vegetarian BLT", "(Fakin') Bacon with lettuce & tomato on whole wheat", true, 2.99);

addItem("BLT", "Bacon with lettuce & tomato on whole wheat", false, 2.99);

addItem("Soup of the day", "Soup of the day, with a side of potato salad", false, 3.29);

addItem("Hotdog", "A hot dog, with saurkraut, relish, onions, topped with cheese", false, 3.05);

}

public void addItem(String name, String description, boolean vegetarian, double price) {

MenuItem menuItem = new MenuItem(name, description, vegetarian, price);

if (numberOfItems >= MAX_ITEMS) {

System.out.println("Sorry, menu is full, Can't add item to menu");

} else {

menuItems[numberOfItems] = menuItem;

numberOfItems++;

}

}

@Deprecated

public MenuItem[] getMenuItems() {

return menuItems;

}

public Iterator createIterator() {

return new DinerMenuIterator(menuItems);

}

}

public class PancakeHouseMenu implements Menu {

private ArrayList menuItems;

public PancakeHouseMenu() {

menuItems = new ArrayList<>();

addItem("K&B's Pancake Breakfast", "Pancakes with scrambled eggs, and toast", true, 2.99);

addItem("Regular Pancake Breakfast", "Pancakes with fried eggs, sausage", false, 2.99);

addItem("Blueberry Pancakes", "Pancakes made with fresh blueberries", true, 3.49);

addItem("Waffles", "Waffles, with your choice of blueberries or strawberries", true, 3.49);

}

public void addItem(String name, String description, boolean vegetarian, double price) {

MenuItem menuItem = new MenuItem(name, description, vegetarian, price);

menuItems.add(menuItem);

}

@Deprecated

public ArrayList getMenuItems() {

return menuItems;

}

public Iterator createIterator() {

return menuItems.iterator();

}

}

迭代器接口:

public interface Iterator {

boolean hasNext();

T next();

}

迭代器類:

public class DinerMenuIterator implements Iterator {

private MenuItem[] items;

private int position = 0;

public DinerMenuIterator(MenuItem[] items) {

this.items = items;

}

@Override

public boolean hasNext() {

return position < items.length && items[position] != null;

}

@Override

public MenuItem next() {

return items[position++];

}

@Override

public void remove() {

if (position <= 0) {

throw new IllegalStateException("You can't remove an item until you've done at least one next()");

}

if (items[position - 1] != null) {

for (int i = position - 1; i < items.length - 1; i++) {

items[i] = items[i + 1];

}

items[items.length - 1] = null;

}

}

}

public class PancakeHouseIterator implements Iterator {

private ArrayList items;

private int position = 0;

public PancakeHouseIterator(ArrayList items) {

this.items = items;

}

@Override

public boolean hasNext() {

return position < items.size();

}

@Override

public MenuItem next() {

return items.get(position++);

}

}

服務員類:

public class Waitress {

private Menu pancakeHouseMenu;

private Menu dinerMenu;

public Waitress(Menu pancakeHouseMenu, Menu dinerMenu) {

this.pancakeHouseMenu = pancakeHouseMenu;

this.dinerMenu = dinerMenu;

}

public void printMenu() {

Iterator pancakeIterator = pancakeHouseMenu.createIterator();

Iterator dinerIterator = dinerMenu.createIterator();

System.out.println("MENU\n----\nBREAKFAST");

printMenu(pancakeIterator);

System.out.println("\nLUNCH");

printMenu(dinerIterator);

}

private void printMenu(Iterator iterator) {

while (iterator.hasNext()) {

MenuItem menuItem = iterator.next();

System.out.print(menuItem.getName() + ", ");

System.out.print(menuItem.getPrice() + " -- ");

System.out.println(menuItem.getDescription());

}

}

}

從上面的代碼可以看出,服務員并沒有針對具體的菜單進行編程,而是依賴于一個創建菜單迭代器的Menu接口和一個迭代器接口Iterator來進行編程的,服務員并不需要知道所傳過來的是何種組裝方式的菜單,而只需要使用實現這兩個接口的菜單對象進行遍歷即可,這就達到了將變化的依賴于多態而實現接口,將不變的依賴于接口的目的,從而實現服務員與菜單組裝方式的分離。

迭代器模式在Java類庫的集合中隨處可見,這里使用的Menu就相當于Java類庫中的Iterable接口,其作用是創建一個迭代器對象,而Iterator接口和Java類庫的Iterator接口基本一致。這里需要說明的是,實際上讓一個類實現迭代器模式在為一個類增加功能的同時也增加了該類的維護負擔,因為類的基本方法是高內聚的,所謂的內聚即是實現了一套相關的完整的功能,而迭代器接口實際上也是一套完整的相關的功能,因而讓一個類實現迭代器模式隱含地為這個類增加了兩套不那么“內聚”的兩套功能,這就會導致該類在進行功能維護的時候需要兼顧雙方。在Java類庫中ArrayList和LinkedList中就有體現,其不僅提供了List所有的基本的remove方法,也提供了迭代器所需要實現的remove方法,為了實現兩者的統一,其不得不作一些約定,比如遍歷集合的時候不能調用該類基本的remove或者add等會更改該類結構的方法。

如有疑問請留言或者到本站社區交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

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

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

相關文章

android socket 長連接_TCP/IP,http,socket,長連接,短連接

點擊上方藍色字體&#xff0c;選擇“標星公眾號”優質文章&#xff0c;第一時間送達上一篇&#xff1a;這300G的Java資料是我師傅當年給我的&#xff0c;免費分享給大家下一篇&#xff1a;這200G的Java實戰資料是我師傅當年教我的第二招作者 | ksfzhaohui來源 | my.oschina.net…

二、Python安裝擴展庫

第一步:推薦easy_install工具 下載地址:https://pypi.python.org/pypi/setuptools 下載"ez_setup.py"文件; 通過運行cmd命令找到ez_setup.py文件所在目錄,通過命令[python ez_setup.py]執行安裝easy_install 安裝成功截圖 第二步:安裝擴展酷 例如安裝"suds"…

ORACLE 10.2.01升級10.2.05 for windows 詳細文檔

最近要做一個數據庫的升級工作&#xff0c;提前在自己的PC機上練習了一下&#xff0c;這種文檔在網上很多&#xff0c;但是大多都是使用命令編輯腳本&#xff0c;其實數據庫還有一個DBUA的升級工具可以使用&#xff0c;使升級工作方便了很多。 OS環境&#xff1a;windows XP 32…

php 導出mysql 結構_導出結構和數據(如phpmyadmin)

在這里,您可以找到一個全面的解決方案來轉儲MySQL結構和數據,比如在PMA中(不使用exec、passthru等):它是Dszymczuk項目的一個分支,有我的增強功能。用法很簡單//MySQL connection parameters$dbhost localhost;$dbuser dbuser;$dbpsw pass;$dbname dbname;//Connects to my…

tableViewCell的操作

在iOS的開發過程中&#xff0c;tableView的使用永遠都是最常用的控件。今天學習了一下tableViewCell的操作。代碼并不是很復雜&#xff0c;如果有OC開發經驗的人&#xff0c;應該很容易看懂的。 class ViewController: UIViewController ,UITableViewDelegate, UITableViewData…

stm32正交編碼器 原理圖_惡劣環境下應用的電感式增量編碼器和絕對編碼器

編碼器可分為兩種基本類型 - 增量編碼器和絕對編碼器。增量編碼器的顯著特征是它報告角度的變化。換句話說&#xff0c;當增量編碼器通電時&#xff0c;它不會報告其角位置&#xff0c;直到它具有測量的參考點。絕對編碼器明確地在比例或范圍內報告其位置。換句話說&#xff0c…

【SqlServer】Sqlserver中的DOS命令操作

輸入osql ?查看是否支持當前版本&#xff0c;如果是SQL Server 2005以上用Sqlcmd , 以下用Osql連接數據庫&#xff08;a&#xff09;Osql -S localhost -U username -P password(SQL Server身份驗證&#xff0c;需要用戶民和密碼)&#xff08;b&#xff09;Osql -S localhos…

微信小程序內訓筆記

2016年9月22日凌晨微信官方正式宣布“小程序”開始內測&#xff0c;有“微信之父”之稱、騰訊集團高級執行副總裁張小龍在2016年末對外宣布“小程序“應用將于2017年1月9日正式推出 這一次微信還是按照慣例&#xff0c;通過機器跑出的數據&#xff0c;首先將“小程序”開放給了…

python基礎代碼的含義_Python基礎學習篇

原標題&#xff1a;Python基礎學習篇 1、編碼 默認情況下&#xff0c;Python 3 源碼文件以 UTF-8 編碼&#xff0c;所有字符串都是unicode 字符串。 當然你也可以為源碼文件指定不同的編碼&#xff1a;# -*- coding: cp-1252 -*- 2、標識符 第一個字符必須是字母表中字母或下劃…

java面向對象super_【JavaSE】面向對象之super、final

一、super關鍵字它是一個指代變量&#xff0c;用于在子類中指代父類對象。1.作用指代父類對象區分子父類同名的成員變量&#xff0c;區分父類中成員變量和子類中同名的局部變量2.使用與this相同&#xff0c;調用父類成員變量和成員方法&#xff1a;super.xx super.xxx()調用父類…

Week_1_Physical Electronics and Semiconductors

Semiconductors Fundamentals Type of solids 轉載于:https://www.cnblogs.com/ronnielee/p/9579783.html

【Linux高頻命令專題(23)】tar

概述 通過SSH訪問服務器&#xff0c;難免會要用到壓縮&#xff0c;解壓縮&#xff0c;打包&#xff0c;解包等&#xff0c;這時候tar命令就是是必不可少的一個功能強大的工具。linux中最流行的tar是麻雀雖小&#xff0c;五臟俱全&#xff0c;功能強大。 tar命令可以為linux的文…

2. Add Two Numbers

直接用一個carry記錄進位就可以 1 //NEW2 class Solution {3 public ListNode addTwoNumbers(ListNode l1, ListNode l2) {4 ListNode root new ListNode(0);5 return addTwoNumbers(l1, l2, root);6 }7 public ListNode addTwoNumbers(ListNode …

安裝Windows更新程序遇到錯誤:0x80070422

看看服務那里 windows update服務是不是被禁用了&#xff1f; 還有一個問題可能是由于Windows Modules Installer被禁用了。

談談對python的理解_淺談對python pandas中 inplace 參數的理解

這篇文章主要介紹了對python pandas中 inplace 參數的理解&#xff0c;具有很好的參考價值&#xff0c;希望對大家有所幫助。一起跟隨小編過來看看吧 pandas 中 inplace 參數在很多函數中都會有&#xff0c;它的作用是&#xff1a;是否在原對象基礎上進行修改 inplace True&am…

java中 hashset_Java中的HashSet

HashSet擴展AbstractSet并實現Set接口。它創建一個使用哈希表進行存儲的集合。哈希表通過使用稱為哈希的機制來存儲信息。在散列中&#xff0c;鍵的信息內容用于確定唯一值&#xff0c;稱為其散列碼。然后&#xff0c;將哈希碼用作存儲與鍵關聯的數據的索引。鍵到其哈希碼的轉換…

mac下的svn服務器建立

MAC下的SVN服務器建立: from : http://blog.csdn.net/q199109106q/article/details/8655204 在Windows環境中&#xff0c;我們一般使用TortoiseSVN來搭建svn環境。在Mac環境下&#xff0c;由于Mac自帶了svn的服務器端和客戶端功能&#xff0c;所以我們可以在不裝任何第三方軟件…

SQL手冊

一.SQL簡介 二.SQL數據類型 三.SQL語法 四.SQL SELECT語句 五.SQL INSERT語句 六.SQL UPDATE語句 七.SQL DELETE語句 八.SQL DROP語句 九.SQL CREDTE語句 十.SQL ALTER 語句總結 十一.SQL事務 十二.函數總結 十三.數據庫其他操作 十四.MySQL 、SQL MS Access、和 SQL Server 數…

python語音合成并播放_使用Python實現文字轉語音并生成wav文件的例子

目前手邊的一些工作&#xff0c;需要實現聲音播放功能&#xff0c;而且僅支持wav聲音格式。 現在&#xff0c;一些網站上支持文字轉語音功能&#xff0c;但是生成的都是MP3文件&#xff0c;這樣還需要額外的軟件來轉成wav文件&#xff0c;十分麻煩。 后來&#xff0c;研究Pytho…

php 字符串 替換 最后,php如何替換字符串中的最后一個字符

php替換字符串中的最后一個字符的方法是&#xff1a;可以通過preg_replace()函數來實現。該函數的語法為&#xff1a;【preg_replace(mixed $pattern, mixed $replacement, mixed $subject】。要替換字符串中的最后一個字符&#xff0c;可以通過preg_replace()函數來實現。(如果…