Computer Science/DataStructure

Collections

자바의정석 3rd Edition 2권을 참조하였습니다.

https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=76083001 

 

Java의 정석

저자는 자바를 소개하는데 그치지 않고 프로그래머로써 꼭 알아야하는 내용들을 체계적으로 정리하였으며 200페이지에 달하는 지면을 객체지향개념에 할애함으로써 이 책 한 권이면 객체지향

www.aladin.co.kr

 


Arrays가 배열 관련 메서드를 제공하는 것처럼, Collections는 컬렉션과 관련된 메서드를 제공한다.

fill(), copy(0, sort(), binarySearch() 등의 메서드는 두 클래스에 모두 포함되어 있으며 같은 기능을 한다.

 

컬렉션의 동기화

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

Vector와 Hashtable과 같은 구버전(JDK1.2 이전)의 클래스들은 자체적으로 동기화 처리가 되어 있는데, 멀티쓰레드 프로그래밍이 아닌 경우에는 불필요한 기능이 되어 성능을 떨어뜨리는 요인이 된다.

그래서 새로 추가된 ArrayList와 HashMap과 같은 컬렉션은 동기화를 자체적으로 처리하지 않고 필요한 경우에만 java.util.Collections클래스의 동기화 메서드를 이용해서 동기화처리가 가능하도록 변경하였다.

Collections클래스에는 다음과 같은 동기화 메서드를 제공하고 있으므로, 동기화가 필요 할 때 해당하는 것을 사용하면 된다.

더보기
static Collection synchronizedCollection(Collection c)
static List 	  synchronizedList(List list)
static Set		  synchronizedSet(Set set)
static Map		  synchronizedMap(Map map)
static SortedSet  synchronizedSortedSet(SortedSet s)
static SortedMap  synchronizedSortedMap(SortedMap m)

이 들을 사용하는 방법은 다음과 같다.

List syncList = Collections.synchronizedList(new ArrayList(...));

변경불가 컬렉션 만들기

컬렉션에 저장된 데이터를 보호하기 위해서 컬렉션을 변경할 수 없게, 즉 읽기 전용으로 만들어야할 때가 있다. 주로 멀티 쓰레드 프로그래밍에서 여러 쓰레드가 하나의 컬렉션을 공유하다보면 데이터가 손상될 수 있는데, 이를 방지하려면 아래의 메서드들을 이용하자.

더보기
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)

 

싱글톤 컬렉션 만들기

단 하나의 객체만을 저장하는 컬렉션을 만들고 싶을 경우가 있다. 이럴 때는 아래의 메서드를 사용하면 된다.

더보기
static List singletonList(Object o)
static Set  singleton(Object o)	// singletoneSet이 아님
static Map  singletonMap(Object key, Object value)

매개변수로 저장할 요소를 지정하면, 해당 요소를 저장하는 컬렉션을 반환한다.

그리고 반환된 컬렉션은 변경할 수 없다.

 

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

컬렉션에 모든 종류의 객체를 저장할 수 있다는 것은 장점이기도하고 단점이기도 하다.

대부분의 경우 한 종류의 객체를 저장하며,

컬렉션에 지정된 종류의 객체만 저장할 수 있도록 제한하고 싶을 때 아래의 메서드를 사용한다.

더보기
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)
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 valueType)
static NavigableMap		checkedSortedMap(SortedMap m, Class keyType, Class valueType)

사용방법은 다음과 같이 두 번째 매개변수에 저장할 객체의 클래스를 지정하면 된다.

더보기
List list = new ArrayList();
List checkedList = checkedList(list, String.class);	// String만 저장가능
checkedList.add("abc");			// OK
checkedList.add(new Integer(3));	// 에러. ClassCastException발생

컬렉션에 저장할 요소의 타입을 제한하는 것은 지네릭스(generics)로 처리 가능하나

이런 메서드를 제공하는 이유는 호환성 때문이다. (version)

 

CollectoinsEx.java

더보기
package kr.co.dong.datastructure;


import java.util.*;
import static java.util.Collections.*;

public class CollectionsEx {
	public static void main(String[] args) {
		List list = new ArrayList();
		System.out.println(list);
		
		addAll(list, 1,2,3,4,5);
		System.out.println(list);
		
		rotate(list, 2);						// 오른쪽으로 두 칸씩 이동
		System.out.println(list);
		
		swap(list, 0, 2);					// 첫 번째와 세 번째를 교환(swap)
		System.out.println(list);
		
		shuffle(list);						// 저장된 요소의 위치를 임의로 변경
		System.out.println(list);
		
		sort(list, reverseOrder());			// 역순 정렬 reverse(list);와 동일
		System.out.println(list);
		
		sort(list);							// 정렬
		System.out.println(list);
		
		int idx = binarySearch(list, 3);	// 3이 저장된 위치(index)를 반환
		System.out.println("index of 3 = " + idx);
		
		System.out.println("max = "+max(list));
		System.out.println("min = "+min(list));
		System.out.println("min = "+max(list, reverseOrder()));
		
		fill(list, 9);						// list를 9로 채운다.
		System.out.println("list = "+list);
		
		// list와 같은 크기의 새로운 list를 생성하고 2로 채운다. 단, 결과는 변경불가
		List newList = nCopies(list.size(), 2);
		System.out.println("newList = " + newList);
		
		System.out.println(disjoint(list, newList));	//공통요소가 없으면 true
		
		copy(list, newList);
		System.out.println("newList = " + newList);
		System.out.println("list = "+list);
		
		replaceAll(list, 2, 1);
		System.out.println("list = "+list);
		
		Enumeration e = enumeration(list);
		ArrayList list2 = list(e);
		
		System.out.println("list2 = " + list2);
	}
}
/*
실행결과
[]
[1, 2, 3, 4, 5]
[4, 5, 1, 2, 3]
[1, 5, 4, 2, 3]
[2, 5, 4, 3, 1]
[5, 4, 3, 2, 1]
[1, 2, 3, 4, 5]
index of 3 = 2
max = 5
min = 1
min = 1
list = [9, 9, 9, 9, 9]
newList = [2, 2, 2, 2, 2]
true
newList = [2, 2, 2, 2, 2]
list = [2, 2, 2, 2, 2]
list = [1, 1, 1, 1, 1]
list2 = [1, 1, 1, 1, 1]
*/

 

'Computer Science > DataStructure' 카테고리의 다른 글

Stack (스택)  (0) 2023.05.03
컬렉션 클래스 정리 & 요약  (0) 2022.11.23
Properties  (0) 2022.11.22
TreeMap  (0) 2022.11.22
해싱과 해싱함수  (0) 2022.11.21