컬렉션은 다수의 데이터, 프레임워크는 표준화된 프로그래밍 방식을 의미합니다. 따라서 컬렉션 프레임워크란 데이터 그룹을을 저장하는 클래스들을 표준화한 설계입니다.
쉽게 말해 자료구조와 데이터를 처리하는 알고리즘을 클래스로 구현해 놓은 것이 Java Collection Framework(JCF) 입니다. 따라서, 직접 자료구조를 구현하지 않고 프레임워크를 가져와서 사용하면 됩니다.
컬렉션 프레임워크에 사용 가능한 데이터는 Object(객체)입니다다. 따라서 int, double, long 등의 primitive type은 사용이 불가능합니다. Wrapper 타입으로 변환해서 박싱해서 저장해야 합니다. null도 저장이 가능합니다.
컬렉션 프레임워크는 크게 Collection 인터페이스와 Map 인터페이스로 나뉩니다.
List, Set, Queue의 구현 클래스들은 공통 부분이 많기에 Collcetion 인터페이스로 정의되어 있습니다.
Map 인터페이스는 두 개의 데이터를 한 쌍으로 관리하기 때문에 Collection 프레임워크와 분리되어 있습니다.
💡 Vector, Stack, HashTable 등은 컬렉션 프레임워크가 아닙니다. JCF가 만들어지기 전부터 존재해왔기 때문에 네이밍 규칙도 맞지 않습니다. 또한, 기존 코드 호환을 위해 남겨진 클래스들이므로 사용하지 않는 것이 좋습니다.
컬렉션 인터페이스들의 최상위 인터페이스이자, Iterator 객체를 관리하는 인터페이스입니다.
메소드 | 설명 |
---|---|
default void forEach(Consumer<? super T> action) | 람다 전용 메소드 |
Iterator<T> iterator() | Iterator |
default Spliterator<T> spliterator() | 파이프라이닝 관련 메소드 |
Map은 Iterable을 상속받지 않기 때문에, Stream을 사용하거나 Key를 Collection으로 변환한 후 반복문을 사용해야 합니다.
List, Set, Queue의 상위 인터페이스
다형성을 이용하여 Collection 타입으로만 사용해도 다양한 기능을 사용할 수 있습니다.
메소드 | 설명 |
---|---|
boolean add(Object o) boolean addAll(Collection c) | 객체 또는 객체들을 Collection에 추가 |
boolean contains(Object o) boolean containsAll(Collection c) | 객체 또는 객체들이 Collection에 포함되어 있는지 확인 |
boolean remove(Object o) boolean removeAll(Collection c) | 객체 또는 객체들을 Collection에서 삭제 |
boolean retainAll(Collection c) | 객체들(c)만 남기고 나머지는 Collection에서 삭제. 변화가 있으면 true, 없으면 false 리턴 |
void clear() | 모두 삭제 |
boolean equals(Object o) | 동일한 Collection인지 비교 (hash 기반 컬렉션이면 equals()만 재정의하면 다르다고 판단) |
int hashCode() | Collection의 해시코드를 반환 |
boolean isEmpty() | 빈 Collection인지 확인 |
Iterator iterator() | Collection의 iterator 반환 (Iterable의 기능) |
int size() | Collection에 저장된 객체 개수 반환 |
Object[] toArray() | Collection을 Array로 반환 |
Object[] toArray(Object[] a) | 배열 a에 Collection의 객체를 저장해서 반환 |
add, remove, contains 기능은 있지만 get 메소드는 존재하지 않습니다. 구현 클래스의 자료구조가 제각각이므로 get은 구현 인터페이스에 정의되어 있습니다.
메서드 | 설명 |
---|---|
void add(int index, Object element) boolean addAll(int index, Collection c) | 특정 index에 객체 또는 객체들을 추가 |
Object remove(int index) | 특정 index에 있는 객체를 삭제하고 리턴 |
Object get(int index) | 특정 index의 객체 반환 |
Object set(int index, Object element) | 특정 index에 객체 추가 |
int indexOf(Object o) | 객체 o의 index 반환 |
int lastIndexOf(Object o) | 객체 o의 index 반환 (거꾸로) |
List subList(int fromIndex, int toIndex) | 특정 Range(from ~ to) 객체 반환 |
ListIterator listIterator() ListIterator listIterator(int index) | ListIterator |
void sort(Comparator c) | Comparator를 통해 리스트 정렬 |
add()
메소드로 요소를 추가해주다가 리스트 공간보다 더 커질 경우, 배열 크기 확장!grow()
메소드ArraysSupport.newLength()
oldCapacity >> 1
입니다.oldCapacity >> 1
은 모든 2진수 비트를 우측으로 1씩 이동하기 때문에, 2를 나누는 것과 동일합니다. (비트 연산자는 속도가 빠름)ArrayList
의 구형 버전 (거의 비슷)Collctions.synchronizedList()
를 쓰면 되기 때문Stack은 클래스이고, Queue는 인터페이스입니다.
ArrayDeque
사용)LinkedList, PriorityQueue, ArrayDeque
)메서드 | 설명 |
---|---|
boolean add(Object o) | Queue에 객체 추가 저장공간 부족 시 IllegalStateException 발생 |
Object remove() | Queue에서 객체를 꺼내 반환 비어있을 경우 NoSuchElementException 발생 |
Object element() | 첫번째 요소 반환 비어있을 경우 NosuchElementException 발생 |
boolean offer(Object o) | Queue에 객체 추가 저장공간 부족 시(저장에 실패할 경우) false 반환 |
Object poll() | 첫 번째 요소 제거 및 반환 비어있을 경우 null을 반환 |
Object peek() | 첫 번째 요소 반환 비어있을 경우 null을 반환 |
peek()
또는 poll()
사용시 최솟갑 반환.compareTo()
로직에 따라 우선순위를 결정하기 때문)위에 적어 놓았습니다.
HashMap
사용PRESENT
라 불리는 빈 Object.add()
에서 put()
결과가 null이면 새로운 요소가 추가된 것이고, remove()
에서 remove()
결과가 PRESENT
이면 이전 요소가 잘 삭제된 것을 의미합니다.public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
add()
메소드if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
EnumSet<UserType> userTypeSet = EnumSet.allOf(UserType.class);
Set entrySet()
, Set keySet()
, Collection values()
ConcurrentHashMap
사용