380 likes | 520 Views
Java Programming. 2013 Summer V acation MIS Java Study Group. Chapter07. 제네릭과 컬렉션. 7.1 컬렉션과 제네릭. 7 .2 제네릭 컬렉션 활용. 7 .3 제네릭 만들기. 컬렉션과 제네릭. 1. 컬렉션 (collection) 의 개념. 컬렉션 컬렉션은 요소 (element) 라고 불리는 가변 개수의 객체들의 모음 객체들의 컨테이너라고도 불림 컬렉션 클래스 예
E N D
Java Programming 2013 SummerVacation MIS Java StudyGroup
Chapter07.제네릭과 컬렉션 7.1 컬렉션과 제네릭 7.2 제네릭 컬렉션 활용 7.3 제네릭 만들기
컬렉션과 제네릭 1. 컬렉션(collection)의 개념 • 컬렉션 • 컬렉션은 요소(element)라고 불리는 가변 개수의 객체들의 모음 • 객체들의 컨테이너라고도 불림 • 컬렉션 클래스 예 • Vector, ArrayList, Hashtable, LinkedList, HashMap, HashSet, Stack • java.util패키지에서 제공 • 다양한 객체들을 삽입, 삭제, 검색 등 관리하는데 사용됨
컬렉션과 제네릭 1. 컬렉션을 위한 인터페이스와 클래스 Collection<E> Set<E> List<E> Queue<E> Map<K, V> 인터페이스 클래스 HashSet<E> ArrayList<E> Vector<E> LinkedList<E> HashMap<K, V> Stack<E>
제네릭 컬렉션 활용 2. Vector 클래스 • Vector의 특성 • java.util.Vector • 여러 객체들을 삽입, 삭제, 검색하는 컨테이너 클래스 • 배열의 길이 제한 단점 극복 • 원소의 개수가 넘쳐나면 자동으로 늘어나는 가변 길이 • Vector에 삽입 가능한 것 • 객체만 가능 • null도 삽입 가능 • 기본 데이터 타입은 불가능 • Wrapper 객체로 만들어 삽입 가능 • Vector에 객체삽입 • 벡터의 맨 뒤에 객체 추가 : 공간이 모자라면 자동 늘림 • 벡터 중간에 객체 삽입 : 삽입된 뒤의 객체는 뒤로 하나씩 이동 • Vector에서 객체 삭제 • 임의의 위치에 있는 객체 삭제 가능 : 객체 삭제 후 하나씩 앞으로 자동 이동
제네릭 컬렉션 활용 2. Vector<Integer> 객체의 내부 구성 add()를 이용하여 요소를 삽입하고 get()을 이용하여 요소를검색합니다 Vector<Integer> 컬렉션 객체 Integer 0 1 2 3 4 5 6 add(Integer) Integer(10) get(3) get(i) Integer(10) 10 5 4 -1 10 Integer Integer Integer Integer
Vector 객체 v Vector 객체 생성 Vector<Integer> v = new Vector<Integer>(); 요소 객체 삽입 v v.add(5); v.add(new Integer(4)); v.add(-1); 5 4 -1 Integer Integer Integer 요소객체개수 n 벡터의 용량 c int n = v.size(); // n은 3 int c = v.capacity(); //c는 7 n = 3 c = 7 v 요소 객체 중간 삽입 v.add(2, “100"); v.add(5, “100"); // v.size()인 3 보다 큰 곳에 삽입 불가능, 오류 5 4 100 4 Integer Integer Integer Integer obj 요소 객체 얻어내기 Integer obj = (Integer)v.get (1); inti = obj.intValue(); i = 4
v 요소 객체 삭제 v.remove(1); v.remove(4); // 인덱스 4에 요소 객체가없으므로 오류 5 100 -1 Integer Integer Integer last = -1 마지막 요소 객체 int last = v.lastElement(); v 모든 요소 객체 삭제 v. removeAllElements();
제네릭 컬렉션 활용 2. 컬렉션과 자동 박싱/언박싱 • JDK 1.5 이전 버전 • Wrapper 클래스를 이용하여 기본 타입을 객체로 만들어 사용 Vector v = new Vector(); v.add(new Integer(4)); v.add(new Character(’r’)); v.add(new Double(3.14)); • 컬렉션으로부터 요소를 얻어올 때도 해당 타입의 값을 얻어오는 메소드를 호출 Integer n = (Integer)v.get(0); int k = n.intValue(); // k = 4 • JDK 1.5부터 • 자동 박싱/언박싱의 기능 추가 Vector v = new Vector(); v.add(4); // 4 → new Integer(4)로 자동 박싱 v.add(’r’); // ’r’ → new Character(’r’)로 자동 박싱 v.add(3.14); // 3.14 → new Double(3.14)로 자동 박싱 int k = v.get(0); // Integer 타입이 int타입으로 자동 언박싱, k = 4
(2, 3) (-5, 20) (30, -8)
제네릭 컬렉션 활용 2. ArrayList<E> • ArrayList의 특성 • java.util.ArrayList • 가변 크기 배열을 구현한 클래스 • ArrayList에 삽입 가능한 것 • 객체만 가능 • 기본 데이타 타입은 불가능 • Wrapper 객체로 만들어 삽입 가능 • null도 삽입 가능 • ArrayList에 객체 삽입 • 리스트의 맨 뒤에 객체 추가 : 공간이 모자라면 자동 늘림 • 리스트의 중간에 객체 삽입 : 삽입된 뒤의 객체는 뒤로 하나씩 이동 • ArrayList에서객체 삭제 • 임의의 위치에 있는 객체 삭제 가능 : 객체 삭제 후 하나씩 앞으로 이동 • 벡터와 거의 유사하며 자동으로 스레드 동기화를 지원하지 않는 점이 가장 큰 차이 • 다수의 스레드가 동시에 ArrayList에 접근할때 ArrayList는 동기화시키지 않음 • ArrayList에 접근하는 곳에서 스레드 동기화를 수행하여야 함
제네릭 컬렉션 활용 2. ArrayList<String> 객체의 내부 구성 add()를 이용하여 요소를 삽입하고 get()을 이용하여 요소를검색합니다 ArrayList<String> 컬렉션 객체 String 0 1 2 3 4 5 6 add(String) “사과” get(3) get(i) “사과” ? “Hello” “HI” “Java” “사과” String String String String
ArrayList객체 a ArrayList<String> a = new ArrayList<String>(7); ArrayList객체 생성 요소 객체 삽입 a a.add(“Hello”); a.add(“Hi”); a.add(“Java”); “Hello” “Hi” “Java” String String String 요소객체개수 n 벡터의 용량 c int n = a.size(); // n은 3 int c = a.capacity(); // capacity()메소드 없음 n = 3 a 요소 객체 중간 삽입 a.add(2, “Sahni"); a.add(5, “Sahni"); // a.size()인 3 보다 큰 곳에 삽입 불가능, 오류 “Hello” “Hi” “Sahni” “Java” String String String String str 요소 객체 얻어내기 Stringstr = a.get(1); str = “hi”
a 요소 객체 삭제 a.remove(1); a.remove(4); // 인덱스 4에 요소 객체가없으므로 오류 “Hello” “Sahni” “Java” String String String a 모든 요소 객체 삭제 a. clear();
제네릭 컬렉션 활용 2. 컬렉션의 순차 검색을 위한 Iterator • Iterator 인터페이스 • Vector, ArrayList, LinkedList와 같은 리스트 자료구조에서 요소를 순차적으로 검색할 때 Iterator 인터페이스를 사용 • iterator() 메소드를 호출하면 Iterator 객체를 반환 • Iterator 객체는 검색한 위치를 기억하고 있어 인덱스 없이 순차적 검색이 가능 • Iterator 인터페이스 메소드
제네릭 컬렉션 활용 2. HashMap<K, V> • HashMap<K, V>의 특성 • java.util.HashMap • 키(key)와 값(value) 사용 • 키와 값이 한쌍으로 삽입됨 • 키는 해시맵에삽입되는 위치를 결정하는데 내부적으로 이용 • 값을 검색하기 위해서는 키를 반드시 이용함 • 키, 값 모두 객체만이 이용됨. 기본 데이터 타입은 사용할 수 없음 • HashMap에 삽입, 검색하는 예 HashMap<String, String> = new HashMap(); // HashMap객체 생성 h.put("apple", "사과"); // 키는 "apple"이며 값이 "사과"인 요소 삽입 String kor = h.get("apple"); // "apple" 키의 값을 검색. kor은"사과"
제네릭 컬렉션 활용 2. HashMap<String, String> HashMap<String, String> 컬렉션 객체 key 테이블 value 테이블 "love" "사랑" key value "apple" "사과" put(key,value) "apple" "사과" key "apple" get(key) "baby" "아기" value "사과" ?
HashMap<String, String> 객체 h 해쉬맵 생성 HashMap h = new HashMap(); h (키, 값) 삽입 h.put("21", “홍길동”); h.put("54", “황기태”); h.put("76", “이소룡”); h.put("123", “해리슨포드”); "76" "이소룡" "21" "홍길동" "123" "해리슨포드" "54" "황기태" 키로 값 읽기 String kor = h.get(“54”); kor = "황기태"
h 키로 요소 삭제 h.remove(“54”); "76" "이소룡" "21" "홍길동" "123" "해리슨포드" 키 개수 int n = h.size(); n = 3
제네릭 컬렉션 활용 2. LinkedList<E> • LinkedList의 특성 • java.util.LinkedList • List 인터페이스를 구현한 클래스 • Vector, ArrayList클래스와 매우 유사 • 요소 객체들은 양방향으로 연결되어 관리됨 • 요소 객체는 맨 앞, 맨 뒤에 추가 가능 • 요소 객체는 인덱스를 이용하여 중간에 삽입 가능 • 맨 앞이나 맨 뒤에 요소를 추가하거나 삭제할 수 있어 스택이나 큐로 사용 가능
제네릭 컬렉션 활용 2. LinkedList<String> 객체의 내부 구성 LinkedList<String> 객체 obj head tail “C#" add(String) get(3) get(i) “C#" ? “C" “C++” “Java” “C#" String String String String
제네릭 컬렉션 활용 2. Collections 클래스 활용 • Collections 클래스 • java.util패키지에 포함 • 컬렉션에 대해 연산을 수행하고 결과로 컬렉션을 반환 • 주요 메소드 • 컬렉션에 포함된 요소들을 소팅하는sort() 메소드 • 요소의 순서를 반대로 하는 reverse() 메소드 • 요소들의 최대, 최소값을 찾아내는 max(), min() 메소드 • 특정 값을 검색하는 binarySearch() 메소드 • 모두 static 메소드
제네릭 만들기 3. 제네릭의 기본 개념 • 제네릭 • 디자인 패턴의 매개 변수화된 타입과 메소드(parameterized type and method)를 의미 • JDK 1.5부터 도입 • 컬렉션은 다양한 타입의 객체들을 하나로 모아서 관리하므로 제네릭으로 정의되어 있음
제네릭 만들기 3. 제네릭 클래스 작성 예 • 제네릭 클래스작성 예 • 일반화된 타입(generic type) 매개 변수 T를 가진 MyClass public class MyClass<T> { T val; void set(T a) { val = a; } T get() { return val; } } • 작성된 MyClass타입 객체 생성 예 MyClass<String> s = new MyClass<String>(); s.set("hello"); System.out.println(s.get()); // "hello" 출력 MyClass<Integer> n = new MyClass<Integer>(); n.set(new Integer(5)); System.out.println(n.get()); // 숫자 5 출력
MyClass<String> s = new MyClass<String>(); MyClass<Integer> n = new MyClass<Integer>(); public class MyClass<T> { T val; void set(T a) { val = a; } T get() { return val; } } s n • public class MyClass • { • String val; • void set(String a) • { • val = a; • } • String get() • { • return val; • } • } • public class MyClass • { • Integer val; • void set(Integer a) • { • val = a; • } • Integer get() • { • return val; • } • }
public class MyClass<T> { T val; void set(T a) { val = a; } T get() { return val; } } • 타입 매개 변수 • ‘<‘과 ‘>’사이의 문자로 표현 • 하나의 대문자를 타입 매개 변수로 사용 • 많이 사용하는 타입 매개 변수 문자 • E : Element를 의미하며 컬렉션에서 요소를 표시할 때 많이 사용한다. • T : Type을 의미한다. • V : Value를 의미한다. • K : Key를 의미 • 타입 매개변수가 나타내는 타입의 객체 생성 불가 • ex) T a = new T(); • 타입 매개 변수는 나중에 실제 타입으로 대체 된다. • 어떤 문자도 매개 변수로 사용될 수 있다.
제네릭 만들기 3. 제네릭 클래스 변수선언과 객체 생성 • 변수 선언 • 제네릭 클래스 또는 인터페이스 타입 변수를 선언할 때는 타입 매개 변수에 실제 타입을 기입 List<Integer> li; Vector<String> vs; • 객체 생성 • 제네릭 클래스 객체를 생성할 때도 타입 매개 변수에 실제 타입을 기입 Vector<String> vs = new Vector<String>();
class Gstack • { • inttos; • Object [] stck; • public GStack() • { • … • } • public void push(String item) • { • ... • } • public String pop() • { • … • return (String)stck[tos]; • } • } LIFO Last-In First-out • class Gstack • { • inttos; • Object [] stck; • public GStack() • { • … • } • public void push(Integer item) • { • ... • } • public Integer pop() • { • … • return (Integer)stck[tos]; • } • } LA 5 LA busan seoul 5 3 1 busan 3 seoul 1
제네릭 만들기 3. • 제네릭에서 배열의 제한 • 제네릭 클래스 또는 인터페이스의 배열을 허용하지 않음 • 타입 매개 변수가 나타내는 타입의 배열을 생성하는 것도 허용되지 않음 • 앞 예제에서는 Object 타입으로 배열 생성 후 실제 사용할 때 타입 캐스팅 • 타입 매개변수가 나타내는 타입의 배열 선언은 허용 GStack<Integer>[] gs = new GStack<Integer>[10]; T[] a = new T[10]; return (T)stck[tos]; // 타입 매개 변수 T타입으로 캐스팅 public void myArray(T[] a) {....}
제네릭 만들기 3. • 제네릭메소드 정의 • 메소드에서도 타입 매개 변수를 이용하여 제네릭메소드 정의 가능 • 제네릭메소드를 호출할 때는 컴파일러가 메소드의 인자를 통해 이미 타입을 알고 있으므로 타입을 명시하지 않아도 됨 • sa는 String[], gss는 GStack<String> 타입이므로 T를 String으로 유추 class GenericMethodEx { static <T> void toStack(T[] a, GStack<T> gs) { for (int i = 0; i < a.length; i++) { gs.push(a[i]); } } } String[] sa = new String[100]; GStack<String> gss = new GStack<String>(); GenericMethodEx.toStack(sa, gss);
GStack<T> 제네릭 클래스를 활용하는 GenericMethodExample gs • public class GStack • { • inttos; • Object [] stck; • public GStack() • { • tos = 0; • stck = new Object [10]; • } • public void push(Double item) • { • if(tos == 10) • return; • stck[tos] = item; • tos++; • } • public Double pop() • { • if(tos == 0) • return null; • tos--; • return (Double)stck[tos]; • } • } 컴파일러는 위의 제네릭메소드reverse가 전달받는 인자를 통해 reverse 메소드의리턴타입을Double로 알고있으므로 타입을 명시하지 않고서도 reverse 메소드 호출이 가능하다.
Java 제 7장 학습 수고하셨습니다. 열심히 공부해주셔서 고맙습니다. Q&A