컬렉션 프레임워크(Collection Framework)이란, 데이터 군을 저장하는 클래스들을 표준화한 설계를 뜻한다. 컬렉션은 다수의 데이터, 프레익워크는 표준화된 프로그래밍방식을 의미한다. (출처: 자바의 정석)
컬렉션 프레임워크에서는 List
인터페이스, Set
인터페이스, Map
인터페이스 크게 3개의 인터페이스를 정의했는데 인터페이스와 다형성을 이용한 객체지향적 설계를 통해 표준화되어 있기 때문에 재사용성이 높은 코드를 작성할 수 있다는 장점이 있다.
위에서 언급한 것처럼 컬렌션 프레임워크에서는 3가지 인터페이스를 정의했지만 List
와 Set
을 구현한 컬렉션 클래스들은 많은 공통부분이 있었기 때문에 컬렉션 인터페이스를 추가로 정의했다. 이는 Java언어의 객체지향적 성격을 잘 살린 설계라고 볼 수 있다. Map
인터페이스는 이들과 다른 형태의 컬렉션을 다루기 때문에 상속계층도에 포함되지 못했다.
인터페이스 | 특징 | 구현클래스 |
---|---|---|
List | 순서 유지 O, 데이터 중복 저장 O | ArrayList, LinkedList, Stack, Vector 등 |
Set | 순서 유지 X, 데이터 중복 저장 X | HashSet, TreeSet 등 |
Map | 키와 값을 쌍으로 저장, 순서 유지 X, 키 중복 저장 X | HashMap, TreeMap, Hashtable, Properties 등 |
Vector
, Hashtable
과 같은 기존의 컬렉션 클래스들은 호환을 위해, 설계를 변경해서 남겨두었지만 가능하면 ArrayList
와 HashMap
을 사용하도록 하자.
Map 인터페이스는 Key
와 Value
를 하나의 쌍으로 묶어서 저장하는 컬렉션 클래스를 구현하는 데 사용된다. 키는 중복될 수 없고 값은 중복을 허용한다.
Map인터페이스로 구현한 클래스로는 Hashtable, HashMap, SortedMap 등이 있다.
메서드 | 특징 |
---|---|
void clear() | Map의 모든 객체 삭제 |
boolean containsKey(Object key) | 지정된 key객체와 일치하는 Map의 key객체가 있는지 확인 |
boolean containsValue(Object value) | 주어진 value객체와 일치하는 Map의 value객체가 있으면 true, 없으면 false 리턴 |
Set entrySet() | key-value쌍으로 구성된 모든 Map.Entry 타입의 객체를 Set에 담아서 리턴 |
Object get(Object key) | 주어진 key객체에 대응하는 value객체를 찾아서 반환 |
boolean isEmpty() | 컬렉션이 비어 있는지 확인 |
Set keySet() | Map에 저장된 모든 key를 Set 객체에 담아서 리턴 |
Object put(Object key, Object value) | Map에 value객체를 key객체에 연결(mapping)하여 저장 (새로운 키일 경우 null 리턴, 동일한 키가 있을 경우 값 대체하고 이전값 리턴) |
Object remove(Object key) | 주어진 key객체와 일치하는 key-value 객체 삭제 |
int size() | 저장된 key-value 쌍의 총 갯수 리턴 |
Collection values() | Map에 저장된 모든 value객체 반환 |
HashMap
은 Map
을 구현했으므로 키와 값을 묶어서 하나의 데이터(entry)
로 저장한다는 특징을 갖는다. 그리고 해싱을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어서 뛰어난 성능을 보인다.
public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {
transient Entry[] table;
...
static class Entry implements Map.Entry {
final Object key;
Object value;
...
}
}
HashMap
의 실제 코드를 보면 Entry
라는 내부 클래스를 정의하고 Entry
타입의 배열을 선언하여 데이터를 저장하는 것을 볼 수 있다. 이는 객체지향적 관점에서에서 키, 값을 각각 다른 배열에 선언한는 것에 비해 데이터 무결성 보장할 수 있기 때문이다.
class HashMapEx {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "user1");
map.put(2, "user2");
map.put(3, "user3");
System.out.println("총 entry 수 : " + map.size());
System.out.println("2 : " + map.get(2));
}
}
/* 출력:
총 entry 수 : 3
2 : user2
*/