item 31 Jung inchul - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
Effective Java 3e ์์ดํ 31๋ฅผ ์์ฝํ ๋ด์ฉ ์ ๋๋ค.
public class Stack<E> {
public Stack();
public void push(E e);
public E pop();
public boolean isEmpty();
public void pushAll(Iterable<E> src) {
for (E e : src)
push(e);
}
}
์ด ๋ฉ์๋๋ ๊นจ๋์ด ์ปดํ์ผ ๋์ง๋ง ์๋ฒฝํ์ง ์๋ค. Integer
๋ Number
์ ํ์ ํ์
์ด๋ ์ ๋์ํด์ผ ํ ๊ฒ ๊ฐ๋ค.
Strack<Number> numberStack = new Stack<>();
Iterable<Integer> intergers = ...;
numberStack.pushAll(integers);
ํ์ง๋ง ์ค์ ๋ก๋ ๋ค์์ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ฌ๋ค. ๋งค๊ฐ๋ณ์ํ ํ์
์ด ๋ถ๊ณต๋ณ
์ด๊ธฐ ๋๋ฌธ์ด๋ค.
StackTest.java:7: error: incompatible types: Iterable<Integer>
cannot be converted to Iterable<Number>
numberStack.pushAll(integers);
^
์๋ฐ๋ ์ด๋ฐ ์ํฉ์ ๋์ฒํ ์ ์๋ ํ์ ์ ์์ผ๋์นด๋
ํ์
์ด๋ผ๋ ํน๋ณํ ๋งค๊ฐ๋ณ์ํ ํ์
์ ์ง์ํ๋ค. pushAll
์ ์
๋ ฅ ๋งค๊ฐ๋ณ์ ํ์
์ 'E
์ Iterable
'์ด ์๋๋ผ 'E์ ํ์ ํ์
์ Iterable'์ด์ด์ผ ํ๋ฉฐ, ์์ผ๋์นด๋ ํ์
Iterable<? extends E>
๊ฐ ์ ํํ ์ด๋ฐ ๋ป์ด๋ค.
public void pushAll(Iterable<? extends E> src) {
for (E e : src)
push(e);
}
๊ธฐ๋ฅ ํ์ฅ์ผ๋ก ์๋์ ๊ฐ์ ๋ฉ์๋๊ฐ ์ถ๊ฐ๋์๋ค.
public void popAll(Collection<E> dst) {
when (!isEmpty())
dst.add(pop())
}
๊ทธ๋ฆฌ๊ณ ํด๋ผ์ด์ธํธ์์ ๋ค์๊ณผ ๊ฐ์ ์๋ฅผ ์คํํ๋ค๋ฉด ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์๊น?
Strack<Number> numberStack = new Stack<>();
Iterable<Object> objects = ...;
numberStack.popAll(objects);
์ด ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์์ popAll ์ฝ๋์ ํจ๊ป ์ปดํ์ผํ๋ฉด "Collection๋ Collection์ ํ์ ํ์ ์ด ์๋๋ค"๋ผ๋ ๋น์ทํ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์ด๋ฒ์๋ ์์ผ๋์นด๋
ํ์
์ผ๋ก ํด๊ฒฐํ ์ ์๋ค.
public void popAll(Collection<? super E> dst) {
when (!isEmpty())
dst.add(pop())
}
์ ์ฐ์ฑ์ ๊ทน๋ํ
ํ๋ ค๋ฉด ์์์ ์์ฐ์๋ ์๋น์์ฉ ์
๋ ฅ ๋งค๊ฐ๋ณ์์ ์์ผ๋์นด๋ ํ์
์ ์ฌ์ฉํ๋ผ ํํธ, ์
๋ ฅ ๋งค๊ฐ๋ณ์๊ฐ ์์ฐ์์ ์๋น์ ์ญํ ์ ๋์์ ํ๋ค๋ฉด ์์ผ๋์นด๋ ํ์
์ ์จ๋ ์ข์ ๊ฒ ์๋ค.
๋ค์ ๊ณต์์ ์ธ์๋๋ฉด ์ด๋ค ์์ผ๋์นด๋ ํ์ ์ ์จ์ผ ํ๋์ง ๊ธฐ์ตํ๋ ๋ฐ ๋์์ด ๋ ๊ฒ์ด๋ค.
ํฉ์ค(PECS) : producer-extends, consumer-super
์ฆ, ๋งค๊ฐ๋ณ์ํ ํ์
T๊ฐ ์์ฐ์
๋ผ๋ฉด <? extends T>๋ฅผ ์ฌ์ฉํ๊ณ , ์๋น์
๋ผ๋ฉด <? super T>๋ฅผ ์ฌ์ฉํ๋ผ. ์ด์ ์ ์์ฒ๋ผ pushAll์ Stack์ด ์ฌ์ฉํ E ์ธ์คํด์ค๋ฅผ ์์ฐํ๊ณ popAll์ Stack์ด E ์ธ์คํด์ค๋ฅผ ์๋นํ๋ ์ชฝ์ ์ํ๋ค.
๊ทธ๋ ๋ค๋ฉด ์๋์ ๊ฐ์ ๋ฉ์๋๋ ์ด๋ป๊ฒ ์์ ํด์ผ ํ ๊น?
public static <E> Set<E> union(Set<E> s1, Set<E> s2)
s1๊ณผ s2 ๋ชจ๋ E์ ์์ฐ์์ด๋ PECS
๊ณต์์ ๋ฐ๋ผ ๋ค์์ฒ๋ผ ์ ์ธํด์ผ ํ๋ค.
public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2)
๊ทธ๋ ๋ค๋ฉด ํด๋ผ์ด์ธํธ์์ ์๋์ ๊ฐ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
Set<Integer> integers = Set.of(1,3,5);
Set<Double> doubles = Set.of(2.0, 4.0, 6.0);
Set<Number> numbers = union(integers, doubles);
์์ ์ฝ๋๋ ์๋ฐ8๋ถํฐ ์ ๋๋ก ์ปดํ์ผ๋๋ค. ์๋ฐ7
๊น์ง๋ ์ด ์ฝ๋๋ฅผ ์ปดํ์ผํ๋ฉด ์ค๋ฅ ๋ฉ์์ง๋ฅผ ๋ณด๊ฒ ๋ ๊ฒ์ด๋ค.
Union.java:14: error: incompatible types
Set<Number> numbers = union(integers, doubles);
^
required: Set<Number>
found: Set<INT#1>
where INT#1, INT#2 are intersection types:
INT#1 extends Number, Comparable<? extends INT#2>
INT#2 extends Number, Comparable<?>
์ปดํ์ผ๋ฌ๊ฐ ์ฌ๋ฐ๋ฅธ ํ์ ์ ์ถ๋ก ํ์ง ๋ชปํ ๋๋ฉด ์ธ์ ๋ ๋ช ์์ ํ์ ์ธ์๋ฅผ ์ฌ์ฉํด์ ํ์ ์ ์๋ ค์ฃผ๋ฉด ๋๋ค.
Set<Number> numbers = Union.<Number>union(integers, doubles);
ํ์
๋งค๊ฐ๋ณ์์ ์์ผ๋์นด๋์๋ ๊ณตํต๋๋ ๋ถ๋ถ์ด ์์ด์, ๋ฉ์๋๋ฅผ ์ ์ํ ๋ ๋ ์ค ์ด๋ ๊ฒ์ ์ฌ์ฉํด๋ ๊ด์ฐฎ์ ๋๊ฐ ๋ง๋ค. ์๋ฅผ ๋ค์ด ์ฃผ์ด์ง ๋ฆฌ์คํธ์์ ๋ช
์ํ ๋ ์ธ๋ฑ์ค์ ์์ดํ
๋ค์ ๊ตํ(swap)ํ๋ ์ ์ ๋ฉ์๋
๋ฅผ ๋ ๋ฐฉ์ ๋ชจ๋๋ก ์ ์ ํด๋ณด์.
public static <E> void swap(List<E> list, int i, int j);
public static void swap(List<?> list, int i, int j);
public API
๋ผ๋ฉด ๊ฐ๋จํ ๋ ๋ฒ์งธ๊ฐ ๋ซ๋ค. ์ด๋ค ๋ฆฌ์คํธ๋ ์ด ๋ฉ์๋์ ๋๊ธฐ๋ฉด ๋ช
์ํ ์ธ๋ฑ์ค์ ์์๋ค์ ๊ตํํด ์ค ๊ฒ์ด๋ค.
์ด๋ ๋นํ์ ์ ํ์ ๋งค๊ฐ๋ณ์๋ผ๋ฉด ๋นํ์ ์ ์์ผ๋์นด๋๋ก ๋ฐ๊พธ๊ณ , ํ์ ์ ํ์ ๋งค๊ฐ๋ณ์๋ผ๋ฉด ํ์ ์ ์์ผ๋ ์นด๋๋ก ๋ฐ๊พธ๋ฉด ๋๋ค.
ํ์ง๋ง ์๋ ์ฝ๋๋ ์ปดํ์ผํ๋ฉด ๊ทธ๋ค์ง ๋์์ด ๋์ง ์๋ ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋์จ๋ค.
public static void swap(List<?> list, int i, int j) {
list.set(i, list.set(j, list.get(i));
}
์์ธ์ ๋ฆฌ์คํธ์ ํ์
์ด List<?>
์ธ๋ฐ, List<?>์๋ null
์ธ์๋ ์ด๋ค ๊ฐ๋ ๋ฃ์ ์ ์๋ค๋ ๋ฐ ์๋ค. ๋คํํ (๋ฐํ์ ์ค๋ฅ๋ฅผ ๋ผ ๊ฐ๋ฅ์ฑ์ด ์๋) ํ๋ณํ์ด๋ ๋ฆฌ์คํธ์ ๋ก ํ์
์ ์ฌ์ฉํ์ง ์๊ณ ๋ ํด๊ฒฐํ ๋ฐฉ๋ฒ์ด ์๋ค. ๋ฐ๋ก ์์ผ๋์นด๋ ํ์
์ ์ค์ ํ์
์ ์๋ ค์ฃผ๋ ๋ฉ์๋๋ฅผ private ๋์ฐ๋ฏธ ๋ฉ์๋
๋ก ๋ฐ๋ก ์์ฑํ์ฌ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
public static void swap(List<?> list, int i, int j) {
swapHelper(i, list.set(j, list.get(i));
}
public static <E> void swapHelper(List<E> list, int i, int j) {
list.set(i, list.set(j, list.get(i));
}
์กฐ๊ธ ๋ณต์กํ๋๋ผ๋ ์์ผ๋์นด๋
ํ์
์ ์ ์ฉํ๋ฉด API๊ฐ ํจ์ฌ ์ ์ฐํด์ง๋ค. ๊ทธ๋ฌ๋ ๋๋ฆฌ ์ฐ์ผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๋ฅผ ์์ฑํ๋ค๋ฉด ๋ฐ๋์ ์์ผ๋์นด๋ ํ์
์ ์ ์ ํ ์ฌ์ฉํด์ค์ผ ํ๋ค. PECS
๊ณต์์ ๊ธฐ์ตํ์. ์ฆ, ์์ฐ์(producer)๋ extends๋ฅผ ์๋น์(consumer)๋ super๋ฅผ ์ฌ์ฉํ๋ค. Comparable
๊ณผ Comparator
๋ ๋ชจ๋ ์๋น์๋ผ๋ ์ฌ์ค๋ ์์ง ๋ง์