Java/컬렉션 프레임워크

List, Set, Map 인터페이스

개발자-제이 2023. 8. 27. 15:26

Collection 인터페이스 (List, Set의 조상)

 

 Collection 인터페이스의 메서드

메서드 설명
boolean add(E e) 지정된 요소 e를 컬렉션에 추가.
boolean addAll(Collection<? extends E> c) 주어진 컬렉션 c의 모든 요소를 현재 컬렉션에 추가.
void clear() 컬렉션의 모든 요소를 제거.
boolean contains(Object o) 컬렉션이 특정 객체 o를 포함하고 있는지 여부를 반환.
boolean containsAll(Collection<?> c) 컬렉션이 주어진 컬렉션 c의 모든 요소를 포함하고 있는지 여부를 반환.
boolean isEmpty() 컬렉션이 비어 있는지 확인.
Iterator<E> iterator() 컬렉션을 순회할 수 있는 Iterator를 반환.
boolean remove(Object o) 컬렉션에서 특정 객체 o를 제거 (첫 번째 일치하는 항목).
boolean removeAll(Collection<?> c) 컬렉션에서 주어진 컬렉션 c의 모든 요소를 제거.
boolean retainAll(Collection<?> c) 주어진 컬렉션 c에 포함된 요소만 유지하고, 나머지는 제거.
int size() 컬렉션의 요소 개수를 반환.
Object[] toArray() 컬렉션의 모든 요소를 포함하는 배열을 반환.
<T> T[] toArray(T[] a) 컬렉션의 요소를 지정된 배열 a의 타입에 맞게 변환하여 반환.

Collectrion 인터페이스는 컬렉션 클래스(List, Set으로 구현한 클랙스) 저장된 데이터를 읽고, 추가하고, 삭제하는 컬렉션을 다루는데 가장 기본적인 메서드들을 정의하고 있다.


List 인터페이스 (Collection 인터페이스의 자손)

List 인터페이스는 데이터 값에 대한 "중복을 허용"하고 "저장순서가 유지"되는 컬렉션을 구현하는데 사용된다. List 인터페이스를 구현한 클래스로는 ArrayList, LinkedList 있다.

  • 순서 O, 중복O

*참고* 위 List 인터페이스 특징에 대해 서술한 "컬렉션 구현하는데 사용된다". 말에 혼동이 있다.  컬렉션은 일반적으로 컬렉션 프레임워크의 인터페이스로 구현한 클래스의 "인스턴스" 표현하는 개념이다.

예를 들어, "List 컬렉션"이라고 하면 List 인터페이스를 구현한 클래스인 ArrayList LinkedList 같은 클래스의 "인스턴스" 의미하는 것이다. 마찬가지로 "Set 컬렉션"이라고 하면 Set 인터페이스를 구현한 HashSet TreeSet 같은 클래스의 인스턴스를 말하는 것이다.

 

List 상속 계층도

List 인터페이스의 메서드 

메서드 설명
void add(int index, E element) 특정 index 위치에 요소 element를 삽입.
boolean add(E e) 리스트의 끝에 요소 e를 추가.
boolean addAll(Collection<? extends E> c) 리스트의 끝에 컬렉션 c의 모든 요소를 추가.
boolean addAll(int index, Collection<? extends E> c) 특정 index 위치에 컬렉션 c의 모든 요소를 삽입.
void clear() 리스트의 모든 요소를 제거.
boolean contains(Object o) 리스트에 특정 요소 o가 포함되어 있는지 확인.
E get(int index) 특정 index 위치의 요소를 반환.
int indexOf(Object o) 리스트에서 처음으로 나타나는 o의 위치를 반환.
int lastIndexOf(Object o) 리스트에서 마지막으로 나타나는 o의 위치를 반환.
boolean isEmpty() 리스트가 비어 있는지 확인.
Iterator<E> iterator() 리스트를 순회할 수 있는 Iterator 반환.
ListIterator<E> listIterator() 리스트를 순회할 수 있는 ListIterator 반환.
ListIterator<E> listIterator(int index) 특정 index 위치에서 시작하는 ListIterator 반환.
E remove(int index) 특정 index 위치의 요소를 제거하고 반환.
boolean remove(Object o) 리스트에서 처음 발견되는 요소 o를 제거.
boolean removeAll(Collection<?> c) 리스트에서 컬렉션 c에 포함된 모든 요소를 제거.
boolean retainAll(Collection<?> c) 리스트에서 컬렉션 c에 포함된 요소만 유지하고 나머지는 제거.
E set(int index, E element) 특정 index 위치의 요소를 element로 변경.
int size() 리스트의 요소 개수를 반환.
List<E> subList(int fromIndex, int toIndex) 리스트의 fromIndex부터 toIndex 이전까지의 부분 리스트 반환.
Object[] toArray() 리스트의 모든 요소를 포함하는 Object[] 배열 반환.
<T> T[] toArray(T[] a) 리스트의 요소를 배열 a에 맞춰 변환하여 반환.
void sort(Comparator<? super E> c) 리스트를 주어진 Comparator에 따라 정렬.
void replaceAll(UnaryOperator<E> operator) 리스트의 모든 요소를 operator를 이용해 변경.

 


Set 인터페이스(Collection 인터페이스의 자손)

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

  • 순서 X 중복 X 

Set 상속계층도

 

Set 인터페이스의 메서드

메서드 설명
boolean add(E e) 요소 e를 추가 (중복된 요소는 추가되지 않음).
boolean addAll(Collection<? extends E> c) 컬렉션 c의 모든 요소를 추가 (중복 요소는 제외됨).
void clear() 모든 요소를 제거.
boolean contains(Object o) 특정 요소 o가 포함되어 있는지 여부를 확인.
boolean containsAll(Collection<?> c) 주어진 컬렉션 c의 모든 요소가 포함되어 있는지 여부 확인.
boolean isEmpty() Set이 비어 있는지 확인.
Iterator<E> iterator() Set을 순회할 수 있는 Iterator 반환.
boolean remove(Object o) 특정 요소 o를 제거.
boolean removeAll(Collection<?> c) 컬렉션 c의 모든 요소를 Set에서 제거.
boolean retainAll(Collection<?> c) Set에서 c에 포함된 요소만 유지하고 나머지는 제거.
int size() Set의 요소 개수를 반환.
Object[] toArray() Set의 모든 요소를 포함하는 배열 반환.
<T> T[] toArray(T[] a) Set의 요소를 지정된 타입의 배열 a로 변환하여 반환.
void forEach(Consumer<? super E> action) 각 요소에 대해 action을 실행.
Spliterator<E> spliterator() Set의 요소를 나누어 처리할 수 있는 Spliterator 반환.
   
boolean removeIf(Predicate<? super E> filter) 조건을 만족하는 요소를 제거 (Java 8부터 추가).

 


Map 인터페이스

 

Map 인터페이스는 키(Key)와 값(Value)을 하나의 쌍으로 묶어서 저장하는 컬렉션 클래스를 구현하는 데 사용된다. 키는 고유해야하므로, 중복될 수 없지만 값은 중복을 허용한다. (Key와 value의 관계를 id와 password의 관계와 같다고 생각하면 쉽다. 사용자의 id는 중복되면 안되지만, password는 중복되어도 상관없다). 

  • 순서 X 중복 (키 X 값 O)

기존에 저장된 데이터와 중복된 키와 값을 저장하면 기존의 값은 없어지고 마지막에 저장된 값이 남게 된다.(키의 중복을 허용하지 않기 때문)

Map인터페이스를 구현한 클래스로는, Hashtable, HashMap, LinkedHashMap, SortedMap, TreeMap 등이 있다.

*참고*  키와 인덱스는 비슷하지만 다른 개념이다. 인덱스는 순차적인 위치를 가진다는 개념이지만, 키는 특정 위치라는 개념이 없다. 책으로 비유하자면, 소설 책과 사전이라고 생각할 수 있다. 소설 책을 읽는 방법은 순차적으로 페이지를 넘겨가며 읽지만, 사전은 특정 단어를 찾아서 읽는다. 여기서 소설책의 페이지 번호를 인덱스라고 비유하고, 사전의 특정 단어는 키라고 표현할 수 있는 것이다.

이 예시에서는 사전의 정렬 방식은 제외를 하고 생각해야 이해할 수 있다. 단지 특정 단어로 값을 찾다라는 의미에 초점을 두어야 한다. 그 이유는 Map의 요소(키, 값)은 순차적으로 메모리에 저장되지 않고 분산되어 저장되기 때문이다. (Map의 특징 순서X) 

Map의 상속 계층도 

Map 인터페이스의 메서드

메서드 설명
void clear() 모든 키-값 매핑을 제거.
boolean containsKey(Object key) 특정 키가 존재하는지 확인.
boolean containsValue(Object value) 특정 값이 존재하는지 확인.
V get(Object key) 특정 키에 매핑된 값을 반환.
V getOrDefault(Object key, V defaultValue) 키가 존재하면 값을 반환하고, 없으면 defaultValue 반환.
boolean isEmpty() Map이 비어 있는지 확인.
V put(K key, V value) 키-값을 추가하거나 기존 키의 값을 변경.
void putAll(Map<? extends K, ? extends V> m) 다른 Map의 모든 키-값을 현재 Map에 추가.
V putIfAbsent(K key, V value) 특정 키가 존재하지 않을 때만 값을 추가.
V remove(Object key) 특정 키에 해당하는 항목을 제거하고 값을 반환.
boolean remove(Object key, Object value) 특정 키-값 쌍이 일치하면 제거.
V replace(K key, V value) 특정 키의 값을 새로운 값으로 변경.
boolean replace(K key, V oldValue, V newValue) 특정 키의 기존 값이 oldValue일 때만 newValue로 변경.
int size() Map에 저장된 키-값 개수를 반환.
Set<K> keySet() Map에 있는 모든 키를 Set으로 반환.
Collection<V> values() Map에 있는 모든 값을 Collection으로 반환.
Set<Map.Entry<K, V>> entrySet() Map에 있는 모든 키-값 쌍을 Set<Map.Entry<K, V>> 형태로 반환.
void forEach(BiConsumer<? super K, ? super V> action) 모든 키-값 쌍에 대해 action 실행.
V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) 특정 키의 값을 새롭게 계산.
V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) 키가 없을 경우 값을 계산하여 추가.
V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) 키가 존재할 경우 값을 새롭게 계산.
V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) 특정 키의 값과 새 값을 병합.

*참고* 위 메서드에서 반환 타입이 Collection인 것과 Set인 것이 약간의 혼동을 일으킬 수 있다. 이는 Java의 컬렉션 프레임워크 설계에서 유래한 것이다. Collection 인터페이스(List, Set)는 List, Set과 같은 "단일 요소 컬렉션"을 다루는 인터페이스이다. 반면 Map은 요소가 키와 값, 쌍으로 이루어져 있다. (즉, 키와 값이 하나의 요소로 취급된다.)

Map 인터페이스의 values() 메서드는 키-값 중 모든 '값(value)'을 컬렉션(Collection) 형태로 반환한다. (키와 값을 분리하여 값만을 다루게 되면 "단일 요소로써" Collection으로 다루는 것이 효율적이라서 반환 타입이 Collection인 것이다.) 이는, Map의 모든 값들을 모아서 List나 Set처럼 다룰 수 있도록 도와준다.(List와 Set은 Collection인터페이스의 자손) 

 

List와 Set으로 반환되는 기준은 아래 예시를 통해 알아본다. 

Map<> ageMap1 = new HashMap<>();
Map<> ageMap2 = new HashMap<>();

// 중복된 값이 있는 Map
ageMap1.put("Tom", 20);	
ageMap1.put("Bob", 20);
ageMap1.put("David", 30);

// 중복된 값이 없는 Map
ageMap1.put("Tom", 10);	
ageMap1.put("Bob", 20);
ageMap1.put("David", 30);

List의 특징은 앞서 서술한대로 "중복을 허용"하기 때문에, values() 메서드 호출 시 Map의 모든 값 중에 중복된 값이 있으면, List 형태로 반환하는 것이고 중복된 값이 없으면 Set 형태로 반환하는 것이다.

이와 마찬가지로 위 Map의 메서드 중, keySet()메서드가 반환 타입이 Set인 이유는 Map의 특성 상 ''는 중복을 허용하지 않기 때문에 반환타입이 Set인 것이다. 

 

Map.Entry 인터페이스

Map.Enty 인터페이스는 Map 인터페이스의 내부 인터페이스이다. 내부 클래스의 개념과 같이 인터페이스도 인터페이스 안에 인터페이스를 정의하는 "내부 인터페이스(inner interface)를 정의하는 것이 가능하다.

Map에 저장되는 key와 value쌍을 다루기 위해 내부적으로 Entey인터페이스를 정의해 놓았으며, 이것은 보다 객체지향적으로 설계하도록 유도하기 위한 것으로 Map인터페이스를 구현하는 클래스에서는 Map.Entry 인터페이스도 함께 구현해야 한다. 


비교

종류 List Set Map
특징 순서O, 중복O 순서X, 중복X 순서X, 중복(키X, 값O)
구현 클래스  ArrayList, LinkedList 등 HashSet, TreeSet 등 HashMap, TreeMap 등

 

출처 - 자바의 정석 3판 ( 저자: 남궁성)

반응형

'Java > 컬렉션 프레임워크' 카테고리의 다른 글

Set 컬렉션 - TreeSet(개념)  (0) 2023.09.06
List 컬렉션, LinkedList  (2) 2023.09.03
List 컬렉션, ArrayList  (0) 2023.09.02
컬렉션 프레임워크  (0) 2023.08.27