Iterator Pattern

Muzi·2023년 3월 28일
0

디자인 패턴

목록 보기
1/14

Iterator

: 하나씩 열거하면서 처리한다

for (int i = 0); i < arr.length; i++) {
	System.out.println(arr[i]);
}

해당 코드에서 '다음', '그 다음'으로 차례차례 진행되며 i를 늘려 가다 보면 배열 arr의 요소 전체를 처음부터 순서대로 검색하게된다

여기 사용되는 변수 i의 기능을 추상화하여 일반화한 것을 Iterator 패턴이라고한다.

예제

책장(BookShelf)안에 책(Book)을 넣고 책 이름을 차례대로 표시하는 프로그램

핵심 인터페이스

// 집합체를 나타내는 인터페이스 예제에서는 Iterable<Book>으로 이용
// 선언된 iterator()메서드는 집합체 안 요소를 하나하나 처리해 나가고 싶을때 이용한다
public interface Iterable<E> { // E는 타입 파라미터로 '모여 있는 것'을 나타내는 타입을 지정
    public abstract Iterator<E> iterator();
}
// 하나하나의 요소 처리를 반복하기 위한 것 예제에서는 Iterator<Book>
// 루프 변수와 같은 역할
public interface Iterator<E> {
    public abstract boolean hasNext(); // 다음 요소가 존재하는지
    public abstract E next(); // 다음 요소를 가져온다
}

1. Book

public class Book {
    private String name;
    
    public Book(String name) {
        this.name = name;
    }
    public String getName() { // 할 수 있는건 책 이름을 얻는것 뿐
        return name;
    }
}

2. BookShelf

// Iterable<Book>을 구현하고 있다
public class BookShelf implements Iterable<Book> {
    private Book[] books;
    private int last = 0;
    
    public BookShelf(int maxsize) {
        this.books = new Book[maxsize];
    }
    public Book getBookAt(int index) {
        return books[index];
    }
    public void appendBook(Book book) {
        this.books[last] = book;
        last++;
    }
    public int getLength() {
        return last;
    }
    
    // iterator 메소드를 오버라이드 구현
    @Override
    public Iterator<Book> iterator() {
        return new BookShelfIterator(this);
    }
}
  • 책장에는 books라는 배열 필드 존재
  • BookShelf의 iterator()는 BookShelfIterator 클래스의 인스턴스를 생성하여 반환
  • 책장에 꽃혀 있는 책을 반복해서 처리하고 싶을때 iterator() 호출

3. BookShelfIterator

public class BookShelfIterator implements Iterator<Book> {
    private BookShelf bookShelf;
    private int index;
    
    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }
    
    @Override
    public boolean hasNext() {
        if (index < bookShelf.getLength()) {
            return true;
        } else {
            return false;
        }
    }
    
    @Override
    public Book next() {
    	if (!hasNext()) {
        	throw new NoSuchElementException();
        }
        Book book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
}
  • Iteartor<Book> 인터페이스를 구현하고 있다

책장 검색

// 책들을 책장에 넣고 순회하며 책들의 이름을 출력하는 클래스
import java.util.*;

public class Main {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(4);
        bookShelf.appendBook(new Book("Around the World in 80 Days"));
        bookShelf.appendBook(new Book("Bible"));
        bookShelf.appendBook(new Book("Cinderella"));
        bookShelf.appendBook(new Book("Daddy-Long-Legs"));
        
        // 1. 명시적 Iterator
        Iterator it = bookShelf.iterator();
        while (it.hasNext()) {
            Book book = (Book)it.next();
            System.out.println(book.getName());
        }
        
        // 2. 확장 for문 사용
        for (Book book: bookShelf) {
        	System.out.println(book.getName());
        }
        System.out.println();
            
    }
}

1. 명시적 Iterator 사용

  • booShelf.iterator()로 얻은 it으로 책장을 순회

2. 확장 for문

  • Iterator를 사용한 반복 처리를 간결하게 기술
  • 일반적으로 Java의 확장 for문은 Iterable 인터페이스를 구현한 클래스(BookShelf)의 인스턴스에 대해 내부적으로 Iterator() 메서드를 호출하여 순회를 처리한다.
profile
좋아하는걸 열심히

0개의 댓글