この記事では、Java のイテレータの詳細な説明に関する関連情報を主に紹介します。この記事が、必要な方の参考になれば幸いです。
Java のイテレータの使用の詳細な説明前書き:
イテレータ パターンはコレクションをカプセル化し、主にその内部要素を走査する方法をユーザーに提供します。イテレータ パターンには 2 つの利点があります。① 内部実装の詳細を公開せずにトラバースする方法をユーザーに提供します。② 要素間の移動の責任を集約オブジェクトではなくイテレータに割り当て、ユーザー間の統合と集約オブジェクト間の分離を実現します。 。
イテレータモードは主に Iterator インターフェースを通じて集約オブジェクトを管理し、これを使用する場合、ユーザーは Iterator 型のオブジェクトを取得するだけで集約オブジェクトの走査を完了できます。ここでの集合オブジェクトは通常、ArrayList、LinkedList などの同じまたは類似の特性のセットを持つオブジェクトを指し、基礎となる実装は配列です。イテレータ モードによる集約オブジェクトのトラバースは、主に Iterator インターフェイスの next() メソッドと hasNext() メソッドを通じて実行されます。ここでの next() メソッドは現在のトラバース ポイントの要素値を返し、hasNext() メソッドも返します。現在のトラバースポイントを表します。それ以降には要素はありません。 Iterator インターフェイスには、現在のトラバース ポイントにある要素を削除する Remove() メソッドもあります。このメソッドは、通常の状況では使用する必要はありません。現在の集約オブジェクトのトラバースがこの操作をサポートしていない場合、このメソッドで UnSupportedOperationException がスローされることがあります。 ここでは、次の例を使用してイテレータ パターンを説明します。現在、2 つのレストランに 2 つのメニュー セットがあり、1 つのメニュー セットは配列を使用して実装され、もう 1 つのメニュー セットは ArrayList を使用して実装されています。 2 つのレストランの合併により、2 つのメニューを統合する必要があります。双方のシェフはそれぞれのメニューの組み立て方法に慣れているため、今後も独自のメニュー スタイルを維持したいと考えています。しかし、ウェイターにとっては、顧客にメニューを提供する際に、2つのメニューに応じて2通りの対応をしなければならないため、後から新しい店舗が合併した場合には、ウェイターの業務の難易度は必然的に高くなる。使用されるメニュー タイプが 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') 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<MenuItem> createIterator() { return new DinerMenuIterator(menuItems); } } public class PancakeHouseMenu implements Menu<MenuItem> { private ArrayList<MenuItem> 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<MenuItem> getMenuItems() { return menuItems; } public Iterator<MenuItem> createIterator() { return menuItems.iterator(); } }
イテレータインターフェイス:
public interface Iterator<T> { boolean hasNext(); T next(); }
Iterator クラス:
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'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<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++); } }
Waiter クラス:
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 はプログラミングに使用されます。ウェイターはメニューが渡されるアセンブリ メソッドの種類を知る必要はありませんが、これら 2 つのインターフェイスを実装するメニュー オブジェクトを使用するだけで済みます。変更についてはポリモーフィズムに依存し、定常的な依存性についてはインターフェイスに依存することでインターフェイスを実装することで、ウェイター メソッドとメニュー アセンブリ メソッドの分離を実現することが目的です。
イテレータ パターンは Java クラス ライブラリのコレクションのいたるところで見られます。ここで使用される Menu は Java クラス ライブラリの Iterable インターフェイスに相当します。その機能はイテレータ オブジェクトを作成することであり、Iterator インターフェイスは基本的に同じです。 Java クラス ライブラリの Iterator インターフェイス。ここで説明する必要があるのは、実際にクラスにイテレータ パターンを実装させると、クラスに機能が追加されるだけでなく、クラスの基本的なメソッドの凝集性が高いため、クラスのメンテナンスの負担も増加するということです。実装とは関連する関数の完全なセットであり、イテレータ インターフェイスは実際には関連する関数の完全なセットです。したがって、クラスにイテレータ パターンを実装させると、「結合性の低い」関数のセットがクラスに暗黙的に追加されます。このクラスの機能を維持する際には、両方の側面を考慮する必要があります。これは、Java クラス ライブラリ ArrayList と LinkedList に反映されており、List のすべての基本的な削除メソッドを提供するだけでなく、この 2 つを統合するためにイテレータによって実装する必要がある削除メソッドも提供されます。たとえば、コレクションを走査する場合、クラスの構造を変更するクラスの基本的なメソッドの削除または追加を呼び出すことはできません。
以上がJava でのイテレータの使用方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。