컬렉션 객체의 저장을 뜻하고, 프레임워크는 사용 방법을 정해놓은 라이브러리를 말한다.
컬렉션 프레임워크는 사용 방법을 정의한 인터페이스와 실제 객체를 저장하는 다양한 구현 클래스를 제공한다.
컬렉션 프레임 워크의 주요 인터페이스에는 List, Set, Map 이 있다.
List 컬렉션 은 배열과 비슷하게 객체를 인덱스로 관리한다.
배열과 차이점이 있다면 저장 용량이 자동으로 증가, 객체를 저장할 때 자동 인덱스가 부여된다는 점이다. 또 추가, 삭제, 검색을 위한 다양한 메소드들이 제공된다.
List 컬렉션은 객체 자체를 저장하는 것이 아닌 객체의 번지를 참조한다. 그렇기 때문에 동일한 객체를 중복 저장할 수 있는데 이런 경우에는 동일한 번지가 참조된다.
null도 저장이 가능한데 이 경우에는 해당 인덱스는 객체를 참조하지 않는다.
< List 특징 >
- 요소의 저장 순서가 유지된다. (순서 보장)
- 같은 요소의 중복 저장을 허용한다.
List 컬렉션에는 ArrayList, Vector, LinkedList 등이 있다.
List 컬렉션에서 공통적으로 사용 가능학 List 인터페이스의 메소드이다.
기능 | 메소드 | 설명 |
---|---|---|
객체추가 | boolean add(E e) | 주어닌 객체를 맨 끝에 추가 |
void add(int index, E element) | 주어진 인덱스에 객체를 추가 | |
E set(int index, E element) | 주어진 인덱스에 저장된 객체를 주어진 객체로 바꿈 | |
객체 검색 | boolean contains(Object o) | 주어진 객체가 저장되어 있는지 확인 |
E get(int indext) | 주어진 인덱스에 저장된 객체를 리턴 | |
boolean isEmpty() | 컬렉션이 비어 있는지 조사 | |
int size() | 저장되어 있는 전체 객체 수 리턴 | |
객체 삭제 | void clear() | 저장된 모든 객체 삭제 |
E remove(int index) | 주어진 인덱스에 저장된 객체 삭제 | |
boolean remove(Object o) | 주어진 객체를 삭제 |
ArrayList 는 List 인터페이스의 대표적인 구현 클래스이다.
ArrayList를 생성하기 위해서는 저장할 객체 타입은 E타입 파라미터 자리에 표기하고 기본 생성자를 호출하면 된다.
List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<>();
ArrayList 객체를 생성하면 내부에 10개의 객체를 저장할 수 있는 초기 용량을 가지게 된다.
저장되는 객체 수가 늘어나면 자동으로 용량이 증가한다.
ArrayList에 객체를 추가하면 0번 인덱스부터 순서대로 저장된다.
ArrayList에 특정 인덱스의 객체를 삭제하면 바로 뒤 인덱스부터 마지막 인덱스까지 앞으로 1씩 당겨지고,
반대로 특정 인덱스에 객체를 삽입하면 해당 인덱스부터 마지막 인덱스까지 모두 1씩 밀려난다.
특정 인덱스에 객체를 추가, 제거하는 일이 빈번하다면 ArrayList 사용하는 것은 좋지 않다.
인덱스를 이용해서 객체를 찾거나 맨 마지막에 객체를 추가하는 경우에는 ArrayList 를 사용하는 것이 좋다.
Vector 는 ArrayList와 동일한 내부 구조를 가지고 있다. Vector를 생성하기 위해서는 저장할 객체 타입을 타입 파라미터로 표기하고 기본 생성자를 호출하면 된다.
List<E> list = new Vector<E>();
List<E> list = new Vector<>();
ArrayList와 차이점은 Vector는 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 Vector의 메소드들을 실행할 수 없고, 하나의 스레드가 메소드를 실행을 완료해야지만 다른 스레드가 메소드를 실행할 수 있다는 점이다.
그래서 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있다.
LinkedList는 List 구현 클래스이다. ArrayList와 사용 방법은 똑같은데 내부 구조는 완전 다르다.
ArrayList 는 내부 배열에 객체를 저장해서 관리하지만,
LinkedListsms 인접 참조를 링크해서 체인처럼 관리한다.
LinkedList에서 특정 인덱스의 객체를 제거하면 앞뒤 링크만 변경되고 나머지 링크는 변경되지 않는다.
특정 인덱스에 객체를 삽입할 때도 마찬가지이다.
LinkedList를 생성하기 위해서는 저장할 객체 타입을 타입 파라미터(E)에 표기하고 기본 생성자를 호출하면 된다.
LinkedList가 처음 생성될 때는 어떠한 링크도 만들어지지 않기 때문에 내부는 비어 있다고 보면 된다.
List<E> list = new LinkedList<E>();
List<E> list = new LinkedList<>();
순차적으로 추가, 삭제하는 경우 => ArrayList가 빠르다. -> 비효율적인 메모리 사용.
중간에 추가, 삭제하는 경우 => 앞뒤 링크 정보만 변경하면 되는 LinkedList가 빠르다. -> 데이터가 많으면 접근성이 떨어진다.
구분 | 순차적 추가,삭제 | 중간에 추가,삭제 | 검색 |
---|---|---|---|
ArrayList | 빠르다 | 느리다 | 빠르다 |
LinkedList | 느리다 | 빠르다 | 느리다 |
Set 컬렉션 은 저장 순서가 유지되지 않는다. 객체를 중복해서 저장할 수 없고, 하나의 null만 저장할 수 있다.
Set 컬렉션은 수학의 집합과 비슷하다. 순서 상관없고 중복이 허용되지 않기 때문이다.
< Set 특징 >
- 요소의 저장 순서를 유지하지 않는다.
- 같은 요소의 중복 저장을 허용하지 않는다.
Set 컬렉션에는 HashSet, LinkedHashSet, TreeSet 등이 있다.
Set 컬렉션에서 공통적으로 사용 가능학 Set 인터페이스의 메소드이다.
기능 | 메소드 | 설명 |
---|---|---|
객체 추가 | boolean add(E e) | 주어진 객체 저장 |
객체 검색 | boolean contains(Object o) | 주어진 객체가 저장되어 있는지 확인 |
boolean inEmpty() | 컬렉션이 비어 있는지 조사 | |
Iterator< E> iterator() | 저장된 객체를 한 번씩 가져오는지 반복자를 리턴 | |
int size() | 저장되어 있는 전체 객체 수를 리턴 | |
객체 삭제 | void clear() | 저장된 모든 객체 삭제 |
boolean remove(Object o) | 주어진 객체를 삭제 |
Set 컬렉션은 인덱스로 객체를 검색해서 가져오는 메소드가 없다.
그대신 전체 객체를 대상으로 한 번씩 반복해서 가져오는 반복자를 제공한다.
반복자는 Iterator 인터페이스를 구현한 객체를 말하는데 iterator()메소드를 호출하면 얻을 수 있다.
Iterator 인터페이스에 선언된 메소드
리턴 타입 | 메소드 | 설명 |
---|---|---|
boolean | hasNext() | 가져올 객체가 있으면 true, 없으면 false 리턴 |
E | next() | 컬렉션에서 하나의 객체를 가져온다. |
void | remove() | Set컬렉션에서 객체를 제거 |
HashSet은 Set 인터페이스의 구현 클래스이다. hashSet을 생성하기 위해서는 기본 생성자를 호출하면 된다.
Set<E> set = new HashSet<E>();
타입 파라미터 E에는 컬렉션에 젖아할 객체 타입을 지정하면 된다.
HashSet은 객체들을 순서 상관없이 저장하고 동일한 객체는 중복 저장하지 않는다.
HashSet은 객체를 저장하기 전에 먼저 객체의 hashCode()메소드를 호출해서 해시코드를 얻어내고, 이미 저장되어 있는 객체들의 해시코드와 비교한다. 동일한 해시코드가 있다면 equals()메소드로 두 객체를 비교해서 true가 나오면 동일한 객체로 판단하고 중복 저장하지 않는다.
Map 인터페이스는 Collection 인터페이스와는 다른 저장 방식을 가진다.
Map 인터페이스를 구현한 Map 컬렉션 클래스들은 키와 값을 하나의 쌍으로 저장하는 방식(key-value 방식)을 사용한다.
Map 컬렉션은 키(key)와 값(value)으로 구성된 Map.entry 객체를 저장하는 구조를 가지고 있다.
Entry는 Map 인터페이스 내부에 선언된 중첩 인터페이스이다. 키와 값은 모두 객체이다.
키(key)는 중복 저장될 수 없지만, 값(value)은 중복 저장될 수 있다.
만약 기존에 저장된 키와 동일한 키로 값을 저장하면 기존 값은 없어지고 새로운 값으로 대체된다.
< Map 특징 >
- 요소의 저장 순서를 유지하지 않는다.
- 키는 중복을 허용하지 않지만, 값의 중복은 허용한다.
Map 컬렉션에는 HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등이 있다.
기능 | 메소드 | 설명 |
---|---|---|
객체 추가 | 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> keSet() | 모든 키를 Set 객체에 담아서 리턴 | |
int size() | 저장된 키의 총 수를 리턴 | |
Collection< V> values() | 저장된 모든 값을 Collection에 담아서 리턴 | |
객체 삭제 | void clear() | 모든 Map.Entry(키와값)를 삭제 |
V remove(Object key) | 주어진 키와 일치하는 Map.Entry를 삭제하고 값을 리턴 |
HashMap은 Map 인터페이스를 구현하는 대표적인 컬렉션이다.
HashMap의 키로 사용할 객체는 hashCode()와 equals() 메소드를 재정의해서 동등 객체가 될 조건을 정해야 한다.
객체가 달라도 동등 객체라면 같은 키로 간주하고 중복 저장되지 않도록 하기 위해서이다.
동등 객체의 조건은 hashCode()의 리턴값이 같아야 하고, equals()메소드가 true를 리턴해야 한다.
HashMap을 생성하기 위해서는 키 타입과 값 타입을 타입 파라미터로 주고 기본생성자를 호출하며 된다.
Map<K, V> map = new HashMap<K, V>();
키와 값의 타입은 기본 타입인 byte, short, int, float, double, boolean, char을 사용할 수 없고 클래스, 인터페이스 타입만 사용 가능하다.
Map<String, Integer> map = new HashMap<String, Integer>();
Map<String, Integer> map = new HashMap<>();
Hashtable은 HashMap과 동일한 내부 구조를 가지고 있다. Hashtable도 키로 사용할 객체는 hshCode()와 equals() 메소드를 재정의해서 동등 객체가 될 조건을 정해야 한다.
HashMap과 차이점은 Hashtable은 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 Hashtable의 메소드들을 실행할 수 없고, 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행 할 수 있다는 점이다.
Hashtable의 생성 방법은 키 타입과 값 타입을 지정하고 기본 생성자를 호출하면 된다.
Map<K, V> map = new Hashtable<K, V>();
참고
혼자공부하는 자바
TCP School(http://www.tcpschool.com/java/java_collectionFramework_concept)
코딩 팩토리(https://coding-factory.tistory.com/550)