자바의정석 ch11

soso·2023년 2월 22일
0
post-thumbnail

Chapter11 컬렉션 프레임워크

컬렉션 프레임워크

▶컬렉션(collection)
여러 객체(데이터)를 모아 놓은 것을 의미한다.
▶프레임워크(framework)
표준화, 정형화된 체계적인 프로그래밍 방식이다.
▶컬렉션 프레임워크(collection framework)
컬렉션(다수의 객체)을 다루기 위한 표준화된 프로그래밍 방식이다.
컬렉션을 쉽고 편리하게 다룰 수 있는 다양한 클래스를 제공한다.
java.util패키지에 포함되어있고 JDK1.2부터 제공된다.
▶컬렉션 클래스(collection class)
다수의 데이터를 저장할 수 있는 클래스 (예)Vector, ArrayList, HashSet)

라이브러리와 프레임워크

라이브러리(그래픽 라이브러리, 통계 라이브러리 등)는 공통으로 사용될만한 유용한 기능을 모듈화하여 제공하는데 비해,
프레임워크는 단순힌 기능뿐 아니라 프로로그래밍 방식을 정형화하여 프로그램의 개발 생산성을 높이고 유지보수를 용이하게 한다.

컬렉션 프레임워크의 핵심 인테페이스

컬렉션데이터 그룹을 크게3가지 타입이 존재한다고 인식,
각 컬렉션을 다루는데 필요한 기능을 3개의 인터페이스로 정의하였다.
인터페이스 List와 Set을 구현한 클래스들의 공통된 부분을 뽑아 Collection인터페이스를 정의할수 있지만
Map인터페이스는 전혀 다른 형태로 컬렉션을 다루기때문에 상승계층도에 포함되지 못했다.

Collection인터페이스

List와 Set의 조상인 Collection인터페이스에 정의된 메서드

List인터페이스

List인터페이스는 중복을 허용하면서 저장순서가 유지되는 컬렉션 클래스 구현에 사용한다.

Set인터페이스

Set인터페이스는 중복을 허용하지 않고 저장순서가 유지되지 않는 컬렉션 클래스 구현에 사용된다.
Set인터페이스를 구현하는 클래스로는 HashSet, TreeSet등이 있다.

Map인터페이스

Map인터페이스는 키(key)와 값(ralue)을 하나의 쌍으로 묶어서 저장하는 컬렉션 클래스 구현에 사용된다.
키는 중복될 수 없지만 값은 중복을 허용한다.
기존에 저장된 데이터 와 중복된 키와 값을 저장하면 기존의 값은 없어지고 마지막에 저장된 값이 남게 된다.
Map 인터페이스를 구현한 클래스로는 Hashtable,HashMap, LinkedHashMap, SortedMap,TreeMap 등이 있다.

ArrayList

ArrayList는 기존의 Vector를 개선한 것으로 구현원리와 기능적으로 동일하다.
ArrayList와 달리 Vector는 자체적으로 동기화처리가 되어 있다.
List인터페이스를 구현하므로, 저장순서가 유지되고 중복을 허용한다.
데이터의저장공간으로 배열을 사용한다.(배열기반)

ArrayList의 메서드

ArrayList의 추가와 삭제

ArrayList요소를 삭제하는 경우, 삭제할 객체의 바로 아래에 있는 데이터를 한칸씩 위로 복사헤서 삭제할 객체를 덮어쓰는 방식으로 처리한다.
만일 삭제할 객체가 마지막 데이터라면, 복사할 필요 없이 단순히 null로 변경해주면 된다.

Java API소스보기

Vector클래스와 같이 Java API에서 제공하는 기본 클래스의 실제 소스를 보고 싶다면, JDK 를 설치한 디렉토리에서 stc. Zip파일을 찾을 수 있다.
src.zip이라는 파일의 압축을 푼 다음, 패키지별로 찾아 들어가면 원하는 클래스의 실제소 스를 볼 수 있다.

LinkedList - 배열의 장단점

▶장점
배열은 가구조가 간단하며 사용하기 쉽고 데이터를 읽어오는데 걸리는 시간(접근시간, access time)이 가장 빠르다

▶단점1: 크기를 변경할 수 없다.
크기를 변경할 수 없으므로 새로운 배열을 생성해서 데이터를 복사해야한다.
실행속도를 향상시키기 위해서는 충분히 큰 크기의 배열을 생성해야 하므로 메모리가 낭비된다.

▶단점2: 비순차적인 데이터의 추가 또는 삭제에 시간이 많이 걸린다.
차례대로 데이터를 추가하고 마지막에서부터는 데이터를 삭제하는 것은 빠르지만, 배열의 중간에 데이터를 추가하려면, 빈자리를 만들기 위해 다른 데이터들을 복사해서 이동해야 한다.

LinkedList - 배열의 단점을 보완

배열의 단점을 보안하기위해 링크드 리스트(Linked list)라는 자료구조가 고안되었다.
배열과 달리 링크드 리스트는 불연속적으로 존재하는 데이터를 서로 연결(link)한 형태로 구성되어 있다.

LinkedList의 추가와 삭제

링크드 리스트에서의 데이터 삭제는 간단하다.
삭제하고자 하는 요소의 이전요소가 삭제하고자 하는 요소의 다음 요소를 참조하도록 변경하기만 하면된다.
배열처럼 데이터를 이동하기 위해 복사하는 과정이 없기 때문에 처리속도가 매우빠르다.

▶데이터 삭제: 단한번의 참조변경만으로 가능하다.
▶데이터 추가: 한번의 Node객체생성과 두 번의 참조변경만 가능하다.

LinkedList -이중 연결 리스트

▶링크드 리스트(Linked list)
-연결리스트. 데이터의 접근성이 나쁘다.

▶더블리 링크드 리스트(doubly linked list)
-이중 연결리스트, 접근성이 향상됐다.

▶더블리 써큘러 링크드 리스트(doubly circular linked list)
-이중 원형 리스트

ArrayList와 LinkedList의 비교

다루고자 하는 데이터의 개수가 변하지 않는 경우라면 ArrayList,
데이터 개수의 변경이 잦다면 LinkedList를 사용하는것이 좋다.

Stack과 Queue

▶스택(Stack) : LIFO(Last In First Out)구조.
마지막에 저장된 것을 제일 먼저 꺼내게 된다.

▶큐(Queue) : FIFO(First IN First Out)구조.
제일 먼저 저장한것을 제일 먼저 꺼내게 된다.

Stack과 Queue의 메서드

Stack과 Queue의 활용

스택의 활용 예 - 수식계산, 수식괄호검사, 위드프로세서의 undo/redo, 웹브라우저의 뒤로/앞으로
큐의 활용 예 -최근사용문서, 인쇄작업 대기목록, 버퍼(buffer)

Iterator, ListIterator, Enumeration

켈렉션에 저장된 데이터를 접근(읽어오기)하는데 사용되는 인터페이스이다.

Iterator 컬렉션에 저장된 요소를 접근하는데 사용된는 인터페이스
ListIterator Iterator에 양방향 조회기능추가(List를 구현하는 경우만 사용가능)
Enumeration Iterator의 구버전

Map과 Iterator

Map에는 Iterator()가 없다.
KeySet(), entrySet(), Value()와 같은 메서드를 통해 키와 값을 Set과 collection형태로 얻어와서 Iterator() 호출해야 한다.

Arrays

Arrays클래스에는 배열을 다루기 편리한 메서드(static)를 제공한다.

Arrays의 메서드(1) -복사

배열채우기 - copyOf(), copyOfRange()
copyOf() : 배열 전체 복사

copyOfRange() : 배열의 일부를 복사해서 새로운 배열을 만들어 반환한다.copyOfRange()에 지정된 점범위의 끝은 포함되지 않는다.

int[] arr = {0, 1, 2, 3, 4}
int[] arr2 = Arrays.copyOf(arr, arr.lenght); // arr2=[0,1,2,3,4]
int[] arr3 = Arrays.copyOf(arr, 3); // arr3=[0,1,2]
int[] arr4 = Arrays.copyOf(arr, 7); // arr4[0,1,2,3,4,0,0]
int[] arr5 = Arrays.copyOfRange(arr, 2, 4); // arr5=[2,3] ←4는 불포함
int[] arr6 = Arrays.copyOfRange(arr, 0, 7); // arr6=[0,1,2,3,4,0,0]

Arrays의 메서드(2) -채우기, 정렬, 검색

배열의 복사 - fill(), setAll()
fill() : 배열의 모든 요소를 지정된 값으로 채운다.

setAll() : 배열을 채우는데 사용할 함수형 인터페이스를 매개변수로 받는다. 메서드 호출 시 함수형 인터페이스를 구현한 객체를 매개변수로 지정, 또는 람다식을 지정해야 한다.

배열의 정렬과 검색 - sort(), binarySearch()
sort() : 배열 정렬

binarySearch() : 배열에 저장된 요소를 검색할때 사용한다.
반드시 배열이 정렬된 상태여야 올바른 결과를 얻는다.

int[] arr = {3,2,0,1,4}
Arrays.sort(arr); // 배열 arr을 정리한다.
System.out.println(Arrays.toString(arr)); // [0,1,2,3,4]
int idx = Arrays.binarySearch(arr, 2); // idx=2 

▶순차검색과 이진검색

순차검색(linear search)은 배열 첫 번째 요소부터 순서대로 하나씩 검색하기때문에 배열이 정렬되어 있을 필요는 없지만 배열의 요소를 하나씩 비교하기 때문에 시간이 많이 걸린다.

이진 검색(binary search)은 배열의 검색할 범위를 반복 적으로 절반씩 줄여가면서 검색하기 때문에 검색속도가 빠르다.
큰 배열의 검색에 유리하다.
단, 배열이 정렬이 되어 있는 경우에만 사용할 수 있다는 단점이 있다.

Arrays의 메서드(3) -비교와 출력

문자열의 비교와 출력 -toString(), equals()
toString() : 배열의 모든 요소를 문자열로 출력할 수 있다. toString()은 일차원 배열만 사용할수있다.

다차원배열은 deepToString()을 사용해야한다.
deepToString()은 배열의 모든 요소를 재귀적으로 접근해서 문자열을 구성하므로 2차원뿐만 아니라 3차원 이상의 배열에도 동작한다.

int[] arr = {0,1,2,3,4}
int[][] arr2D ={{11,12}, {21,22}}
System.out.println(Arrays.toString(arr)); // [0, 1, 2, 3, 4]
System.out.println(Arrays.deepToString(arr2D)); // [[11, 12], [21, 22]]

equals() : 두 배열에 저장된 모든 요소를 비교해서 같으면 true, 다르면 flase를 반환한다. equals()은 일차원 배열만 사용할수있다.
다차원배열의 비교에는 deepEquals()을 사용해야한다.

String[][] str2D = new String[][]{{"aaa", "bbb"}, {"AAA", "BBB"}};
String[][] str2D2 = new String[][]{{"aaa", "bbb"}, {"AAA", "BBB"}};
System.out.println(Arrays.equals(str2D, str2D2)); // false
System.out.println(Arrays.deepEquals(str2D, str2D2)); // true

2차원 String배열을 equals()로 비교하면 배열에 저장된 내용이 같은데도 false를 결과로 얻는다.
다차원 배열은 '배열의 배열'의 형태로 구성하기 때문에 equals()로 비교하면, 문자열을 비교하는 것이 아니라 '배열에 저장된 배열의 주소'를 비교하게 된다. 서로 다른 배열은 항상 주소가 다르므로 false를 결과로 얻는다.

Arrays의 메서드(4) -변환

배열을 List로 변환 - asList(Object... a)
asList() : 배열을 List에 담아 반환한다.
매개변수 타입이 가변 인수라서 배열 생성 없이 저장할 요소들만 나열하는 것도 가능하다.

List list = Arrays.asList (new Integer [11,2,3,4,5}); // list =[1, 2, 3, 4, 5]
List list = Arrays.asList (1,2,3,4,5); // list =[1, 2, 3, 4, 5]
list.add(6); // Unsupportedoperationexception 예외 발생

주의할 점은 asList()가 반환한 List의 크기를 변경할 수 없다는 것이다.
즉, 추가 또 는 삭제가 불가능하다.
저장된 내용은 변경가능하다. 만일 크기를 변경할 수 있는 List가 필요하다면 다음과 같이 하면 된다.

List list = new ArrayList (Arrays. asList (1,2,3,4,5));

parallelXXX(), spliterator(), stream()

'parallel'로 시작하는 이름의 메서드들이 있는데, 이 메서드들은 보다 빠른 결과를 얻기 위해 여러 쓰레드가 작업을 나누어 처리하도록 한다.
spliterator() : 여러 쓰레드가 처리할 수 있게 하나의 작업을 여러 작업으로 나누는 Spliterator를 반환한다.
stream() : 컬렉션을 스트림으로 변환한다.

Comparator와 Comparable

객체정렬에 필요한 메서드(정렬기준)을 정의한 인터페이스이다.

Comparator 기본 정렬기준을 구하는데 사용
Comparable 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용

Compare()와 CompareTo()는 두 객체의 비교결과를 반환하도록 작성한다
같으면0, 오른쪽이 크면 음수(-), 작으면 양수(+)

Integer와 Comparable

Integer클래스의 compareTo()는 두 Integer객체에 저장된 int값(value)을 비교해서 같으면 0, 크면 -1, 작으면 1을 반환한다.

Comparable을 구현한 클래스들이 기본적으로 오름차순으로 정렬되어 있지만, 내림차순으로 정렬 또는 다른 기준에 의해서 정렬되도록 하고 싶을 때 Comparator를 구현해서 정렬기준을 제공할 수 있다.

HashSet

순서를 유지하지 않고 중복을 허용하지 않는다.
Set인터페이스를 구현한 대표적인 컬렉션 클래스이다.
순서를 유지하려면, LinkedHashSet클래스를 사용하면 된다.

TreeSet

이진 탐색 트리(binary search tree) 자료구조 형태로 테이터를 저장하는 클래스
범위 검색과 정렬에 유리한 컬렉션 클래스이다.
HashSet보다 데이터 추가, 삭제에 시간이 더 걸린다.

이진 트리는 모든 노드가 최대 2개의 하위 노드를 갖는다.
각 요소(node)가 나무(tree)형태로 연결(LinkedList의 변형)되었다.

이진 탐색 트리(binary search tree)


이진 탐색 트리(binary search troo)는

  • 모든 노드는 최대 두 개의 지식노드를 가질 수 있다.
  • 왼쪽 지식노트의 값은 부모노드의 값보다 작고 오른쪽 자식노드의 값은 부모노드의 값보다 커야한다.
  • 노드의 추가 식제에 시간이 컬린다. (반복 비교로 자리를 찾아 저장)
  • 검색(벌위검색)과 정렬에 유리하다.
  • 중복된 값을 지장하지 못한다.

TreeSet의 메서드

HashMap과 Hashtable

HashMap은 Map을 구현했으므로 앞에서 살펴본 Map의 특징, 키(key)와 값(value)을 묶어서 하나의 데이터(entry)로 저장한다는 특징을 갖는다.
그리고 해싱(hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어서 뛰어난 성능을 보인다.

HashMap의 키(Key)와 값(value)

HashMap은 키와 값을 각각 (Object, Object)의 형태로 저장하기 때문에 어떠한 객체도 저장할 수 있고 키는 주로 String을 대문자 또는 소문자로 통일해서 사용하곤 한다.

키(Key) 컬렉션 내의 키(Key) 중에서 유일해야 한다.
값(value) 키(Key)와 달리 데이터의 중복을 허용한다.

HashMap의 메서드

Collections의 메서드 -동기화

컬렉션을 위한 메서드(static)를 제공
컬렉션 채우기, 복사, 정렬, 검색 -fill(), copy(), sort(), binarySearch()등

컬렉션 동기화 -synchronizedXXX()

멀티 쓰레드(multi- thread) 프로그래밍에서는 하나의 객체를 여러 쓰레드가 동시에 접근 할 수 있기 때문에 데이터의 무결성(integrity)을 유지하기 위해서는 공유되는 객체에 동기화(synchronization)가 필요하다.

static Collection synchronizedCollection(Collection c)
static List synchronizedList(List list)
static Set synchronizedSet(Set s)
static Map synchronizedMap(Map m)
static SortedSet synchronizedSortedSet(SortedSet s)
static SortedMap synchronizedSortedMap(SortedMap m)

Collections의 메서드 -변경불가, 싱글톤

변경불가(readOnly) 컬렉션 만들기 -unmodifiableXXX()

컬렉션에 저장된 데이터를 보호하기 위해서 컬렉션을 변경할 수 없게 읽기 전용으로 만들어야 할 때가 있다.

static Collection unmodifiableCollection(Collection c)
static List unmodifiableList(List list)
static Set unmodifiableSet(Set s)
static Map unmodifiableMap(Map m)
static NavigableSet unmodifiableNavigableSet(NavigableSet s)
static SortedSet unmodifiableSortedSet(SortedSet s)
static NavigableMap unmodifiableNavigableMap(NavigableMap m)
static SortedMap unmodifiableSortedMap(SortedMap m)

싱글톤 컬렉션 만들기 -singletoneXXX()

단 하나의 객체만을 저장한다.

static List singletoneList(Object o)
static Set singletone(Object o) //singletoneSet 아님!!
static Map singletoneMap(Object o)

Collections의 메서드 -단일 컬렉션

한 종류의 객체만 저장하는 컬렉션 만들기 -chekedXXX()

컬렉션에 모든 종류의 객체를 저장할 수 있다는 것은 장점이자 단점이다.
대부분의 경우 한 종류의 객체를 저장하며, 컬렉션에 지정된 종류의 객체만 저장할 수 있도록 제한하고 싶을때 chekedXXX()메서드를 사용한다.

static Collection CheckedCollection(Collection c, class type)
static List CheckedList(List list, class type)
static Set CheckedSet(Set s, class type)
static Map CheckedMap(Map m, class type, class valueType)
static Queue CheckedQueue(Queue queue, class type)
static NavigableSet CheckedNavigableSet(NavigableSet s, class type)
static SortedSet CheckedSortedSet(SortedSet s, class type)
static NavigableMap CheckedNavigableMap(NavigableMap m, class keyType, class type)
static SortedMap CheckedSortedMap(SortedMap m, class keyType, class type)

컬렉션 클래스 정리 & 요약

profile
오늘의 기록

0개의 댓글