-
[Java] Collection 프레임워크(List, Set, Map)Java 2020. 3. 4. 02:51반응형
java.util 패키지는 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 Collection과 관련된 인터페이스와 클래스를 제공한다.
Collection 프레임워크 주요 인터페이스
- List
- Set
- Map
List 인터페이스
- List 인터페이스를 구현한 클래스 : ArrayList, Vector, LinkedList
- 순서를 유지한 상태로 저장하고 객체 중복 저장을 허용한다.
- 객체를 인덱스로 관리하기 때문에 객체가 추가되면 자동 인덱스가 부여되고 해당 인덱스를 통해 객체를 검색, 삭제할 수 있는 기능을 제공한다.
- 객체 자체를 저장하는 것이 아니라 객체의 주소 값을 참조하는 것.
- List 인터페이스의 공통 메소드
method 기능 boolean add(E e) 객체를 리스트 맨 마지막에 추가 void add(int index, E e) 객체를 주어진 인덱스에 추가 E set(int index, E e) 주어진 인덱스에 존재하는 객체를 주어진 객체로 변경 boolean contains(Object o) 주어진 객체의 존재여부 E get(int index) 주어진 인덱스의 저장된 객체를 리턴 boolean isEmpty() collection이 비어있는지 여부 int size() 모든 객체 수를 리턴 void clear() 저장되어 있는 모든 객체를 삭제 E remove(int index) 주어진 인덱스에 저장된 객체를 삭제 boolean remove(Object o) 주어진 객체를 삭제 - ArrayList
- ArrayList는 List 인터페이스의 구현 클래스이며, 객체를 추가하면 인덱스로 관리한다.
- 생성할 때 크기가 고정되고 사용 중에 크기를 변경할 수 없는 배열과 달리, ArrayList는 메모리가 허용하는 선에서 저장 용량을 초과하면 자동적으로 용량을 늘린다.
- 특정 인덱스의 객체를 제거하면 바로 뒤 인덱스부터 마지막 인덱스까지 모두 앞으로 한 칸씩 당겨진다.
- 특정 인덱스의 객체를 중간부터 추가하면 해당 인덱스부터 마지막 인덱스까지 모두 뒤로 한칸씩 밀려난다.(맨 마지막에 추가할 경우 밀려날 것이 없음)
- 자료의 최대 개수가 크면 클수록 중간 삽입에 의해 밀리는 값의 양이 많으므로 속도에 영향이 큼.
장점 단점 index를 검색하여 조회할 경우 매우 빠른 수행 속도를 가짐. 데이터 검색에 유리함.
빈번한 객체 중간 삽입과 삭제가 일어날 경우, 객체가 삽입 또는 삭제되면서 인덱스의 값이 밀리거나 당겨지게 되므로 성능 에 대한 이슈 발생이 있을 수 있음.
- Vector
- Vector은 ArrayList와 동일한 내부 구조를 지님.
- ArrayList와 다른 점은 Thread safety 하다. 즉, 동기화된 메소드로 구성되어 멀티스레드가 동시에 이 메소드를 실행할 수 없고 하나의 스레드가 실행을 완료해야만 다른 스레드를 실행할 수 있다.
- LinkedList
- ArrayList와 사용방법은 같지만 내부 구조가 다름.
- 인덱스로 관리하는 ArrayList와 달리, LinkedList는 인접 참조를 링크해서 관리함.(각 객체들은 자신의 앞 객체와 뒤 객체가 누구인지만 알고 있다고 생각하자)
- 특정 인덱스의 객체를 삽입, 제거 시, 해당 객체의 앞과 뒤 링크만 변경되고 나머지 링크는 변경되지 않는다.
장점 단점 빈번한 객체 삽입과 삭제가 일어날 경우, 불필요한 데이터 복사가 없고 해당 객체의 앞과 뒤 링크만 변경시켜주면 되기 때문에 빠른 수행이 가능하다.
객체 검색 시, 처음부터 객체를 순회하는 구조이기 때문에 성능상 이슈가 발생할 수 있다.
Set 인터페이스
- Set 인터페이스를 구현한 클래스 : HashSet, TreeSet, LinkedHashSet
- 순서를 유지하지 않고 객체 중복 또한 허용하지 않는다.
- index로 객체를 검색해서 가져오지 않고 전체 객체를 대상으로 한 번씩 반복해서 가져오는 반복자를 사용함.(iterator)
Set<String> names = new HashSet<String>(); Iterator<String> it = names.iterator(); while(it.hasNext()){ // 가져올 객체가 있으면 true 없으면 false String name = it.next(); // 객체 하나를 가져옴 }
- Set 인터페이스의 공통 메소드
method 기능 boolean add(E e) 주어진 객체를 저장하고 성공하면 true, 중복 객체가 존재하면 false를 리턴 Iterator<E> iterator() 저장된 객체를 한 번씩 가져오는 반복자 리턴 boolean contains(Object o) 주어진 객체의 존재여부 boolean isEmpty() collection이 비어있는지 여부 int size() 모든 객체 수를 리턴 void clear() 저장되어 있는 모든 객체를 삭제 boolean remove(Object o) 주어진 객체를 삭제 - HashSet
Set<E> set = new HashSet<E>();
- HashSet은 객체들을 순서 없이 저장하고 동일한 객체는 중복 저장하지 않는다.(여기서 의미하는 중복 객체란 같은 인스턴스를 의미하는 것이 아닌 equals() 메소드로 두 객체를 비교해서 나오는 값이 같을 때, 동일한 객체로 판단한다.)
Map 인터페이스
- Map 인터페이스를 구현한 클래스 : HashMap, Hashtable, TreeMap, Properties, LinkedHashMap
- 키(Key)와 값(Value)을 하나의 쌍으로 묶어서 관리하는 구조(키를 중복 저장할 경우, 기존의 값이 없어지고 새로운 값이 대치된다.)
- 키와 값 모두 객체
- Map 인터페이스의 공통 메소드
method 기능 K put(K key, V value) 주어진 key로 value를 저장. 새로운 key일 경우 null을 리턴하고 동일한 key가 있을 경우 새로운 value로 대체하고 이전 value를 반환 boolean containsKey(Object Key) 주어진 key의 존재 여부 boolean containsValue(Object value) 주어진 value의 존재여부 Set<Map.Entry<K, V>> entrySet() key와 value의 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아서 리턴 V get(Object key) 주어진 key에 해당하는 value를 리턴 boolean isEmpty() collection이 비어있는지 여부 Set<K> keySet() 모든 key를 Set 객체에 담아서 리턴 int size() 저장된 key의 총 수를 리턴 Collection<V> values() 저장된 모든 value를 Collection에 담아서 리턴 void clear() 모든 Map.Entry를 삭제 V remove(Object key) 주어진 key와 일치하는 Map.Entry를 삭제하고 value를 리턴 저장된 전체 Map객체를 하나씩 받아오는 방법
- keySet() 메소드 사용
// Map 생성 Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "바나나"); map.put(2, "사과"); map.put(3, "메론"); // keySet() 메소드로 모든 key를 Set 컬렉션에 주입 Set<Integer> set = map.keySet(); // iterator 사용해서 순회하며 key 구하기 Iterator<Integer> it = set.iterator(); while(it.hasNext()) { int key = it.next(); System.out.println("key : " + key); // key를 통해 value 구하기 System.out.println("value : " + map.get(key)); }
- entrySet() 메소드 사용
// Map 생성 Map<Integer, String> map = new HashMap<Integer, String>(); map.put(1, "바나나"); map.put(2, "사과"); map.put(3, "메론"); // entrySet() 메소드로 Map.entry를 Set 컬렉션에 주입 Set<Map.Entry<Integer, String>> entrySet = map.entrySet(); // iterator 사용해서 순회하며 entry 구하기 Iterator<Map.Entry<Integer, String>> entryIt = entrySet.iterator(); while(entryIt.hasNext()) { Map.Entry<Integer, String> entry = entryIt.next(); int key = entry.getKey(); String value = entry.getValue(); System.out.println("key : " + key); System.out.println("value : " + value); }
- HashMap
Map<String, Integer> map = new HashMap<String, Integer>();
- HashMap의 key로 사용할 객체는 hashCode()와 equals() 메소드를 재정의 해서 동등 객체가 될 조건을 정해야 한다.(key 타입으로 String을 많이 사용하는데, String은 문자열이 같은 경우 동등 객체가 될 수 있도록 hashCode()와 equals() 메소드가 정의되어 있음.)
- 키와 값 타입은 기본 타입은 사용할 수 없고 클래스 및 인터페이스 타입만 가능하다.
- Hashtable
Map<String, Integer> map = new Hashtable<String, Integer>();
- Hashtable은 HashMap과 동일한 내부 구조를 가지고 있다.
- key로 사용할 객체는 hashCode()와 equals() 메소드를 재정의 해서 동등 객체가 될 조건을 정해야한다.
- 동기화된 메소드로 구성되어 있기 때문에 멀티 스레드가 동시에 메소드를 실행할 수 없다.(Thread-satety)
반응형'Java' 카테고리의 다른 글
[Effective Java 공부하기] 4. 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) 2022.03.31 [Effective Java 공부하기] 2. 생성자에 매개변수가 많다면 빌더를 고려하라 (0) 2022.03.29 [JAVA] 정규표현식 정리하기(); (0) 2021.06.29 [Java] 제네릭 타입 정리하기(); (0) 2021.04.25 [java] 자바를 사용해서 메일 보내기 (feat. SMTP Protocol) (0) 2020.02.07