Heim  >  Artikel  >  Java  >  Detaillierte Erläuterung der Verwendung von Iteratoren in Java

Detaillierte Erläuterung der Verwendung von Iteratoren in Java

黄舟
黄舟Original
2017-09-23 10:13:241262Durchsuche

Dieser Artikel stellt hauptsächlich relevante Informationen zur detaillierten Verwendung von Iteratoren in Java vor. Ich hoffe, dieser Artikel kann jedem helfen, der Hilfe braucht.

Die Verwendung von Iteratoren in Java die Methode

Vorwort:

Das Iteratormuster kapselt eine Sammlung, hauptsächlich um Benutzern eine Möglichkeit zu bieten, ihre internen Elemente zu durchlaufen. Das Iteratormuster hat zwei Vorteile: ① Es bietet Benutzern die Möglichkeit, zu durchlaufen, ohne ihre internen Implementierungsdetails offenzulegen. ② Es weist die Verantwortung für das Reisen zwischen Elementen Iteratoren statt Aggregatobjekten zu und realisiert so die Integration zwischen Benutzern und Aggregatobjekten .

Der Iteratormodus verwaltet ein Aggregatobjekt hauptsächlich über die Iteratorschnittstelle. Bei seiner Verwendung muss der Benutzer nur ein Objekt vom Typ Iterator abrufen, um die Durchquerung des Aggregatobjekts abzuschließen. Die Aggregatobjekte beziehen sich hier im Allgemeinen auf ArrayList, LinkedList und die zugrunde liegende Implementierung ist ein Array usw. Objekte, die eine Reihe gleicher oder ähnlicher Eigenschaften aufweisen. Das Durchlaufen von Aggregatobjekten im Iteratormodus erfolgt hauptsächlich über die Methoden next() und hasNext() der Iterator-Schnittstelle. Die Methode next() gibt hier den Elementwert des aktuellen Durchlaufpunkts und die Methode hasNext() zurück stellt den aktuellen Durchlaufpunkt dar. Danach gibt es keine Elemente mehr. Es gibt auch eine Methode „remove()“ in der Iterator-Schnittstelle, die das Element am aktuellen Durchlaufpunkt entfernt. Diese Methode muss unter normalen Umständen nicht verwendet werden. In einigen Sonderfällen kann diese Methode aufgerufen werden. Wenn die Durchquerung des aktuellen Aggregatobjekts diesen Vorgang nicht unterstützt, kann eine UnSupportedOperationException ausgelöst werden.

Hier verwenden wir das folgende Beispiel, um das Iteratormuster zu veranschaulichen. Derzeit gibt es zwei Menüsätze für zwei Restaurants. Ein Menüsatz wird mithilfe eines Arrays implementiert, während der andere Menüsatz mithilfe einer ArrayList implementiert wird. Aufgrund der Fusion der beiden Restaurants müssen die beiden Menüs nun integriert werden. Da sich die Köche beider Seiten an ihre jeweiligen Menüzusammenstellungsmethoden gewöhnt haben, hoffen beide, weiterhin ihre eigenen Menüstile beizubehalten. Allerdings müssen Kellner bei der Bereitstellung von Menüs für Kunden diese auf zwei unterschiedliche Arten gemäß zwei Menüsätzen handhaben, was die Arbeit der Kellner zwangsläufig erschweren wird. Darüber hinaus wird die Arbeit der Kellner zwangsläufig schwieriger, wenn z. B. neue Restaurants hinzukommen Wenn der verwendete Menütyp HashMap ist, behält der Kellner diesen Menüsatz bei, was einer Erweiterung nicht förderlich ist. Je nach den Bedürfnissen des Kellners benötigt er eine Menüliste. Wenn diese auf verschiedene Menükategorien ausgerichtet ist, erhöht dies zwangsläufig die Schwierigkeit seiner Arbeit, und die in verschiedenen Menükategorien bereitgestellten Methoden entsprechen nicht unbedingt den Anforderungen des Kellners Daher muss eine Menüspezifikation entsprechend den Bedürfnissen des Kellners formuliert werden, damit der Kellner diese auf die gleiche Weise durchlaufen kann. Hier kann das Iterator-Muster verwendet werden. Der Kellner muss nur die Iterator-Schnittstelle durchlaufen, und das Menü jedes Kochs muss nur den Iterator implementieren, und er kann seine Menüpunkte weiterhin auf seine eigene Weise verwalten. Dadurch wird die Entkopplung verschiedener Menüs und Kellner erreicht. Nachfolgend finden Sie den spezifischen Code zur Lösung dieses Problems mithilfe des Iteratormusters.

Menüoberfläche (enthält hauptsächlich Methoden zum Erstellen von Iteratoren):


public interface Menu<T> {
  Iterator<T> createIterator();
}

Menüelemente:


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;
  }
}

Menüklasse (wie Menüelemente zusammengestellt werden):


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();
  }
}

Iterator-Schnittstelle:


public interface Iterator<T> {
  boolean hasNext();
  T next();
}

Iterator-Klasse:


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++);
  }
}

Kellnerklasse:


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());
    }
  }
}

Wie es sein kann Aus dem obigen Code geht hervor, dass der Kellner nicht für ein bestimmtes Menü programmiert, sondern auf eine Menüschnittstelle angewiesen ist, die einen Menü-Iterator und einen Iterator-Schnittstellen-Iterator für die Programmierung erstellt. Der Kellner muss nicht wissen, um welche Art von Assemblermethode es sich handelt Das Menü? Sie müssen zum Durchlaufen nur die Menüobjekte verwenden, die diese beiden Schnittstellen implementieren. Dies erreicht den Zweck der Implementierung der Schnittstelle, indem sie sich bei Änderungen auf die Schnittstelle verlässt. Dies ermöglicht die Trennung von Kellnern und Menüs Montagemethoden.

Das Iteratormuster ist überall in der Sammlung der Java-Klassenbibliotheken zu sehen. Das hier verwendete Menü entspricht der Iterable-Schnittstelle in der Java-Klassenbibliothek. Seine Funktion besteht darin, ein Iteratorobjekt zu erstellen, und die Iterator-Schnittstelle ist dieselbe als Iterator-Schnittstelle der Java-Klassenbibliothek. Im Grunde das Gleiche. Hier muss erklärt werden, dass die tatsächliche Implementierung des Iteratormusters durch eine Klasse nicht nur die Funktionalität einer Klasse erhöht, sondern auch den Wartungsaufwand der Klasse erhöht, da die Grundmethode der Klasse sehr kohärent ist und die sogenannte Zusammenhalt ist die Implementierung Ein vollständiger Satz verwandter Funktionen, und die Iteratorschnittstelle ist tatsächlich ein vollständiger Satz verwandter Funktionen. Wenn Sie also eine Klasse das Iteratormuster implementieren lassen, werden der Klasse implizit zwei Sätze weniger „kohäsiver“ Funktionen hinzugefügt. Dies führt dazu, dass bei der Aufrechterhaltung von Funktionen dieser Klasse beide Seiten berücksichtigt werden müssen. Dies spiegelt sich in den Java-Klassenbibliotheken ArrayList und LinkedList wider. Sie stellen nicht nur alle grundlegenden Entfernungsmethoden von List bereit, sondern auch die Entfernungsmethode, die von Iteratoren implementiert werden muss Um einige Konventionen zu treffen, können Sie beispielsweise beim Durchlaufen einer Sammlung nicht die grundlegenden Methoden zum Entfernen oder Hinzufügen der Klasse aufrufen, die die Struktur der Klasse ändern.

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Verwendung von Iteratoren in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn