제네릭 오버로딩을 대체할 수 있으며 유용하다.
메소드에 제네릭을 적용
1 2 3 4 5 6 7 8 public <T,P,Q,R> void println ( T t ) { System.out.println(t); } public static void main (String args[]) { println( 10 ); println( true ); }
메소드 반환형에 제네릭 적용
1 2 3 4 5 6 7 public <T, P> List<P> println ( T t ) { System.out.println( t ); List<P> list = new ArrayList <P>(); return list; }
제네릭 배열을 어떻게 동적으로 생성하느냐
1 2 3 4 5 6 7 8 9 10 11 12 13 public MyStack ( E[] objects, int capacity ) { buffer = ( E[] ) Array.newInstance(objects.getClass(), capacity); buffer = ( E[] )Array.newInstance(Object.class, capacity); buffer = ( E[] )new Object [capacity]; this .capacity = capacity; currentIndex = 0 ; }
제네릭 호출 방식
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void main (String[] args) { MyStack<String> stack = new MyStack <String>(3 ); MyStack<?> stack = new MyStack <String>(3 ); } public .... f(List<? extends Shape >){ ... }
가변변수 가변변수를 배우기 전에는 파라미터에 배열을 넣을 생각을 할 것이다. 하지만 이를 대체할 수 있는것이 가변변수이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static void main (String args[]) { println2( "둘리" ); println2( "둘리" , "마이콜" ); println2( "둘리" , "마이콜" , "또치" ); } public static void println2 (String ... params) { for ( String s : params){ System.out.println(s); } }
아래의 경우 Object를 파라미터로 주면 캐스팅을 계속 해줘야한다.
1 2 3 4 5 6 7 public <T> void println ( T t) { System.out.println(t); } public void println (Object o ) { System.out.println(o); }
익명클래스 파라미터를 전달하는 부분에서 객체를 생성하여 메소드를 호출. 객체를 생성하지 않고 메소드 호출부분에서 객체를 생성함.
1 2 3 4 5 6 7 8 9 draw( new Drawable () { @Override public void draw () { System.out.println("한 번만 만들고 버릴 도형을 그렸습니다" ); } });
Collection Collection인터페이스는 inteator() 메소드를 갖고 있다. List, Set 클래스는 Collection클래스를 구현하며 List는 중복허용, 순서를 갖는다. 그러나 Set는 중복을 허용하지 않으며 순서를 갖지 않는다. List인터페이스는 add, get, remove를 갖는다. LinkedList, ArrayList가 List 인터페이스를 구현한다.
ArrayList는 빈번한 삽입,삭제가 일어나는 경우 사용하면 안된다. 그 과정이 길기 떄문에. LinkedList는 삽입삭제가 유용하나 10000번째 놈이면 10000번을 next해야한다.
멀티스레드에서 ArrayList, LinkedList의 add를 사용할 때는 동기화 처리를 해줘야한다. 하지만 Vector은 멀티스레드 환경에서 동기화를 해주지 않아도 된다.
ArrayList , LinkedList, VectorTest2 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 public class ArrayListTest { public static void main (String[] args) { List<String> list = new ArrayList <String>(); LinkedList<String>(); Vector<String>(); list.add( "둘리" ); list.add( "마이콜" ); list.add( "도우넛" ); int count = list.size(); for ( int i = 0 ; i < count ; i++) { String s = list.get( i ); System.out.println(i); } list.remove( 1 ); Iterator<String> it = list.iterator(); while ( it.hasNext() ) { String s = it.next(); System.out.println( s ); } for ( String s : list) { System.out.println( s ); } } }
Vector 1.2 시대의 Vector인터페이스는 addElement, elementAt, removeElement, elements메소드를 갖고 있다. 그 후 1.2이후에 생긴 List를 구현하여 List의 메소드를 갖는다. Vector를 사용하려면 Vector 메소드를 사용하거나 List 인터페이스 내부의 메소드만 사용하든가 해야 복잡해지지 않는다.
과거 Vector을 사용하는 방식. 호환성 때문에 존재할뿐.. 사용일 지양하자.
VectorTest.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 public class VectorTest { public static void main (String[] args) { Vector<String> v = new Vector <String>(); v.addElement( "둘리" ); v.addElement( "마이콜" ); v.addElement( "도우넛" ); Enumeration<String> e = v.elements(); while ( e.hasMoreElements() ) { String s = e.nextElement(); System.out.println( s ); } v.removeElementAt( 1 ); System.out.println("=====================" ); int count = v.size(); for ( int i=0 ; i< count; i++) { String s = v.elementAt( i ); System.out.println( s ); } } }
Set Set 인터페이스는 key, value로 구성된다. key를 통해 value에 접근할 수 있다. HashSet, TreeSet가 Map인터페이스를 구현한다. hashCode를 오버라이드 하여 사용하여야 한다.
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 public class HashSetTest { public static void main (String[] args) { Set<Value> set = new HashSet <Value>(); Value v1 = new Value (10 ); Value v2 = new Value (5 ); Value v3 = new Value (10 ); Value v4 = new Value (20 ); set.add(v1); set.add(v2); set.add(v3); set.add(v4); System.out.println(set.contains(new Value (10 ))); set.remove( new Value (10 ) ); Iterator<Value> it = set.iterator(); while ( it.hasNext() ){ Value v = it.next(); System.out.println(v); } } }
성능향상을 위해 hash를 오버라이드 한다.
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 public class Value { private int value; public Value ( int value ) { this .value = value; } @Override public String toString () { return "Value [value=" + value + "]" ; } @Override public int hashCode () { final int prime = 31 ; int result = 1 ; result = prime * result + value; return result; } @Override public boolean equals (Object obj) { if (this == obj) return true ; if (obj == null ) return false ; if (getClass() != obj.getClass()) return false ; Value other = (Value) obj; if (value != other.value) return false ; return true ; }
Stack 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class StackTest { public static void main (String[] args) { Stack<String> stack = new Stack <String>(); stack.push("둘리" ); stack.push("마이콜" ); stack.push("도우넛" ); stack.push("길동" ); System.out.println( stack.isEmpty() ); System.out.println( stack.pop() ); System.out.println( stack.pop() ); System.out.println( stack.peek() ); System.out.println( stack.pop() ); System.out.println( stack.pop() ); System.out.println( stack.pop() ); } }
Queue 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class QueueTest { public static void main (String[] args) { Queue<String> queue = new LinkedList <String>(); queue.offer("둘리" ); queue.offer("마이콜" ); queue.offer("도우너" ); queue.offer("길동" ); System.out.println( queue.isEmpty() ); System.out.println( queue.poll() ); System.out.println( queue.poll() ); System.out.println( queue.peek() ); System.out.println( queue.poll() ); System.out.println( queue.poll() ); System.out.println( queue.isEmpty() ); System.out.println( queue.poll() ); } }
Map Map 인터페이스가 존재하는데 HashMap, HashTable가 이를 구현한다.
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 public static void main (String[] args) { Map<String, Integer> map = new HashMap <String, Integer>(); map.put("둘리" , 100 ); map.put("마이콜" , 50 ); map.put("도우넛" , 80 ); map.put("길동" , 90 ); map.put( "둘리" , 0 ); int score = map.get( "둘리" ); System.out.println(score); map.remove( "둘리" ); int sum = 0 ; Set<String> keySet = map.keySet(); Iterator<String> it = keySet.iterator(); while ( it.hasNext() ) { String key = it.next(); System.out.println( key ); int s = map.get( key ); sum += s; } System.out.println( "평균 : " + sum / keySet.size() ); }