어서와 Java는 처음이지! 제15장 제네릭과 컬렉션. 어서와 Java는 처음이지! 제15장 제네릭과 컬렉션.

Slides:



Advertisements
Similar presentations
5 장 조건과 반복 ②. Contents Counting and Looping [while 문 사용 ] Powers of 2 [while 문 사용 ] More Guessing [do 문 사용 ] Election Day [do 문 사용 ] Finding Maximum &
Advertisements

명품 JAVA Programming 제 3 장 반복문, 배열, 예외처리.
어서와 Java는 처음이지! 제3장선택과 반복.
제 7주 2015년 1학기 강원대학교 컴퓨터학부 담당교수: 정충교
어서와 Java는 처음이지! 제2장 자바 프로그래밍 기초.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
IntArray[0] int length 5 intArray 객체 제 3 장 반복문, 배열, 예외처리.
객체지향 프로그래밍.
어서와 Java는 처음이지! 제2장 자바 프로그래밍 기초.
7장 배열 ②.
어서와 Java는 처음이지! 제4장 배열.
Java Presentation 중간 시험2 풀이
윤 홍 란 제3장 클래스와 객체의 사용-1 윤 홍 란
2주 실습강의 Java의 기본문법(1) 인공지능연구실.
Chapter 02 자바 기본구조 자바 프로그래밍의 기초적인 문법을 소개
[INA470] Java Programming Youn-Hee Han
명품 JAVA Programming 제 7 장 제네릭과 컬렉션.
명품 JAVA Essential.
제7장 제어구조 I – 식과 문장.
명품 JAVA Essential.
정적 메소드와 정적 변수 상수 래퍼 클래스 포매팅
명품 JAVA Programming.
명품 JAVA Programming 제 4 장 클래스와 객체.
Power Java 제4장 자바 프로그래밍 기초.
3. 배열.
JAVA 프로그래밍 6장 객체지향프로그래밍의 핵심.
Power Java 제10장 배열.
객체지향 언어와 클래스, 객체 ㅎㅎ 개요 클래스의 선언, 객체의 생성 및 속성 참조 방식 멤버 변수 메소드 한빛미디어(주)
자바 5.0 프로그래밍.
Choi, Namseok Java 기초 (Java의 제어문과 배열) Choi, Namseok
[INA470] Java Programming Youn-Hee Han
명품 JAVA Essential.
Power Java 제14장 제네릭과 컬렉션.
명품 Java Programming.
최용술 장 Thread 최용술
10장 다중 스레드 10.1 스레드 개요 10.2 Thread 클래스 10.3 스레드 생성
2장 자바환경과 자바 프로그램 2.1 자바 개발 환경 2.2 자바 통합환경 2.3 자바 응용 프로그램과 애플릿 프로그램
윤 홍 란 4 장 클래스 작성 윤 홍 란
김 정 석 Web Programming 김 정 석
주소록 프로그램.
7장 배열 ①.
6장 객체-지향 설계 ①.
12 검색.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
5장 조건과 반복 ②.
6장 객체-지향 설계 ①.
어서와 Java는 처음이지! 제4장 배열 IT응용시스템공학과 김형진 교수.
15장. 컬렉션 프레임워크.
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
제 2장 어휘구조와 자료형 토 큰 리 터 럴 주 석 자 료 형 배 열 형.
제1장 자료구조를 배우기 위한 준비.
SpringFramework 중간고사 요약 REST by SpringFramework.
[INA470] Java Programming Youn-Hee Han
컴퓨터공학실습(I) 3주 인공지능연구실.
DataScience Lab. 박사과정 김희찬 (화)
Java IT응용시스템공학과 김형진 교수 5장. 객체지향 개념 public class SumTest {
Chap02 객체 지향 개념 2.1 객체지향(object-oriented)과 절차지향(procedural-oriented)
JA A V W. 04.
내부 클래스와 내부 인터페이스에 대하여 내부 클래스의 선언 방법과 이용 방법 내부 인터페이스의 선언 방법과 이용 방법
자바 5.0 프로그래밍.
26강 JAVA Collections - I - 컬렉션이란? - JAVA도 결국 효과적인 데이터를 처리하기 위한 수단
Chapter 02. 소프트웨어와 자료구조.
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
JVM의 구조와 메모리 모델 JVM의 내부 구조 클래스 파일 클래스 로더 메소드(method) 영역 힙(heap) 영역
6장 클래스(상속).
Java 5장. 객체지향 개념 public class SumTest {
List, ArrayList, Vector, LinkedList 가 있습니다
12장. 자료구조로 사용되는 클래스 자료구조란? 자료구조 클래스의 사용방법.
List, ArrayList, Vector, LinkedList 가 있습니다
Chapter8 : 인터페이스와 패키지 8.1 인터페이스 개요와 인터페이스 정의 8.2 인터페이스의 사용
Presentation transcript:

어서와 Java는 처음이지! 제15장 제네릭과 컬렉션

제네릭이란? 제네릭 프로그래밍(generic programming)이란 다양한 종류의 데이터를 처리할 수 있는 클래스와 메소드를 작성하는 기법이 다

기존의 방법 일반적인 객체를 처리하려면 Object 참조 변수를 사용 예제로 하나의 데이터를 저장하는 Box 클래스를 살펴보자.

예제 public class Box { private Object data; public void set(Object data) { this.data = data; } public Object get() { return data; } } Box b = new Box(); b.set("Hello World!"); // ① 문자열 객체를 저장 String s = (String)b.get(); // ② Object 타입을 String 타입으로 형변환 b.set(new Integer(10)); // ③ 정수 객체를 저장 Integer i = (Integer)b.get( ); // ④ Object 타입을 Integer 타입으로 형변환

제네릭을 이용한 방법 class Box<T> { private T data; public void set(T data) { this.data = data; } public T get() { return data; } } Box<String> b = new Box<String>(); Box<Integer> b = new Box<Integer>();

예제 설명

LAB: SimplePair 클래스 작성하기 public class SimplePairTest { public static void main(String[] args) { SimplePair<String> pair = new SimplePair<String>("apple", "tomato"); System.out.println(pair.getFirst()); System.out.println(pair.getSecond()); } apple tomato

SOLUTION public class SimplePair<T> { private T data1; public SimplePair(T data1, T data2) { this.data1 = data1; this.data2 = data2; } public T getFirst() { return data1; } public T getSecond() { return data2; } public void setFirst(T data1) { this.data1 = data1; } public void setSecond(T data2) { this.data2 = data2; }

다중 타입 매개 변수(Multiple Type Parameters) public class OrderedPair<K, V> { private K key; private V value; public OrderedPair(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public V getValue() { return value; }

다중 타입 매개 변수(Multiple Type Parameters) public class OrderedPairTest { public static void main(String[] args) { OrderedPair<String, Integer> p1 = new OrderedPair<String, Integer>("mykey", 12345678); OrderedPair<String, String> p2 = new OrderedPair<String, String>("java", "a programming laguage"); System.out.println(p1.getKey() + " " + p1.getValue()); System.out.println(p2.getKey() + " " + p2.getValue()); } mykey 12345678 java a programming laguage

제네릭 메소드 하지만 일반 클래스의 메소드에서도 타입 매개 변수를 사용하 여서 제네릭 메소드를 정의할 수 있다. 이 경우에는 타입 매개 변수의 범위가 메소드 내부로 제한된다. public class MyArrayAlg { public static <T> T getLast(T[] a) { return a[a.length - 1]; } public class MyArrayAlgTest { public static void main(String[] args) { String[] language = { "C++", "C#", "JAVA" }; String last = MyArrayAlg.getLast(language); // last는 “JAVA" System.out.println(last); }

LAB 배열 안에서 i번째 요소와 j번째 요소를 교환하는 swap(int i, int j) 메소드를 제네릭 메소드로 작성하여 보자. public class MyArrayAlgTest { public static void main(String[] args) { String[] language = { "C++", "C#", "JAVA" }; MyArrayAlg.swap(language, 1, 2); for(String value : language) System.out.println(value); }

SOLUTION public class MyArrayAlg { public static <T> void swap(T[] a, int i, int j) { T tmp = a[i]; a[i] = a[j]; a[j] = tmp; }

LAB 다음 코드와 같이 정수 배열, 실수 배열, 문자 배열을 모두 출력 할 수 있는 제네릭 메소드 printArray()를 작성하여 보자. public class GenericMethodTest { public static void main(String args[]) { Integer[] iArray = { 10, 20, 30, 40, 50 }; Double[] dArray = { 1.1, 1.2, 1.3, 1.4, 1.5 }; Character[] cArray = { 'K', 'O', 'R', 'E', 'A' }; printArray(iArray); printArray(dArray); printArray(cArray); }

SOLUTION public class GenericMethodTest { public static void main(String args[]) { Integer[] iArray = { 10, 20, 30, 40, 50 Double[] dArray = { 1.1, 1.2, 1.3, 1.4, 1.5 }; Character[] cArray = { 'K', 'O', 'R', 'E', 'A' }; printArray(iArray); printArray(dArray); printArray(cArray); } public static <T> void printArray(T[] array) { for (T element : array) { System.out.printf("%s ", element); System.out.println();

한정된 타입 매개 변수 때때로 특정한 종류의 객체들만을 받게 하고 싶은 경우가 있다. public class MyArrayAlg { public static <T extends Comparable> T getMax(T[] a) if (a == null || a.length == 0) return null; T largest = a[0]; for (int i = 1; i < a.length; i++) if (largest.compareTo(a[i]) < 0) largest = a[i]; return largest; }

제네릭과 상속 제네릭과 상속에 대하여 생각해보자. 자바 라이브러리에는 Number 클래스를 상속받아서 Integer와 Double 클래스를 정의하고 있다. Box<Number> box = new Box<Number>(); box.add(new Integer(10)); // Number 객체 대신에 Integer 객체를 주어도 된다. box.add(new Double(10.1)); // Number 객체 대신에 Double 객체를 주어도 된다. public void process(Box<Number> box) { ... } 어떤 타입을 받을 수 있을까?

제네릭과 상속 Integer가 Number의 자식이긴 하지만, Box<Integer>는 Box<Number>의 자식은 아니다.

상한이 있는 와일드 카드 어떤 클래스 A의 자손 클래스들을 와일드 카드로 표시하려면 <? extends A>와 같이 표시한다. 이것을 상한이 있는 와일드 카드(Upper Bounded Wildcard)라 고 한다. 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))

제한없는 와일드 카드 제한없는 와일드 카드(Unbounded Wildcard)는 단순히 ?으로 만 이루어진다. 예를 들면 List<?>와 같다. 와일드 카드 ?은 모든 타입에 매치된다. import java.util.List; public class MyList { public static void printList(List<?> list) { for (Object elem : list) System.out.print(elem + " "); System.out.println(); }

import java.util.Arrays; import java.util.List; public class WildCardTest { public static void main(String[] args) { List<Integer> li = Arrays.asList(1, 2, 3); List<String> ls = Arrays.asList("one", "two", "three"); MyList.printList(li); MyList.printList(ls); } 1 2 3 one two three

하한이 있는 와일드 카드 어떤 클래스의 조상 클래스들을 와일드 카드로 나타내려면 <? super A>와 같은 문법을 사용한다. public static void addNumbers(List<? super Integer> list) { for (int i = 1; i <= 10; i++) { list.add(i); }

정리 아래 그림을 완벽하게 이해할 수 있으면 어느 정도 제네릭 공부 는 된 셈이다.

컬렉션 컬렉션(collection)은 자바에서 자료 구조를 구현한 클래스 자료 구조로는 리스트(list), 스택(stack), 큐(queue), 집합(set), 해 쉬 테이블(hash table) 등이 있다.

컬렉션의 역사 초기 버전: Vector, Stack, HashTable, Bitset, Enumeration이 그 것이다. 버전 1.2부터는 풍부한 컬렉션 라이브러리가 제공 인터페이스와 구현을 분리 (예) List 인터페이스를 ArrayList와 LinkedList 클래스가 구현

컬렉션의 예: Vector 클래스 Vector 클래스는 java.util 패키지에 있는 컬렉션의 일종으로 가 변 크기의 배열(dynamic array)을 구현하고 있다.

예제 import java.util.Vector; public class VectorTest { public static void main(String[] args) { Vector vc = new Vector(); vc.add("Hello World!"); vc.add(new Integer(10)); vc.add(20); System.out.println("vector size :" + vc.size()); for (int i = 0; i < vc.size(); i++) { System.out.println("vector element " + i + " :" + vc.get(i)); } String s = (String)vc.get(0);

예제 vector size :3 vector element 0 :Hello World! vector element 1 :10

컬렉션 인터페이스와 컬렉션 클래스 자바는 컬렉션 인터페이스와 컬렉션 클래스로 나누어서 제공한 다. 자바에서는 컬렉션 인터페이스를 구현한 클래스도 함께 제 공하므로 이것을 간단하게 사용할 수도 있고 아니면 각자 필요 에 맞추어 인터페이스를 자신의 클래스로 구현할 수도 있다.

Collection 인터페이스

Collection 인터페이스

List 인터페이스 리스트(List)는 순서를 가지는 요소들의 모임으로 중복된 요소 를 가질 수 있다.

ArrayList ArrayList를 배열(Array)의 향상된 버전 또는 가변 크기의 배열이 라고 생각하면 된다. ArrayList<String> list = new ArrayList<String>(); 원소 추가 list.add( "MILK" ); list.add( "BREAD" ); list.add( "BUTTER" );

ArrayList<String> list = new ArrayList<String>(); list.add( "MILK" ); list.add( "BREAD" ); list.add( "BUTTER" ); list.add( 1, "APPLE" ); // 인덱스 1에 "APPLE"을 삽입 list.set( 2, "GRAPE" ); // 인덱스 2의 원소를 "GRAPE"로 대체 list.remove( 3 ); // 인덱스 3의 원소를 삭제한다.

LinkedList 빈번하게 삽입과 삭제가 일어나는 경우에 사용

예제 import java.util.*; public class LinkedListTest { public static void main(String args[]) { LinkedList<String> list = new LinkedList<String>(); list.add("MILK"); list.add("BREAD"); list.add("BUTTER"); list.add(1, "APPLE"); // 인덱스 1에 “APPLE"을 삽입 list.set(2, "GRAPE"); // 인덱스 2의 원소를 “GRAPE"로 대체 list.remove(3); // 인덱스 3의 원소를 삭제한다. for (int i = 0; i < list.size(); i++) System.out.println(list.get(i)); }

반복자 사용하기 ArrayList<String> list = new ArrayList<String>(); list.add("하나“); list.add("둘“); list.add("셋“); list.add("넷“); String s; Iterator e = list.iterator(); while(e.hasNext()) { s = (String)e.next(); // 반복자는 Object 타입을 반환! System.out.println(s); } MILK APPLE GRAPE

배열을 리스트로 변환하기 List<String> list = Arrays.asList(new String[size]); 일반적인 배열을 리스트로 변환한다.

Set 집합(Set)은 원소의 중복을 허용하지 않는다.

Set 인터페이스를 구현하는 방법 HashSet TreeSet LinkedHashSet 레드-블랙 트리(red-black tree)에 원소를 저장한다. 따라서 값에 따라 서 순서가 결정되며 하지만 HashSet보다는 느리다. LinkedHashSet 해쉬 테이블과 연결 리스트를 결합한 것으로 원소들의 순서는 삽입되 었던 순서와 같다.

예제 import java.util.*; public class SetTest { public static void main(String args[]) { HashSet<String> set = new HashSet<String>(); set.add("Milk"); set.add("Bread"); set.add("Butter"); set.add("Cheese"); set.add("Ham"); System.out.println(set); } [Bread, Milk, Butter, Ham, Cheese]

예제 import java.util.*; public class FindDupplication { public static void main(String[] args) { Set<String> s = new HashSet<String>(); String[] sample = { "단어", "중복", "구절", "중복" }; for (String a : sample) if (!s.add(a)) System.out.println("중복된 단어 " + a); System.out.println(s.size() + " 중복되지 않은 단어: " + s); } 중복된 단어 중복 3 중복되지 않은 단어: [중복, 구절, 단어]

대량 연산 메소드 s1.containsAll(s2) — 만약 s2가 s1의 부분 집합이면 참이다. s1.addAll(s2) — s1을 s1과 s2의 합집합으로 만든다. s1.retainAll(s2) — s1을 s1과 s2의 교집합으로 만든다. s1.removeAll(s2) — s1을 s1과 s2의 차집합으로 만든다.

예제 public class SetTest1 { public static void main(String[] args) { Set<String> s1 = new HashSet<String>(); Set<String> s2 = new HashSet<String>(); s1.add("A"); s1.add("B"); s1.add("C"); s2.add("A"); s2.add("D"); Set<String> union = new HashSet<String>(s1); union.addAll(s2); Set<String> intersection = new HashSet<String>(s1); intersection.retainAll(s2); System.out.println("합집합 " + union); System.out.println("교집합 " + intersection); } 합집합 [D, A, B, C] 교집합 [A]

큐(queue) 큐는 후단(tail)에서 원소를 추가하고 전단(head)에서 원소를 삭 제한다.

예제 import java.util.*; public class QueueTest { public static void main(String[] args) throws InterruptedException { int time = 10; Queue<Integer> queue = new LinkedList<Integer>(); for (int i = time; i >= 0; i--) queue.add(i); while (!queue.isEmpty()) { System.out.print(queue.remove()+" "); Thread.sleep(1000); // 현재의 스레드를 1초간 재운다. } 10 9 8 7 6 5 4 3 2 1 0

우선순위큐 우선 순위큐는 원소들이 무작위로 삽입되었더라도 정렬된 상태 로 원소들을 추출한다. 즉 remove()를 호출할 때마다 가장 작은 원소가 추출된다. 우선 순위큐는 히프(heap)라고 하는 자료 구조를 내부적으로 사 용한다.

예제 import java.util.*; public class PriorityQueueTest { public static void main(String[] args) { PriorityQueue<Integer> pq = new PriorityQueue<Integer>(); pq.add(30); pq.add(80); pq.add(20); for (Integer o : pq) System.out.println(o); System.out.println("원소 삭제"); while (!pq.isEmpty()) System.out.println(pq.remove()); } 20 80 30 원소 삭제

Map Map은 많은 데이터 중에서 원하는 데이터를 빠르게 찾을 수 있 는 자료 구조이다. 맵은 사전과 같은 자료 구조이다.

예제 import java.util.*; class Student { int number; String name; public Student(int number, String name) { this.number = number; this.name = name; } public String toString() { return name;

예제 public class MapTest { public static void main(String[] args) { Map<String, Student> st = new HashMap<String, Student>(); st.put("20090001", new Student(20090001, "구준표")); st.put("20090002", new Student(20090002, "금잔디")); st.put("20090003", new Student(20090003, "윤지후")); // 모든 항목을 출력한다. System.out.println(st); // 하나의 항목을 삭제한다. st.remove("20090002"); // 하나의 항목을 대치한다. st.put("20090003", new Student(20090003, "소이정")); // 값을 참조한다. System.out.println(st.get("20090003")); // 모든 항목을 방문한다. for (Map.Entry<String, Student> s : st.entrySet()) { String key = s.getKey(); Student value = s.getValue(); System.out.println("key=" + key + ", value=" + value); } 예제

예제 {20090001=구준표, 20090002=금잔디, 20090003=윤지후} 소이정 key=20090001, value=구준표 key=20090003, value=소이정

Collections 클래스 Collections 클래스는 여러 유용한 알고리즘을 구현한 메소드들 을 제공한다. 정렬(Sorting) 섞기(Shuffling) 탐색(Searching)

정렬 정렬은 데이터를 어떤 기준에 의하여 순서대로 나열하는 것이 다.

예제 import java.util.*; public class Sort { public static void main(String[] args) { String[] sample = { "i", "walk", "the", "line" }; List<String> list = Arrays.asList(sample); // 배열을 리스트로 변경 Collections.sort(list); System.out.println(list); } [i, line, the, walk]

탐색 탐색이란 리스트 안에서 원하는 원소를 찾는 것이다.

예제 import java.util.*; public class Search { public static void main(String[] args) { int key = 50; List<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < 100; i++) list.add(i); int index = Collections.binarySearch(list,key); System.out.println("탐색의 반환값 =" + index); } 탐색의 반환값 =50

LAB: 영어사전의 구현 여기서는 Map을 사용하여서 영어 사전을 구현하여 보자. 사용 자가 단어를 입력하면 단어의 설명을 보여준다. 영어 단어를 입력하시오:map 단어의 의미는 지도 영어 단어를 입력하시오:school 단어의 의미는 학교 영어 단어를 입력하시오:quit

예제 import java.util.*; public class EnglishDic { public static void main(String[] args) { Map<String, String> st = new HashMap<String, String>(); st.put("map", "지도"); st.put("java", "자바"); st.put("school", "학교"); Scanner sc = new Scanner(System.in); do { System.out.print("영어 단어를 입력하시오:"); String key = sc.next(); if( key.equals("quit") ) break; System.out.println("단어의 의미는 " + st.get(key)); } while(true); }