>  기사  >  Java  >  Java의 반복자 사용에 대한 자세한 설명

Java의 반복자 사용에 대한 자세한 설명

黄舟
黄舟원래의
2017-09-23 10:13:241261검색

이 글은 주로 Java의 Iterator 사용에 대한 자세한 설명을 소개합니다. 도움이 필요한 친구들은

Java의 Iterator 사용에 대한 자세한 설명

을 참조하세요. 머리말:

반복자 패턴은 컬렉션을 캡슐화하여 주로 사용자에게 내부 요소를 탐색할 수 있는 방법을 제공합니다. 반복자 패턴에는 두 가지 장점이 있습니다. ① 내부 구현 세부 정보를 노출하지 않고 사용자에게 이동하는 방법을 제공합니다. ② 집계 개체 대신 요소 간 이동 책임을 할당하여 사용자 간의 통합과 집계 개체 간의 분리를 실현합니다. .

 iterator 모드는 주로 Iterator 인터페이스를 통해 집계 개체를 관리하며, 이를 사용할 때 사용자는 Iterator 유형 개체만 가져오면 집계 개체의 순회가 완료됩니다. 여기에서 집계 개체는 일반적으로 ArrayList, LinkedList와 같은 동일하거나 유사한 특성 집합을 가진 개체를 나타내며 기본 구현은 배열입니다. Iterator 모드를 통한 집합 객체의 순회는 주로 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();
  }
}

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

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

위의 코드에서 웨이터가 특정 메뉴에 대해 프로그래밍하지 않고 메뉴 반복에 의존하여 메뉴를 생성한다는 것을 알 수 있습니다. 서버의 메뉴 인터페이스와 반복자 인터페이스 Iterator는 프로그래밍에 사용됩니다. 웨이터는 메뉴가 전달되는 어셈블리 방법의 종류를 알 필요가 없지만 이 두 인터페이스를 구현하는 메뉴 개체만 사용하면 됩니다. 변경에 대해 다형성에 의존하여 인터페이스를 구현하고, 인터페이스에 지속적으로 의존하여 웨이터와 메뉴 조립 방법의 분리를 실현하는 것을 목적으로 합니다.

 반복자 패턴은 Java 클래스 라이브러리 컬렉션의 모든 곳에서 볼 수 있습니다. 여기서 사용된 메뉴는 Java 클래스 라이브러리의 Iterable 인터페이스와 동일하며 해당 기능은 반복자 객체를 생성하는 것이며 Iterator 인터페이스는 기본적으로 동일합니다. Java 클래스 라이브러리의 Iterator 인터페이스. 여기서 설명해야 할 것은 실제로 클래스에 반복자 패턴을 구현하게 하면 클래스에 기능이 추가될 뿐만 아니라 클래스의 기본 메소드가 응집력이 높고 소위 말하는 클래스의 유지 관리 부담도 증가한다는 것입니다. 응집력은 구현 관련 함수의 전체 집합이며 반복자 인터페이스는 실제로 관련 함수의 전체 집합입니다. 따라서 클래스가 반복자 패턴을 구현하도록 하면 암시적으로 덜 "응집성"인 함수 집합 두 개가 클래스에 추가됩니다. 따라서 이 클래스의 기능을 유지할 때 양쪽을 모두 고려해야 합니다. 이는 Java 클래스 라이브러리 ArrayList 및 LinkedList에 반영됩니다. 이는 List의 모든 기본 제거 메소드를 제공할 뿐만 아니라 이 두 가지의 통합을 달성하기 위해 반복자에 의해 구현되어야 하는 제거 메소드도 제공합니다. 예를 들어, 컬렉션을 순회할 때 클래스 구조를 변경하는 클래스의 기본 제거 또는 추가 메서드를 호출할 수 없습니다.

위 내용은 Java의 반복자 사용에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.