Week14(Generic)
์ ๋ค๋ฆญ์ ๊ธฐ๋ณธ ๊ฐ๋
์ ๋ค๋ฆญ์ ๋ชจ๋ ์ข ๋ฅ์ ํ์ ์ ๋ค๋ฃฐ ์ ์๋๋ก, ํด๋์ค๋ ๋ฉ์๋์ ๋งค๊ฐ๋ณ์(generic type)์ ์ด์ฉํ์ฌ ์ ์ธํ๋ ๊ธฐ๋ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋ณธ ๋ ์ฐ์ด๋ด๊ธฐ ์ํด ๋ง๋ค์ด์ง ํ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ํธํ๋ค. ์๋ฐ์์์ ์ ๋ค๋ฆญ์ ํด๋์ค ์ฝ๋๋ฅผ ์ฐ์ด๋ด๋ฏ์ด ์์ฐํ ์ ์๋๋ก ์ผ๋ฐํ(generic)์ํค๋ ๋๊ตฌ์ด๋ค.
+์ ๋ค๋ฆญ ํ์
๋งค๊ฐ๋ณ์
์ฌ๊ธฐ์ ํ์ ๋งค๊ฐ ๋ณ์๋ก ์ฌ์ฉํ๋ ๋ฌธ์๋ ๋ค๋ฅธ ๋ณ์์ ํผ๋์ ํผํ๊ธฐ ์ํด ์ผ๋ฐ์ ์ผ๋ก ํ๋์ ๋๋ฌธ์๋ฅผ ์ฌ์ฉ
E : Element์ ์๋ฏธํ์ฌ ์ปฌ๋ ์ ์์ ์์์์ ๋ํ๋
T : Type์ ์๋ฏธ
V : Value์ ์๋ฏธ
K : Key์ ์๋ฏธ
์ ๋ค๋ฆญ ์ปฌ๋ ์
์์ฑ
๋ฒกํฐ ์์ฑํ ๋, Vector ์ E์ ์์๋ฅผ ์ฌ์ฉํ ํ์ ์ ์ง์ ํด์ผ ํ๋ค. ์๋ฅผ ๋ค์ด, ์ ์ ๊ฐ๋ง ์ฝ์ ๊ฐ๋ฅํ ๋ฒกํฐ๋ฅผ ๋ง๋ค๊ณ ์ ํ๋ฉด ๋ค์ ๊ณผ ๊ฐ์ด E์ Integer๋ฅผ ์ง์ ํ์ฌ ์ฌ์ฉ๊ฐ๋ฅ
Vector<Integer> v = new Vector<Integer>();
์ด๋ ๊ฒ ๋ฐ์ดํฐ์ ํ์ ์ ๋ฃ์ด์ค์ผํ๋๋ฐ
int, char, double ๋ฑ์ ๊ธฐ๋ณธ ํ์ ์ E์ ์ฌ์ฉํ ์ ์๋ค.
Vector<int> v = new Vector<int>();
->์ด๋ ๊ฒ ํ๋ฉด ์๋ฌ๊ฐ ๋๊ฒ ๋๋ค.
Vector<Integer> v = new Vector<Integer>(5);
์ด๋ ๊ฒ ์ด๊ธฐ ์ฉ๋์ ์ง์ ํ ์ ์์ง๋ง ๊ฐ๋ฐ์๋ ์์ฑ๋ ๋ฒกํฐ์ ์ฉ๋์ ๊ตณ์ด ์ ํ์ ์๋ค. ์ปฌ๋ ์ ์ ์์ ์ ์ฉ๋์ ์ค์ค๋ก ์กฐ์ ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๊ฒ ๋ ์ ๋ค๋ฆญ์ ์ฅ์ ์ด๋ค
Vector E ํด๋์ค์ ์ฃผ์๋ ๋ฉ์๋
boolean add(E element)
๋ฒกํฐ์ ๋งจ ๋ค์ element ์ถ๊ฐ
void add(int index, E element)
์ธ๋ฑ์ค index์ element๋ฅผ ์ฝ์
int capacity()
ํ์ฌ ๋ฒกํฐ์ ์ฉ๋์ ๋ฆฌํด
void clear()
๋ฒกํฐ์ ๋ชจ๋ ์์ ์ญ์
boolean contains(Object o)
๋ฒกํฐ๊ฐ ์ง์ ๋ ๊ฐ์ฒด๋ฅผ o์ด ํฌํจํ๊ณ ์๋ค๋ฉด true๋ฅผ ๋ฆฌํด
E elementAt(int index)
index ์์น์์์ ์์ ๋ฆฌํด
E get(int index)
index ์์น์์์ ์์ ๋ฆฌํด
E remove(int index)
index ์์น์์์ ์์ ์ญ์
int size()
๋ฒกํฐ๊ฐ ํฌํจ๋๋ ์์์ ๊ฐฏ์ ๋ฆฌํด
๋ฒกํฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ์์
๋ฒกํฐ์์์ ์ฝ์ ์ ๋ฒกํฐ์ ๋์ด๋ ์ค๊ฐ์ ์์๋ฅผ ์ฝ์ ํ ์ ์์
import java.util.Vector;
public class vTest {
public static void main(String[] args) {
Vector<Integer> v = new Vector<>();
//์๋๋ ์ ์๋ฅผ Integer ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฝ์
v.add(new Integer(1));
v.add(new Integer(2));
//์๋ ๋ฐ์ฑ ๊ธฐ๋ฅ์ ํ์ฉํ๋ฉด ๊ตณ์ด Integer ๊ฐ์ฒด๋ก ๋ณํ๋์ด ์ฝ์
๋ ์ ์์
v.add(3);
v.add(4);
//๋ง์ฝ ์ฌ๊ธฐ์์ ๋ค๋ฅธ ๊ฐ์ฒด ํ์
์ ๋ฃ์๋ ค๊ณ ์๋ํ๋ฉด ์๋ฌ๊ฐ ์๊ธด๋ค
// v.add("hello");
// v.add(new Double(3,5));
//๋ฒกํฐ์๋ null๋ ์ฝ์
ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฒกํฐ๋ฅผ ๊ฒ์ํ ๋ null์ด ์กด์ฌํ ์๋ ์์
v.add(null);
//์ํ๋ ์์น์ ๋ฒกํฐ๋ฅผ ์
๋ ฅํ๊ธฐ ์ํด์๋ 2๊ฐ์ ์ธ์๋ฅผ ๊ฐ์ง ํจ์์ฌ์ฉ
//์ด๋ ๊ฒ ๋๋ฉด 2๋ฒ์งธ ์์น์ 100์ด ๋ค์ด๊ฐ๊ฒ ๋๋ค.
v.add(2, 100);
//1, 2, 100, 3, 4 ์ฌ๊ธฐ๊น์ง ํด๋์ด์ผํจ
//์ธ๋ฑ์ค์ ์๋ ์์๋ฅผ ์ญ์ ํ ์ ์๋ค.
//๋ฒกํฐ์์์ 3๋ฒ์งธ ๊ฐ์ด ์์ด์ ธ์ผํ๋๊น 3์ด ์์ด์ ธ์ผ ํ๋ค
v.remove(3);
for(int i=0; i<v.size(); i++){
System.out.println(v.get(i));
}
}
}

์ ๋ค๋ฆญ ๋ง๋ค๊ธฐ
์ ๋ค๋ฆญ ํด๋์ค
๊ธฐ์กด์ ํด๋์ค๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ๊ณผ ์ ์ฌํ์ง๋ง ์ฐจ์ด์ ์ด ์๋ค๋ฉด ํด๋์ค ์ด๋ฆ ๋ค์์ ์ผ๋ฐํ๋ ํ์ ์ ๋งค๊ฐ๋ณ์๋ฅผ <> ์ฌ์ด์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฐจ์ด๊ฐ ์๋ค.
import java.util.Vector;
public class vTest {
//์ ๋ค๋ฆญ ํด๋์ค์ด๋ฉฐ ํ์
๋งค๊ฐ๋ณ์๋ T
static class MyClass<T>{
//๋ณ์ val์ ํ์
์ T
T val;
void set(T a){
val = a;
}
T get(){
return val;
}
}
public static void main(String[] args) {
//T์๋ฆฌ์ ๊ตฌ์ฒด์ ์ธ ํ์
์ ๋ฃ์ด์ฃผ๊ณ ์ฌ์ฉํ ์ ์๋ค.
MyClass<String> s = new MyClass<String>();
//์ด๋ ๊ฒ ๊ฐ์ ๋ฃ์ด์ฃผ๊ณ ์ถ๋ ฅํ ์ ์๋ค.
s.set("HELLO!");
System.out.println(s.get());
//๊ตฌ์ฒดํํ ๋๋ ๊ธฐ๋ณธํ์
์ฌ์ฉ ๋ถ๊ฐ๋ฅ(๋ฐ๋ก ๋ฐ ์ฃผ์)
//MyClass<int> i = new MyClass<int>();
MyClass<Integer> i = new MyClass<Integer>();
i.set(5);
System.out.println(i.get());
}
}
์ ๋ค๋ฆญ ๋ฉ์๋
ํ๋์ ๋ฉ์๋ ์ ์ธ์ผ๋ก ๋ง๋ค์ด์ง๋ฉฐ ๋ค๋ฅธ ํ์ ๋ค์ ์ธ์๋ก ๋ฐ์์ ํธ์ถ ๋ ์ ์๋ ๋ฉ์๋์ด๋ค
์๋ฅผ ๋ค์ด์ ๋ฐฐ์ด์ ๋ฆฌ์คํธ๋ก ๋ณํํ๋ ์ ๋ค๋ฆญ ๋ฉ์๋๋ฅผ ์ ์ํ๋ ์์
public <T> List<T> fromArrayToList(T[] a){
return Arrays.stream(a).collect(Collectors.toList());
}
์ฌ๊ธฐ์ ๋ณด๋ฉด ๋ฉ์๋๋ ํ๋์ด์์ ์ ๋ค๋ฆญ ํ์ ์ ์ฒ๋ฆฌํ ์ ์๊ณ , ๋ชจ๋ ์ ๋ค๋ฆญ ํ์ ๋ค์ด ๋ฉ์๋์ ๋ฆฌํด ํ์ ์ ์์น์ ์ถ๊ฐ๋์ด์ผํ๋ค.
Bounded Type Parameter
ํ์ ํ๋ผ๋ฏธํฐ๋ค์ bound๋ ์ ์๋๋ฐ, bound๋๋ค๋ ์๋ฏธ๋ ์ ํ๋๋ค๋ ์๋ฏธ์ด๊ณ , ์ฝ๊ฒ ์๊ฐํ๋ฉด ๋ฉ์๋๊ฐ ๋ฐ์ ์ ์๋ ํ์ ์ ์ ํํ ์ ์๋ค๋ ๋ป
public class Box<T> {
private T t;
public void set(T t){
this.t =t;
}
public T get() {
return t;
}
public <U extends Number> void inspect(U u){
//์ฌ๊ธฐ์ ํ์
ํ๋ผ๋ฏธํฐ U์ Number๋ก ์ ํํ์ -> extends ํค์๋๋ฅผ ์ฌ์ฉ
//์ด๋ ๊ฒ ๋๋ฉด U์๋ Integer๋, Float, Double์ ๊ฐ์ ํด๋์ค๋ค๋ง ์ฌ์ฉ๊ฐ๋ฅ
System.out.println("T: "+t.getClass().getName());
System.out.println("U: "+u.getClass().getName());
}
public static void main(String[] args) {
Box<Integer> ibox = new Box<Integer>();
ibox.set(10);
//๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ ๋ฐ์ ์ฃผ์๋ถ๋ถ์ ์๋ฌ๊ฐ ๋ ์๋ฐ์ ์๋ค
//ibox.inspect("some text");
}
}
WildCard
์๋ฐ์์ ์์ผ๋ ์นด๋๋ "?"์ผ๋ก ํ์ํ๋ฉฐ ์ ์ ์๋ ํ์ ์ ์๋ฏธํ ๋ ์ฌ์ฉ๋๋ค. ์์ผ๋ ์นด๋๋ ๋ค์ํ ์ํฉ์์ ์ฌ์ฉ๋ ์ ์๋ค. ๋งค๊ฐ๋ณ์์ ํ์ , ํ๋ ๊ทธ๋ฆฌ๊ณ ์ง์ญ๋ณ์๋ก ์ฌ์ฉ๋ ์ ์๋ค.
Object๋ ๋ชจ๋ ์๋ฐ ํด๋์ค๋ค์ ๋ถ๋ชจ ํ์ ์ด๊ธด ํ์ง๋ง Object ์ปฌ๋ ์ ์ด ๋ค๋ฅธ ์ปฌ๋ ์ ๋ค์ ๋ถ๋ชจ๋ ์๋๋ค.
LIst ํ์ ์ ๋ณ์์ List๋ณ์๋ฅผ ํ ๋นํ๊ฒ ๋๋ฉด ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฐ์๋๋ ๊ฒ์ ๋ณด๊ณ ํ์ธํ ์ ์๋ค.
์ด๋ ๊ฒ ํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ ์ปฌ๋ ์ ์์ ์๋ก ๋ค๋ฅธ ํ์ ๋ค์ ์ถ๊ฐํ ๊ฒฝ์ฐ ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ฅผ ๋ง๊ธฐ ์ํ ๊ฒ์ด๋ค.
Upper Bounded Wildcards
์ด๊ฒ์ ์ฌ์ฉํ๋ฉด ๋ณ์์ ๋ํ ์ ํ์ ์ค์ฌ์ค ์ ์๋ค.
์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ "?" ์ extends ํค์๋ ์์ ๋ถ์ฌ์ฃผ๋ฉด ๋๋ค.
public static double sumOfList(List<? extends Number> list) {
double s = 0.0;
for (Number n : list)
s += n.doubleValue();
return s;
}
List<Integer> li = Arrays.asList(1, 2, 3);
System.out.println("sum = " + sumOfList(li));
List<Double> ld = Arrays.asList(1.2, 2.3, 3.5);
System.out.println("sum = " + sumOfList(ld));
์ฌ๊ธฐ์ sumOfList ํจ์๋ Number์ sub type๊น์ง ๋ค ์ฌ์ฉ๋ ์ ์๊ฒ ๋๋ค.
Unbounded Wildcards
printList๋ผ๋ ๋ฉ์๋๋ฅผ ์๊ฐํด๋ณด์, printListํจ์์ ๋ชฉ์ ์ ์ด๋ ํ์ ์ด๋ ์ง ์ถ๋ ฅํ๊ธฐ ์ํจ์ด์ง๋ง ๋ถ๊ฐ๋ฅํ๋ค. ์๋ํ๋ฉด ์ด๊ฒ์ ์ค์ง Object์ list๋ง ์ถ๋ ฅํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ, List, List๋ฑ ์ด๋ฐ ๊ฒ๋ค์์ List์ ์๋ธํ์ ์ด ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
public static void printList(List<Object> list) {
for (Object elem : list)
System.out.println(elem + " ");
System.out.println();
}
๊ทธ๋์ ์ด ํจ์๋ฅผ
public static void printList(List<?> list) {
for (Object elem: list)
System.out.print(elem + " ");
System.out.println();
}
์ด๋ ๊ฒ ์์ผ๋์นด๋์ธ "?" ์ ์ฌ์ฉํด์ค์ ๋ณ๊ฒฝํ๊ฒ ๋๋ฉด
List<Integer> li = Arrays.asList(1, 2, 3);
List<String> ls = Arrays.asList("one", "two", "three");
printList(li);
printList(ls);
์ด๋ ๊ฒ ์ฌ์ฉํ๋๋ฐ์ ๋ฌธ์ ๊ฐ ์๋ค!
Lower Bounded Wildcards
์๋ upper bounded wildcard๊ฐ ๋ชจ๋ฅด๋ ํ์ ์ ์์ธํ ํ์ ์ด๋ ์๋ธํ์ ์ผ๋ก ๋ณํ๋์ง ์๋๋ก ์ ํํ์ผ๋ฉฐ, extends ํค์๋ ์์์ ์ฌ์ฉํ๋ค๋ฉด lower bounded wildcard๋ ํด๋น ํ์ ์ super ํ์ ๊น์ง ํ์ฉํด์ฃผ๋ฉฐ, super ํค์๋ ์์ ์์ผ๋์นด๋์ธ "?" ์ ๋ถํ์ ์ฌ์ฉํ๋ค.
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}
๋ ๋ค๋ฅธ ์์๋ฅผ ๋ค์ด์ Integer์ lists์ ๋ํ ๋ฉ์๋๊ฐ ํ์ํ๊ฒ๋๋ฉด
List<? super Integer> ์ด๋ ๊ฒ ์์ฑํจ์ผ๋ก์จ
Integer์ superํ์ ์ธ Integer, Number, Ojbect์ด๋ ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
๊ทธ๋ฅ List ์ด๋ ๊ฒ ์ฐ๋๊ฒ๋ณด๋ค ๋ฒ์ฉ์ฑ์ด ๋์ด์ง๋ค๊ณ ์๊ฐํ๋ค.
Erasure Type
์ ๋ค๋ฆญ์ ์๋ฐ ์ธ์ด๋ฅผ ์ฌ์ฉํจ์ ์์ด์ ์ปดํ์ผ ์, ๋ ๋นก๋นกํ ํ์ ์ฒดํฌ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ฉฐ, ์ ๋ค๋ฆญ ํ๋ก๊ทธ๋๋ฐ์ ๋์์ค๋ค. ์ปดํ์ผ๋ฌ๋ ์ปดํ์ผ ์, ์ ๋ค๋ฆญ์ ๋ํด์ type erasure๋ผ๋ ํ๋ก์ธ์ค๋ฅผ ์ ์ฉํ๋ค
๋ชจ๋ ํ๋ผ๋ฏธํฐ๋ค์ ๊ทธ๋ค์ ๋ฒ์ฃผ์์์ ์ ๋ค๋ฆญ ํ์ ์ผ๋ก ๋ณ๊ฒฝํ๋ค.
ํ์ ์ ์์ ์ฑ์ ์ ์งํ๊ธฐ ์ํด ํ์ํ ๊ฒฝ์ฐ, ํ์ ์บ์คํธ๋ฅผ ์งํ
์์๋ฅผ ๋ณด๋ฉด์ ํ์ธ
public <T> List<T> genericMethod(List<T> list) {
return list.stream().collect(Collectors.toList());
}
์ด๋ ๊ฒ ์งํ์ ํ๋ ค๊ณ ํ๋ฉด
public <T> List<T> genericMethod(List<Object> list) {
return list.stream().collect(Collectors.toList());
}
ํ์ ์ด๋ ์ด์ ๊ฐ ์ ์ฉ๋๋ฉด์ ํน์ ํ์ ์ผ๋ก ์ ํ๋์ง ์์ T๋ฅผ ์์ ๊ฐ์ด Object๋ก ๋์ฒด๋๋ค
๋ง์ฝ
public <T extends Building> void genericMethod(T t){
...
}
์ด๋ ๊ฒ ํ์ ์ด ์ ํ๋์ด์์ ๊ฒฝ์ฐ์๋ ์ด ํ์ ์ ์ปดํ์ผ ์์ ์์ ์ ํ๋ ํ์ ์ผ๋ก ๊ต์ฒด
public void genericMethod(Building t){
...
}
์ด๋ ๊ฒ ์ ๋ค๋ฆญ์ ๊ดํด์ ์์๋ณด์๊ณ , ์ ๋ค๋ฆญ์ ํ์ ์ ์ ํ์ฑ์ ์ ํํ๊ฒ ํด์ฃผ๋ฉฐ, ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ํ์ฌ๊ธ ์ถ๊ฐ์ ์ธ ์ค๋ฒํค๋ ์์ด ์ ๋ค๋ฆญ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํ์ ๊ฐ๋ฅํ๋๋ก ๋์์ฃผ๋๊ฑฐ ๊ฐ๋ค
์ฐธ๊ณ ์ฌ์ดํธ
๋ช ํ ์๋ฐ ํ๋ก๊ทธ๋๋ฐ - ํฉ๊ธฐํ
https://medium.com/์ฌ๊ธฐ๋ก์ด-๊ฐ๋ฐ์ํ/java-generic-์๋ฐ-์ ๋ค๋ฆญ-f4343fa222df
https://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
Last updated
Was this helpful?