[Java/자바] 컬렉션 프레임워크(Collections Framework)

컬렉션 프레임워크란 "다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미" 합니다.

즉, 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것입니다.

또한, 인터페이스와 다형성을 이용한 객체지향적 설계를 통해 표준화되어 있어 재사용성이 높은 코드를 작성할 수 있고,

다수의 데이터를 다루는데 필요하고 다양하고 풍부한 클래스들을 제공하여 프로그래머들에게 편리함을 제공해줍니다. 

 

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

컬렉션 프레임워크에서는 데이터를 저장하는 자료 구조에 따라 다음과 같은 3가지 타입이 존재 합니다.

그리고 인터페이스 List와 Set의 공통된 부분을 뽑아서 새로운 인터페이스인 Collection을 추가로 정의하였습니다.

List와 Set 인터페이스를 구현한 컬렉션 클래스들은 서로 많은 공통 부분을 가져, 공통된 부분을 다시 뽑아 Collection인터페이스를 정의 했지만

Map인터페이스는 이들과는 저녛 다른 형태로 컬렉션을 다루기 때문에 상속계층도에는 포함되지 않습니다.

 

핵심 인터페이스들의 특징
인터페이스 특징 구현 클래스
List<E> 순서가 있는 데이터의 집합으로, 데이터의 중복을 허용 Vector, ArrayList, LinkedList, Stack, Queue
Set<E> 순서가 없는 데이터의 집합으로, 데이터의 중복을 허용X HashSet, TreeSet
Map<K, V> 키와 값의 한 쌍으로 이뤄지는 데이터의 집합으로, 순서가 없음.
( 키는 중복 O, 값은 중복 X )
HashMap, TreeMap, Hashtable, Properties

 

핵심 인터페이스들의 상속 관계

점선은 구현 관계이고, 실선은 상속 관계입니다. (인터페이스끼리는 다중 상속이 가능)

 Collection을 구현한 클래스 및 인터페이스들은 모두 java.util 패키지에 있습니다.

 

위 그림에서 하늘색의 박스들은 인터페이스로, 녹색 박스들은 이 하늘색 박스들을 구현한 클래스들입니다.

 

생소한 Iterable이란 단어가 있는데 '반복 가능한' 이라는 뜻으로

Iterable 에서는 for-each 제공합니다.

즉, Iterable 인터페이스를 쓰는 모든 클래스들은 기본적으로 for-each 문법을 쉽게 사용할 수 있습니다.

for-each 문법은 따로 키워드가 있는게 아니라 향상된 for 문입니다.

 


Collection 인터페이스

List와 Set의 조상인 Collection 인터페이스에는 다음가 같은 메서드들이 정의 되어 있습니다.

메서드 반환 타입 설명
add(Object o)
addAll(Object o)

boolean  지정된 객체(o) 또는 Collection(c)의 객체들을 Collection에 추가
clear()   Collection의 모든 객체를 삭제
contains(Object o )
containsAll(Object o )
boolean  지정된 객체(o) 또는 Collection의 객체들이 Collection에 포함되었는지 확인
equals(Object o) boolean 동일한 Collection인지 비교
hashCode() int  Collection의 hash code를 반환
isEmpty() boolean  Collection이 비어있는지 확인
iterator() lterator  Collection의 lterator를 얻어서 반환
remove(Object o) boolean  지정된 객체를 삭제
removeAll(Collection c) boolean  지정된 Collection에 포함된 객체들을 삭제
retainAll(Collection c) boolean  지정된 Collection에 포함된 객체만을 남기고 다른 객체들은 Collection에서 삭제.
이 작업으로 Collection에 변화가 있으면 true 없으면 false
size() int  Collection에 저장된 객체의 개수를 반환
toArray() Object[]  Collection에 저장된 객체를 객체배열(Object[])로 반환
toArray(Object[] a) Object[]  지정된 배열에 Collection의 객체를 저장해서 반환

 


List 인터페이스

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

메서드 반환 타입 설명
add(int i, Object e)
addAll(int index, Object e)
boolean 지정된 위치(i)에 객체(e) 또는 컬렉션에 포함된 객체들을 추가
get(int i) Object  지정된 위치(i)에 있는 객체를 반환
indexOf(Object o) int  지정된 객체의 위치(i)를 반환
(List의 첫 번째 요소부터 순반향)
lastIndexOf(Object o) int  지정된 객체의 위치(i)를 반환
(List의 마지막 요소부터 역방향)
listlterator()
listlterator(int i)

Listlterator  List 객체에 접근할 수 있는 Listlterator 를 반환
remove(int i) Object  지정된 위치(i)에 있는 객체를 삭제하고 삭제된 객체를 반환.
set(int i, Object e) Object  지정된 위치(i)에 객체(e)를 저장 ( 값 변경 )
sort(comparator c) void 지정된 비교자(comparator)로 List를 정렬
subList(int strat, int end) List  지정된 범위(start부터 end)에 있는 객체를 반환.

 

 


Set 인터페이스

Set 인터페이스는 중복을 허용하지 않고 저장순서가 유지되지 않는 컬렉션 클래스를 구현하는데 사용됩니다.

메서드 반환 타입 설명
add(Object o) boolean 지정된 요소가 없을 경우 추가.
이미 지정된 요소가 존재할 경우 false를 반환
contains(Object o) boolean 지정된 요소가 Set에 있는지 확인
equals(Object o) boolean 지정된 객체와 현재 Set이 같은지 비교
isEmpty() boolean 현재 Set이 비었을 경우 true, 아니면 false
remove(Object o) boolean 지정된 객체를 제거
size() int Set에 있는 요소의 개수를 반환
clear() void Set에 있는 모든 요소들을 제거
first(Object  o) Object  첫 번째 요소(가장 낮은 요소)를 반환.
last() Object  마지막 요소(가장 높은 요소)를 반환
headSet(Object  toElement) SortedSet<E> 지정된 요소 (toElement)보다 작은 요소들을 Set으로 반환
tailSet(Object  formElement) SortedSet<E> 지정된 요소 (fromElement)보다 큰 요소들을 Set으로 반환
subSet(Object  form, Object  to) SortedSet<E> 지정된 from요소를 포함해 from보다 크고, 지정된 to 요소보다 작은 Set 반환

 

 


Map 인터페이스

키(key)와 값(value)을 하나의 쌍으로 묶어 저장하는 컬렉션 클래스를 구현하는 데 사용됩니다.

이때 키는 중복을 허용하지 않지만, 값은 중복을 허용합니다.

기존에 저장된 데이터와 중복된 키와 값을 저장하면 기존의 값은 없어지고 마지막에 저장된 값이 남습니다.

메서드 반환 타입 설명
clear() void Map의 모든 객체를 삭제
containsKey(Object key) boolean 지정된 key객체와 일치하는 Map의 key객체가 있는지 확인
containsValue(Object value) boolean 지정된 value객체와 일치하는 Map의 value객체가 있는지 확인
entrySet() Set Map에 저장되어 있는 key - value쌍을 Map.Entry타입의 객체로 저장한 Set으로 반환.
equals(Object o) boolean 동일한 Map인지 확인
get(Object key) Object 지정한 key객체에 대응하는 value객체를 반환
hashCode() int 해시코드를 반환
isEmpty() boolean Map이 비어있는지 확인
keySet() Set Map에 저장된 모든 key객체를 반환.
put(Object key, Object value) Object Map에 Value객체를 key객체에 연결하여 저장.
putAll(Map t) void 지정된 Map의 모든 key-value쌍을 추가.
remove(Object key) Object 지정한 key객체와 일치하는 key-value쌍을 삭제
size() int Map에 저장된 key-value쌍의 개수를 반환
values() Collection Map에 저장된 모든 value객체를 반환

 

여기서 keySet()과 values() 메서드를 봅시다.

keySet()은 반환타입이 Set이고, values()는 반환타입이 Collection입니다.

Map인터페이스에서 값은 중복을 허용하기 때문에 Collection타입으로 반환하고, 키는 중복을 허용하지 않기 때문에 Set타입으로 반환합니다.

 


Map.Entry 인터페이스

Map인터페이스의 내부 인터페이스로,  Map에 저장되는 key-value쌍을 다루기 위해 내부적으로 Entry인터페이스를 정의한 것입니다.

Map인터페이스를 구현하는 클래스에서는 Map.Entry인터페이스도 함께 구현해야합니다.

 

메서드 반환 타입 설명
equals(Object o) boolean 동일한 Entry인지 비교
getKey() Object Entry의 key객체를 반환
getValue() Object Entry의 value객체를 반환
hashCode() int Entry의 해시코드를 반환
setValue(Object value) Object Entry의 value객체를 지정된 객체로 바꾼다.

 

Map.Entry를 사용하는 경우

 

  • Map의 entrySet()를 이용해 key와 value의 값이 모두 필요한 경우
import java.util.Map;
import java.util.HashMap;

public class MapEntryEx1 {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<>();
		map.put("A", 10);
		map.put("B", 30);
		
		for(Map.Entry<String, Integer> entry : map.entrySet()) {
			System.out.println("entry.getKey = " + entry.getKey());
			System.out.println("entry.getValue = " + entry.getValue());
		}
	}
}

 

 

  • 스트림(Stream) 사용 시 Map 형식의 데이터에서 처리가 필요할 때

(Map.Entry :: getKey는 Map.Entry의 getKey 메소드를 사용)

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

public class MapEntryEx2 {

	public static void main(String[] args) {
		Map<String, Integer> map = new HashMap<>();
		map.put("A", 10);
		map.put("B", 30);
		
		for(Map.Entry<String, Integer> entry : map.entrySet()) {
			System.out.println("entry.getKey = " + entry.getKey());
			System.out.println("entry.getValue = " + entry.getValue());
		}
		
		// map의 key 값을 리스트로 변환
		System.out.println(map.entrySet().stream()
					.map(Map.Entry<String, Integer>::getKey)
					.collect(Collectors.toList())
		);
		
		// map의 value 값을 리스트로 변환
		System.out.println(map.entrySet().stream()
				.map(Map.Entry<String, Integer>::getValue)
				.collect(Collectors.toList())
		);
	}
}

 


참고자료
자바의 정석3
https://st-lab.tistory.com/142
http://www.tcpschool.com/java/java_collectionFramework_concept