13 / 컬렉션 프레임워크
자바는 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 인터페이스와 구현 클래스를 java.util 패키지에서 제공하는 데 이를 컬렉션 프레임워크라고 한다.
- 컬렉션: 객체의 저장을 의미
- 프레임워크: 사용법을 정해놓은 라이브러리, 짜여진 틀
List 컬렉션
* 객체를 배열처럼 인덱스로 관리하는 컬렉션으로 각 인덱스마다 객체 번지를 참조하고 있다.
* 배열과 달리 저장 용량이 자동으로 증가하고 객체 저장시 자동 인덱스가 부여된다.
* List 컬렉션에는 ArrayList, Vector, LinkedList 등이 있다
* List컬렉션에서 공통 사용 가능한 List 인터페이스의 메소드
| 기능 | 메소드 | 설명 |
| 객체 추가 | boolean add(E element) | 주어진 객체를 맨 끝에 추가 |
| void add(int index, E element) | 주어진 인덱스에 객체를 추가 | |
| E set(int index, E element) | 주어진 인덱스에 저장된 객체를 주어진 객체로 바꾼다. | |
| 객체 검색 | boolean contains(Object o) | 주어진 객체가 저장되어 있는 지 조사 |
| E get(int index) | 주어진 인덱스에 저장된 객체를 리턴 | |
| boolean isEmpty() | 컬렉션이 비어 있는지 조사 | |
| int size() | 저장되어 있는 전체 객체 수를 리턴 | |
| 객체 삭제 | void clear() | 저장된 모든 객체 삭제 |
| E remove(int index) | 주어진 인덱스에 저장된 객체 삭제 | |
| boolean remove(Object o) | 주어진 객체 삭제 |
* E는 제네릭으로 그때 그때 맞는 클래스타입을 넣어주면 된다.
- ArrayList
List<E> list = new ArrayList<E>();
List<E> list = new ArrayList<>();
* 기본 생성자로 객체 생성시 내부에 10개의 객체를 저장할 수 있는 초기 용량을 가지며, 이후 초과되면 자동 증가한다.
* 인덱스는 0번 부터 시작
* 중간 인덱스를 제거하면 그 뒤의 인덱스들은 1씩 당겨짐
* 중간 인덱스를 추가하면 그 뒤의 인덱스들은 1씩 밀려남
이 당겨지고 밀러나는 동작때문에 객체수가 많거나 중간 인덱스의 삭제 추가가 빈번하게 일어난다면 LinkedList를 사용하는 것이 좋다. 하지만 인덱스를 이용해 객체를 찾거나 맨 마지막에 객체를 추가하는 경우라면 ArrayList가 더 성능이 좋다.
- Vector
List<E> list = new Vector<E>();
List<E> list = new Vector<>();
ArrayList와 동일한 내부구조를 가지나 동기화(Synchronized)된 메소드로 구성되어 있어 멀티 스레드가 동시에 Vector의 메소드를 실행할 수 없어, 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제 할 수 있다.
- LinkedList
List<E> list = new LinkedList<E>();
List<E> list = new LinkedList<>();
LinkedList도 ArrayList와 사용법과 동일하나, 내부 구조가 다르다.
ArrayList는 내부 배열에 객체를 저장해서 관리하지만, LinkedList는 인접 참조를 링크해 체인처럼 관리한다.

LinkedList에서 특정 인덱스를 삭제하거나 추가하면, 삭제되거나 추가된 인덱스 전후의 링크만 변경되고 나머지 링크는 변경되지 않는다.

만약 객체가 10000개인 ArrayList에 10번째 인덱스를 추가했다면 10번 부터 객체가 모두 밀리는 동작이 실행되지만 LinkedList라면 단 두개인 9번과 기존 10번 인덱스의 링크만 변경해주면 되므로 이런 부분에서는 LinkedList가 훨씬 효율적이다.
| 구분 | 순차적으로 추가/삭제 | 중간에 추가/삭제 | 검색 |
| ArrayList | 빠르다 | 느리다 | 빠르다 |
| LinkedList | 느리다 | 빠르다 | 느리다 |
Set 컬렉션
* List컬렉션과 달리 Set컬렉션은 저장 순서가 유지되지 않는다. 즉, 순서 상관없다.
* 객체가 중복되지 않는다
* null도 단 한개만 저정할 수 있다.
* Set컬렉션에는 HashSet, LinkedHashSet, TreeSet 등이 있다
* Set컬렉션에서 공통 사용 가능한 Set 인터페이스 메소드
| 기능 | 메소드 | 설명 |
| 객체 추가 | boolean add(E e) | 주어진 객체를 저장. 저장 성공시 true리턴, 중복 개체면 false리턴 |
| 객체 검색 | booleancontains(Object o) | 주어진 객체가 저장되어 있는지 조사 |
| boolean isEmpty() | 컬렉션이 비어있는지 조사 | |
| Iterator<E> iterator() | 저장된 객체를 한번씩 가져오는 반복자를 리턴 | |
| int szie() | 저장되어 있는 전체 객체 수 리턴 | |
| 객체 삭제 | void clear() | 저장된 모든 객체를 삭제 |
| boolean remove(Object o) | 주어진 객체 삭제 |
반복자는 Iterator 인터페이스를 구현한 객체를 말하는데 iterator 메소드를 호출하면 얻을 수 있다.
Set<String> set = ...;
Iterator<String> iterator = set.iterator();
//---- 사용 예제1
Set<String> set = ...;
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()){
String str = iterator.next();
}
//---- 사용 예제2
Set<String> set= ...;
for(String str : set){
}
//---- 사용 예제3
while(iterator.hasNext()){
String str = iterator.next();
if(str.equals("홍길동")){
iterator.remove();
}
}
| 리턴 타입 | 메소드 | 설명 |
| boolean | hasNext() | 가져올 객체가 있으면 true리턴, false리턴 |
| E | next() | 컬렉션에서 하나의 객체를 가져온다 |
| void | remove() | Set 컬렉션에서 객체를 제거 |
- HashSet
Set 인터페이스 구현 클래스
Set<E> set = new HashSet<E>();
Set<E> set = new HashSet<>();
* HashSet은 객체들을 순서없이 저장하고 동일한 객체는 중복 저장하지 않는다.
* HashSet이 판단하는 동일한 객체란 꼭 같은 인스턴스를 뜻하지 않는다. 객체를 저장하기전 HashCode() 메소드를 호출해서 해시코드를 얻고, 이미 저장되어 있는 해시코드와 비교하며, 혹 같은 해시코드가 있다면 이를 다시 equals()메소드로 객체 비교를 하여 true가 나오면 최종적으로 같은 객체로 판단. 중복 저장을 하지않는다.
* String 같은 경우는 같은 문자열을 갖으면 같은 객체로 간주된다.
Map 컬렉션
* Map 컬렉션으 키(Key)와 값(Value)로 구성된 Map.Entry 객체를 저장하는 구조를 가지고 있다.
* Entry는 Map 인터페이스 내부에 선언된 중첩 인터페이스로 키와 값은 모두 객체이다.
* 키는 중복될 수 없으나 값은 중복 될 수 있다.
(만일 저장된 키와 동일한 키로 값을 저장하면 기존 값이 없어지고 새로운 값으로 대체)
* Map 컬렉션에는 HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등이 있다.
* Map 컬렉션에서 공통적으로 사용 가능한 Map 인터페이스의 메소드
| 기능 | 메소드 | 설명 |
| 객체 추가 | V put (K key, V value) | 주어진 키로 값을 저장, 새로운 키 경우 null 리턴, 동일한 키 있을 경우 값 대체하고 이전 값 리턴 |
| 객체 검색 | boolean containsKey(Object key) | 주어진 키가 있는지 여부 확인 |
| boolean containsValue(Object value) | 주어진 값이 있는지 여부 확인 | |
| Set<Map.Entry<K, V>> entrySet() | 키와 값의 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아서 리턴 | |
| V get(Object Key) | 주어진 키가 있는 값을 리턴 | |
| boolean isEmpty() | 컬렉션이 비어 있는지 여부 확인 | |
| Set<K> KeySet | 모든 키를 Set객체에 담아서 리턴 | |
| int size() | 저장된 키의 총 수를 리턴 | |
| Collection<V> values() | 저장된 모든 값을 Collection에 담아서 리턴 | |
| 객체 삭제 | void clear() | 모든 Map.Entry(키와 값)을 삭제 |
| V remove(Object key) | 주어진 키와 일치하는 Map.Entry를 삭제하고 값을 리턴 |
- HashMap
* HashMap의 키로 사용할 객체는 hashCode()와 equals()메소드를 재정의해서 동등 객체가 될 조건을 정해야한다.
동등 객체의 조건은 hashCode()의 리턴값이 같아야하고, equals() 메소드가 true를 리턴해야 한다.

Map<K, V> map = new HashMap<K, V>();
예시)
Map<String, Integer> map = new HashMap<String, Integer>();
Map<String, Integer> map = new HashMap<>();
- Hashtable
Hashtable은 HashMap과 동일한 내부 구조를 가지고 있다. Hashtable도 키로 사용할 객체는 hashCode()와 equals()메소드를 재정의해서 동등 객체가 될 조건을 정해야 한다.
차이점은 Hashtable안은 동기화(synchronized) 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 Hashtable의 메소드를 실행할 수 없고, 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행 할 수 있다. 그래서 Hashtable은 스레드에 안전 (thread safe) 하다.
Map<K, V> map = new Hashtable<K, V>();
예시)
Map<String, Integer> map = new Hashtable<String, Integer>();
Map<String, Integer> map = new Hashtable<>();
'Programming > Java' 카테고리의 다른 글
| 혼공자바] 14-1 입출력 스트림 (0) | 2022.12.27 |
|---|---|
| 혼공자바] 13-2 LIFO와 FIFO 컬렉션 (0) | 2022.12.27 |
| 혼공자바] 12-2 스레드 제어 (0) | 2022.12.19 |
| 혼공자바] 12-1 멀티 스레드 (1) | 2022.12.15 |
| 혼공자바] 11 기본 API 클래스 (0) | 2022.12.14 |
