Chapter 1. Iterator(반복자) : 하나씩 열거하면서 처리

sua·2022년 4월 9일
0
post-thumbnail

1. 예제 프로그램 - 책꽂이(BookShelf)에 책(Book)을 넣은 후, 순서대로 하나씩 다시 끄집어 내서 책 이름을 표시하는 프로그램
<Aggregate.java>

package ch01.Sample;

// 집합체는 자기 원소들을 돌아다닐 Iterator 객체를 반환하는 
// iterator( ) 메소드를 가진다.
public interface Aggregate {
	// 이 집합체의 Iterator를 반환하는 메소드 
    public abstract Iterator iterator();
}

// interface란, 모든 메소드의 body 부분이 없는 특수한 클래스이다.

<Iterator.java>

package ch01.Sample;

// 모든 Iterator가 가져야 할 메소드를 선언한 인터페이스
public interface Iterator {
	// 원소가 더 있는지 검사할 때 사용되는 메소드
    public abstract boolean hasNext(); 
    public abstract Object next(); // 그 다음 원소를 얻어돌 때 사용되는 메소드 
}

<Book.java>

package ch01.Sample;

// 책꽂이에 꽂힐 책을 나타내는 클래스
public class Book {
    private String name = ""; // 책의 이름을 저장한다.

	// 문자열을 입력 인자로 받아서 자신의 속성인 name에 저장한다.
    public Book(String name) {
        this.name = name;
    }

	// 자신의 이름을 반환하는 메소드
    public String getName() {
        return name;
    }
}

<BookShelf.java>

package ch01.Sample;

public class BookShelf implements Aggregate {
     // 책꽂이의 책을 보관하기 위한 Book 배열을 선언한다.
	private Book[ ] books;  //배열 변수만 선언하고, 공간을 할당되지 않았다.
    private int last = 0; // 마지막 책이 꽂힌 위치를 저장한다.

    public BookShelf(int maxsize) {
        this.books = new Book[maxsize]; // 여기서 배열 공간을 실제로 만들었음.
    }

	 // 입력인자인 index에 해당하는 책을 반환하는 메소드
    public Book getBookFrom(int index) {
        return books[index];
    }

	// 책꽂이에 책을 꽂는 메소드
    public void appendBook(Book book) {
        this.books[last] = book;
        last++;
    }

	// 책꽂이의 책 개수를 반환하는 메소드
    public int getLength() {
        return last;
    }

	// 자신의 Iterator를 생성하여 반환하는 메소드
    public Iterator iterator() {
		// 자신을 인자로 하여 BookShelfIterator 객체를 생성하여 반환한다.
        return new BookShelfIterator(this);  //this: 현재 책꽂이
    }
}




<BookShelfIterator.java>

package ch01.Sample;

// 책꽂이에 꽂힌 책을 차례차례 돌아다니는데 사용될 클래스
public class BookShelfIterator implements Iterator {
    // 이 Iterator가 돌아다닐 책꽂이를 가리키는 속성
	private BookShelf bookShelf;
    // 현재 책 번호를 유지하는 속성
	private int index;

	// 입력인자인 BookShelf 객체를 자기 속성인 bookShelf에 저장한다.
	// 나중에 이 속성을 이용해서 책꽂이를 돌아다닌다.
    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;  // 책꽂이를 돌아다니기 전이므로, 0으로 초기화한다.
    }

    // 책꽂이에 접근할 책이 더 있는지 검사하는 메소드
    public boolean hasNext() {
		// 현재 책 번호가 책꽂이에 있는 책 개수보다 작으면,
	    // 책꽂이에 돌아다닐 책이 더 있는 것이므로 true를 반환한다.
        if (index < bookShelf.getLength()) {
            return true;
        } else {
            return false;
        }
    }

	// 다음 책을 얻어오고자 할 때 호출되는 메소드
	// 반환형이 Object 타입이다. 
	//  - Object는 모든 클래스의 부모 클래스이므로 모든 자식을 가리킬 수 있다.  
	//  - 즉, 모든 타입의 객체를 반환할 수 있다.
	//  - 실제로 반환되는 객체는 Book 타입이므로, 올바른 반환형으로 선언된 것이다.
    public Object next() {
        // 이 Iterator가 가리키는 책꽂이의 getBookAt(index)를 이용해서
		// index 책번호에 해당하는 책을 얻어와서 book에 저장한다.
		Book book = bookShelf.getBookFrom(index);
        // 현재 책번호를 1 증가시킨다.
		index++;
		// 얻어온 책을 반환한다.
        return book;
    }
}

<Main.java>

package ch01.Sample;

public class Main {
	// 모든 자바 프로그램은 main() 메소드부터 시작된다.
    public static void main(String[] args) {
    	// 최대 4권의 책을 담을 수 있는 책꽂이를 생성한다.
        BookShelf bookShelf = new BookShelf(4);
        Aggregate bookShelf2 = new BookShelf(4);
        // 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"));

		// 책꽂이의 Iterator를 얻어온다.
        // 실제 생성되는 객체의 타입은 BookShelfIterater이다.
		Iterator it = bookShelf.iterator();
        
		// 책이 계속해서 있으면 while 루프를 돈다.
		// 책이 더 있는지 검사하기 위해서, iterator의 hasNext()를 호출한다.
		while (it.hasNext()) {
			Book book = (Book)it.next(); // 다음 책을 얻어온다.
			// 위 문장 대신에
			// Object book = it.next();
			// 을 사용하면 안 된다.
            // 왜냐하면, 아래에서 book.getName()을 호출하는데,
			// Object 타입은 getName() 을 지원하지 않는다.
			// 따라서,  it.next( )가 반환한 Object 형을 Book 형으로 "강제형변환"해야 한다.

			// 책의 이름을 출력한다.
			System.out.println("" + book.getName());
           
        }

        // 책꽂이에 직접 접근해서 각 책을 얻어와서 책의 이름을 출력한다.
		// iterator를 사용하지 않는다.
		for(int i=0; i<bookShelf.getLength(); i++) {
			Book book = bookShelf.getBookFrom(i);
            System.out.println("" + book.getName());
	    }
    }
}

2. 연습문제 - 책꽂이를 배열에서 벡터로
<Aggregator.java>

package ch01.A1;

// 집합체를 나타냄
public interface Aggregate {
	// 집합체에 대응하는 Iterator 한 개를 생성하는데 사용될 메소드
	// 어떤 집합체의 원소를 하나씩 열거하거나 조사하고자 할 때 
	// 이 메소드를 사용해서 Iterator 인터페이스를 구현한 
	// 클래스의 인스턴스를 한 개 얻어온다.
    public abstract Iterator iterator();
}

<Iterator.java>

package ch01.Sample;

// 모든 Iterator가 가져야 할 메소드를 선언한 인터페이스
public interface Iterator {
	// 원소가 더 있는지 검사할 때 사용되는 메소드
    public abstract boolean hasNext(); 
    public abstract Object next(); // 그 다음 원소를 얻어돌 때 사용되는 메소드 
}

<Book.java>

package ch01.A1;

// 책을 나타내는 클래스
public class Book {
	// 책이름을 저장하는 변수
    private String name = "";
    public Book(String name) {
        this.name = name;
    }
    // 책의 이름을 얻어올 때 호출하는 메소드
    public String getName() {
        return name;
    }
}

<BookShelf.java>

package ch01.A1;

// 책들을 보관하기 위해서 Vector를 사용한다.
import java.util.Vector;

// 책꽂이를 나타내는 클래스 = 집합체(aggregate)
public class BookShelf implements Aggregate {
	// Book의 배열
	// 이 배열의 크기는, 생성자(BookShelf( )) 호출 시 지정된다.
	private Vector books;

	public BookShelf(int initialsize) {
		this.books = new Vector(initialsize);
	}

	public Book getBookAt(int index) {
		return (Book) books.get(index);
	}

	// 책 한 권을 서가에 추가하는 메소드
	public void appendBook(Book book) {
		books.add(book);
	}

	// 현재 책꽂이에 있는 책의 개수를 반환하는 메소드
	public int getLength() {
		return books.size();
	}

	// 책꽂이의 책 하나하나를 끄집어내는 일을 하는
	// BookShelfIterator를 생성하는 메소드
	public Iterator iterator() {
		return new BookShelfIterator(this);
	}
}

<BookShelfIterator.java>

package ch01.Sample;

// 책꽂이에 꽂힌 책을 차례차례 돌아다니는데 사용될 클래스
public class BookShelfIterator implements Iterator {
    // 이 Iterator가 돌아다닐 책꽂이를 가리키는 속성
	private BookShelf bookShelf;
    // 현재 책 번호를 유지하는 속성
	private int index;

	// 입력인자인 BookShelf 객체를 자기 속성인 bookShelf에 저장한다.
	// 나중에 이 속성을 이용해서 책꽂이를 돌아다닌다.
    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;  // 책꽂이를 돌아다니기 전이므로, 0으로 초기화한다.
    }

    // 책꽂이에 접근할 책이 더 있는지 검사하는 메소드
    public boolean hasNext() {
		// 현재 책 번호가 책꽂이에 있는 책 개수보다 작으면,
	    // 책꽂이에 돌아다닐 책이 더 있는 것이므로 true를 반환한다.
        if (index < bookShelf.getLength()) {
            return true;
        } else {
            return false;
        }
    }

	// 다음 책을 얻어오고자 할 때 호출되는 메소드
	// 반환형이 Object 타입이다. 
	//  - Object는 모든 클래스의 부모 클래스이므로 모든 자식을 가리킬 수 있다.  
	//  - 즉, 모든 타입의 객체를 반환할 수 있다.
	//  - 실제로 반환되는 객체는 Book 타입이므로, 올바른 반환형으로 선언된 것이다.
    public Object next() {
        // 이 Iterator가 가리키는 책꽂이의 getBookAt(index)를 이용해서
		// index 책번호에 해당하는 책을 얻어와서 book에 저장한다.
		Book book = bookShelf.getBookFrom(index);
        // 현재 책번호를 1 증가시킨다.
		index++;
		// 얻어온 책을 반환한다.
        return book;
    }
}

<Main.java>

package ch01.Sample;

public class Main {
	// 모든 자바 프로그램은 main() 메소드부터 시작된다.
    public static void main(String[] args) {
    	// 최대 4권의 책을 담을 수 있는 책꽂이를 생성한다.
        BookShelf bookShelf = new BookShelf(4);
        Aggregate bookShelf2 = new BookShelf(4);
        // 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"));

		// 책꽂이의 Iterator를 얻어온다.
        // 실제 생성되는 객체의 타입은 BookShelfIterater이다.
		Iterator it = bookShelf.iterator();
        
		// 책이 계속해서 있으면 while 루프를 돈다.
		// 책이 더 있는지 검사하기 위해서, iterator의 hasNext()를 호출한다.
		while (it.hasNext()) {
			Book book = (Book)it.next(); // 다음 책을 얻어온다.
			// 위 문장 대신에
			// Object book = it.next();
			// 을 사용하면 안 된다.
            // 왜냐하면, 아래에서 book.getName()을 호출하는데,
			// Object 타입은 getName() 을 지원하지 않는다.
			// 따라서,  it.next( )가 반환한 Object 형을 Book 형으로 "강제형변환"해야 한다.

			// 책의 이름을 출력한다.
			System.out.println("" + book.getName());
           
        }

        // 책꽂이에 직접 접근해서 각 책을 얻어와서 책의 이름을 출력한다.
		// iterator를 사용하지 않는다.
		for(int i=0; i<bookShelf.getLength(); i++) {
			Book book = bookShelf.getBookFrom(i);
            System.out.println("" + book.getName());
	    }
    }
}
profile
가보자고

0개의 댓글

관련 채용 정보