Java 디자인 패턴-04.Iterators
(Java 디자인 패턴 스터디 모집 중 : https://github.com/bluedskim/javaDesignPatterns)
패턴 다이어그램
“하나의 집합Collection의 모든 요소를 모두 접근하는 방법은 여러가지가 있을 수 있다”
(출처:https://refactoring.guru/design-patterns/iterator)
해결하려는 문제
- 집합collection의 각각 항목 모두를 접근할 수 있는 일관된 방법을 제공.
특징/용도
- behavioral design patterns의 하나
- iterator는 해당 집합의 실제 구현과는 무관하다(Information Hiding, Separation of concerns).
고려사항
- Java 1.2 부터 Iterable, Iterator 인터페이스가 포함되어 있으므로 직접 만들 필요가 없다.
클래스 다이어그램
소스
- target
- MyIterable.java : 컨테이너가 구현해야하는 인터페이스
1
2
3
4
5
6
7
|
package net.dskim.desingpattern.iterator;
import java.util.Iterator;
public interface MyIterable extends Iterable<Object> {
public Iterator<Object> reverseIterator();
}
|
- ArrayContainer.java : 배열을 가지고 있는 객체
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package net.dskim.desingpattern.iterator;
import java.util.Iterator;
/***
* 배열을 위한 컨테이너
*/
public class ArrayContainer implements MyIterable {
Iterator<Object> arrayIterator;
Iterator<Object> reverseArrayIterator;
public ArrayContainer(Object[] array) {
arrayIterator = new ArrayIterator(array);
reverseArrayIterator = new ReverseArrayIterator(array);
}
@Override
public Iterator<Object> iterator() {
return arrayIterator;
}
@Override
public Iterator<Object> reverseIterator() {
return reverseArrayIterator;
}
}
|
- ArrayIterator.java : 배열학목을 순서대로 접근하기 위한 iterator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package net.dskim.desingpattern.iterator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import lombok.extern.slf4j.Slf4j;
/***
* 배열을 위한 iterator
*/
@Slf4j
public class ArrayIterator implements Iterator<Object>{
Object[] array;
int index = 0;
public ArrayIterator(Object[] array) {
this.array = array;
}
@Override
public boolean hasNext() {
return index <= array.length - 1;
}
@Override
public Object next() {
if(!hasNext()) throw new NoSuchElementException();
return array[index++];
}
}
|
- ReverseArrayIterator.java : 배열학목을 역순으로 접근하기 위한 iterator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package net.dskim.desingpattern.iterator;
import java.util.Iterator;
import java.util.NoSuchElementException;
/***
* 배열 index가 높은 항목에서 낮은 항목으로 탐색하는 iterator
*/
public class ReverseArrayIterator implements Iterator<Object>{
Object[] reverseArray;
int nextIndex = 0;
public ReverseArrayIterator(Object[] originalArray) {
reverseArray = new Object[originalArray.length];
for(int reverseArrayIndex = 0 ; reverseArrayIndex < reverseArray.length ; reverseArrayIndex++){
reverseArray[reverseArrayIndex] = originalArray[originalArray.length - 1 - reverseArrayIndex];
}
}
@Override
public boolean hasNext() {
return nextIndex <= reverseArray.length - 1;
}
@Override
public Object next() {
if(!hasNext()) throw new NoSuchElementException();
return reverseArray[nextIndex++];
}
}
|
- client : IteratorTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
package net.dskim.desingpattern.iterator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.junit.jupiter.api.Test;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class IteratorTest {
/**
* java.util.List의 iterator테스트
*/
@Test
void listIteratorTest() {
List<String> names = new ArrayList<String>();
names.add("Ajay");
names.add("Vijay");
names.add("Martin");
names.add("Racheal");
names.add("Kim");
Iterator<String> namesIterator = names.iterator();
int i = 0;
while (namesIterator.hasNext()) {
assertEquals(names.get(i++), namesIterator.next());
}
}
@Test
void arrayIteratorTest() {
String[] names = {
"Ajay"
,"Vijay"
,"Martin"
,"Racheal"
,"Kim"
};
MyIterable arrayContainer = new ArrayContainer(names);
int i = 0;
Iterator<Object> arrayIterator = arrayContainer.iterator();
while (arrayIterator.hasNext()) {
assertEquals(names[i++], arrayIterator.next());
}
i = 0;
Iterator<Object> reverseArrayIterator = arrayContainer.reverseIterator();
while (reverseArrayIterator.hasNext()) {
assertEquals(names[names.length - (++i)], reverseArrayIterator.next());
}
}
}
|
참고