首頁 Java java教程 Java中關於迭代器的使用詳解

Java中關於迭代器的使用詳解

Sep 23, 2017 am 10:13 AM
java 使用 詳解

這篇文章主要介紹了java 中迭代器的使用方法詳解的相關資料,希望透過本文能幫助到大家,需要的朋友可以參考下

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

前言:

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

      迭代器模式主要是透過Iterator介面來管理一個聚合物件的,而使用者使用的時候只需要拿到一個Iterator類型的物件即可完成對該聚合物件的遍歷。這裡的聚合物件一般是指ArrayList,LinkedList和底層實作為陣列等擁有一組相同或相似特性的物件。透過迭代器模式對聚合物件的遍歷主要是透過Iterator介面的next(),hasNext()方法進行的,這裡next()方法將傳回目前遍歷點的元素值,而hasNext()方法則表徵目前遍歷點之後還有沒有元素。 Iterator介面中還有一個remove()方法,將移除目前遍歷點的元素。在一般情況下不需要使用該方法,一些特殊的情況可以呼叫該方法,如果當前聚合物件的遍歷不支援該操作,那麼可以在該方法中跑出UnSupportedOperationException。

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

選單介面(主要包含建立迭代器的方法):


public interface Menu<T> {
  Iterator<T> 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<MenuItem> {
  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&#39;) 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&#39;t add item to menu");
    } else {
      menuItems[numberOfItems] = menuItem;
      numberOfItems++;
    }
  }

  @Deprecated
  public MenuItem[] getMenuItems() {
    return menuItems;
  }

  public Iterator<MenuItem> createIterator() {
    return new DinerMenuIterator(menuItems);
  }
}
public class PancakeHouseMenu implements Menu<MenuItem> {
  private ArrayList<MenuItem> menuItems;

  public PancakeHouseMenu() {
    menuItems = new ArrayList<>();
    addItem("K&B&#39;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<MenuItem> getMenuItems() {
    return menuItems;
  }

  public Iterator<MenuItem> createIterator() {
    return menuItems.iterator();
  }
}
登入後複製

迭代器介面:

public interface Iterator<T> {
  boolean hasNext();
  T next();
}
登入後複製

迭代器類:

public class DinerMenuIterator implements Iterator<MenuItem> {
  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&#39;t remove an item until you&#39;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<MenuItem> {
  private ArrayList<MenuItem> items;
  private int position = 0;

  public PancakeHouseIterator(ArrayList<MenuItem> 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<MenuItem> pancakeHouseMenu;
  private Menu<MenuItem> dinerMenu;

  public Waitress(Menu<MenuItem> pancakeHouseMenu, Menu<MenuItem> dinerMenu) {
    this.pancakeHouseMenu = pancakeHouseMenu;
    this.dinerMenu = dinerMenu;
  }

  public void printMenu() {
    Iterator<MenuItem> pancakeIterator = pancakeHouseMenu.createIterator();
    Iterator<MenuItem> dinerIterator = dinerMenu.createIterator();
    System.out.println("MENU\n----\nBREAKFAST");
    printMenu(pancakeIterator);
    System.out.println("\nLUNCH");
    printMenu(dinerIterator);

  }

  private void printMenu(Iterator<MenuItem> 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等會更改該類別結構的方法。

以上是Java中關於迭代器的使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1327
25
PHP教程
1273
29
C# 教程
1252
24
突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP與Python:核心功能 PHP與Python:核心功能 Apr 13, 2025 am 12:16 AM

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP的影響:網絡開發及以後 PHP的影響:網絡開發及以後 Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP:許多網站的基礎 PHP:許多網站的基礎 Apr 13, 2025 am 12:07 AM

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP與Python:用例和應用程序 PHP與Python:用例和應用程序 Apr 17, 2025 am 12:23 AM

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。

See all articles