김찬진의 개발 블로그
[23/07/17] Iterable, Iterator, generics wildcard 종합연습 본문
상황 가정
- 커스텀 컬렉션 클래스 MyCollection 을 만들었다
- MyCollection 은 Iterable 인터페이스, Iterator 인터페이스를 상속받고 각 메서드들을 구현했다
- Iterable 인터페이스 : iterator() (forEach(), spliterator() 는 default method이므로 오버라이딩X)
- Iterator 인터페이스: hasNext(), next() (remove(), forEachRemaining() 는 default method이므로 오버라이딩X)
(커스텀 컬렉션 클래스이므로 Iterable 인터페이스를 상속받고 iterator() 메서드를 오버라이딩했다. 만약 옛날 컬렉션 클래스라면 Iterable 인터페이스를 상속받지 않고 직접 구현했을 것이다)
package java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) { // 와일드카드, super로 다형성 꾀함
Objects.requireNonNull(action);
for (T t : this) { // this: Iterable 인터페이스를 상속받은 컬렉션 클래스(조상 클래스 포함)를 의미
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
package generics;
import java.util.Iterator;
import java.util.function.Consumer;
class Fruit {
private String name;
public Fruit(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Apple extends Fruit {
private String color;
public Apple(String name, String color) {
super(name);
this.color = color;
}
public String getColor() {
return color;
}
}
class MyCollection<T> implements Iterable<T> {
private T[] elements;
private int size;
public MyCollection(int capacity) {
elements = (T[]) new Object[capacity];
size = 0;
}
public void add(T element) {
if (size < elements.length) {
elements[size] = element;
size++;
}
}
@Override
public Iterator<T> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<T> {
private int currentIndex;
public MyIterator() {
currentIndex = 0;
}
@Override
public boolean hasNext() {
return currentIndex < size;
}
@Override
public T next() {
T element = elements[currentIndex];
currentIndex++;
return element;
}
}
}
public class GTest3 {
public static void main(String[] args) {
MyCollection<Apple> apples = new MyCollection<>(3);
apples.add(new Apple("Apple 1", "Red"));
apples.add(new Apple("Apple 2", "Green"));
Consumer<Object> objectConsumer = object -> {
System.out.println("Object: " + object);
};
// Consumer<Object> objectConsumer1 = new Consumer<Object>() {
// @Override
// public void accept(Object object) {
// System.out.println("Object: " + object);
// }
// }
Consumer<Fruit> fruitConsumer = fruit -> {
System.out.println("Fruit: " + fruit.getName());
// System.out.println("Fruit: " + fruit.getColor());
};
Consumer<Apple> appleConsumer = apple -> {
System.out.println("Apple Name: " + apple.getName());
System.out.println("Apple Color: " + apple.getColor());
};
apples.forEach(objectConsumer); // Object 타입으로 처리
apples.forEach(fruitConsumer); // Fruit 타입으로 처리
apples.forEach(appleConsumer); // Apple 타입으로 처리
// 이 모든 것은 forEach(Consumer<? super T> action) {...} 덕분
}
}
'1일1배움 > Java' 카테고리의 다른 글
[23/07/20] 메서드 참조 :: (0) | 2023.07.20 |
---|---|
[23/07/18] Comparable, Comparator (0) | 2023.07.18 |
[23/07/17] Iterable, Iterator (0) | 2023.07.17 |
[23/07/17] 문자열 객체, 문자열 리터럴, StringBuilder, StringBuffer (0) | 2023.07.17 |
[23/07/17] JDK, JRE, JVM (0) | 2023.07.17 |
Comments