컬렉션 프레임워크
우리는 배열을 통해 자료 구조를 배웠다. 자료 구조는 프로그램 실행 시 메모리에 자료를 유지하고 관리하기 위해 사용한다. 배열은 정한 크기를 변경하거나 삭제할 수 없다. 또한 별도의 기능이 없기 때문에 직접 index를 이용해 데이터를 저장해야 했다. 자바는 이러한 불편함을 해결하기 위해 필요한 자료구조를 미리 구현하여 java.util 패키지에서 제공하는데 이를 컬렉션 프레임워크라고 한다.
| 인터페이스 | 설명 | 특징 | 대표 구현 클래스 |
| List | 순서가 있는 데이터의 집합 | 데이터 중복 허용 O | ArrayList, LinkedList |
| Set | 순서를 유지하지 않는 데이터의 집합 | 데이터 중복을 허용 X | HashSet, LinkedHashSet |
| Map | key와 value의 쌍으로 이루어진 데이터의 집합 | 순서 유지X, 키 중복 X, 값 중복 O | HashMap,LinkedHashMap, Properties |
제네릭
Integer형 배열, String 형 배열 등 배열에 포함되는 원소의 타입마다 추가, 삭제, 정렬과 같은 함수를 정의하고 사용하는 것은 비효율적이다. 제네릭은 데이터의 타입을 일반화한다는 것을 의미한다. 클래스나 메서드 정의 시 일반화하여 사용할 데이터 타입을 컴파일 할 때 미리 지정하는 방법이다. JDK 1.5 이전에는 여러 타입을 사용하는 대부분의 클래스나 메서드에서 반환값으로 Object 타입을 사용했다. 이러한 경우 런타임 오류가 발생할 수 있다. 하지만 제네릭을 사용하면 컴파일 할 때 타입이 미리 정해지므로 타입 검사나 변환과 같은 번거로운 작업 생략이 가능해 안정성을 높일 수 있다.
제네릭 타입은 타입을 파라미터로 가지는 클래스와 인터페이스를 말하며, 다음과 같이 선언한다.
public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}
T를 타입 변수라고 하는데 이를 이용해 타입을 제한한다. 여러 개의 타입변수는 쉼표로 구분해 명시할 수 있다. 타입 파라미터는 정해진 규칙은 없지만 일반적으로 알파벳 대문자 한 글자로 표현한다.
| 타입 변수 | 의미 |
| <T> | Type |
| <E> | Element |
| <K> | Key |
| <N> | Number |
| <V> | Value |
<T>로 표현한 것이 제네릭이다. 클래스에 제네릭을 부여하면 해당 클래스를 선언할 때 데이터 타입을 부여하게 된다. 그러면 객체를 생성할 때 타입이 지정된 부분이 대체되어 해당 클래스는 지정된 객체만을 저장할 수 있게 되고, 따로 타입을 변환할 필요 없이 데이터를 출력할 수 있다. 제네릭을 이용하면 하나의 객체를 다양한 데이터를 사용할 수 있다.
List 컬렉션
List는 배열과 유사한 자료 구조로 중복이 허용되면서 저장 순서가 유지되는 구조를 제공한다. 즉 배열처럼 index를 사용해 데이터를 저장하고 찾는다. 다만, 배열과는 다르게 크기의 제한이 없으며 삽입, 삭제, 변경의 기능이 자유롭다. 데이터의 크기를 특정할 수 없는 다량의 데이터를 저장할 때 용이하게 사용할 수 있는 자료 구조이다.
| 메서드 | 동작 | 기능 설명 |
| void add(E e) | 삽입 | 데이터를 순차적으로 삽입 |
| void add(int index, E e) | 중간 삽입 | 원하는 index 위치에 삽입 |
| void set(int index, E e) | 치환 | 원하는 index 위치의 값 변경 |
| E get(int index) | 반환 | 선택된 index 위치의 값 반환 |
| void remove(int index) | 삭제 | 선택된 index 위치의 값 삭제 |
| void clear() | 전체 삭제 | 모든 데이터 삭제 |
| int size() | 크기 | 저장된 데이터의 개수 반환 |
| boolean contains(Object o) | 검색 | 데이터의 존재 여부 확인 |
ArrayList는 가장 많이 사용하는 List 인터페이스의 대표적인 구현 클래스이다. 다음과 같이 선언하면 된다.
List <데이터 타입> list = new ArrayList <데이터 타입> ();
자료 구조 선언 시 저장할 데이터의 타입을 명시해야 하는데, 지정되는 데이터는 항상 객체형으로 지정해야 한다. int형, long 형, double 형과 같은 기본 자료형은 대응하는 Wrapper 클래스를 이용해 지정한다.
데이터를 추가하려면 add(E e), add(int index, E e) 메서드를 사용한다. 여기서 E는 리스트 선언 시 지정한 저장 데이터 객체를 의미한다. 일반적인 add(E e) 메서드를 이용해 데이터를 삽입하면 기존에 존재하는 마지막 데이터의 뒤에 차례대로 삽입된다. 삽입 시에는 index가 부여되며 배열과 마찬가지로 순차적으로 부여된다. add(int index, E) 메서드는 원하는 index 위치에 데이터를 삽입할 수 있다. 그러나 연속성 없이 순서를 부여해 삽입하는 것은 불가능하다.
List에 저장된 데이터를 변경할 수 있는데, 변경을 원하는 index 위치와 치환할 값 또는 객체를 지정하면 해당 위치의 값이 변경된다. 이때 이와 같이 메서드를 사용하면 된다.
void set(int index, E value);
List의 데이터 삭제는 단지 데이터만 삭제되는 게 아니라 해당 위치의 공간까지 삭제된다. 배열의 경우 공간이 생성되면 삭제할 수 없지만, List는 원하는 위치의 공간을 삭제할 수 있으며 빈 공백을 메우기 위해 뒤의 데이터들이 앞으로 이동한다.
List에 담긴 값을 가졍로 때는 E get(int index) 메서드를 이용해 원하는 index 위치에 저장되어 있는 값을 출력할 수 있다.
LinkedList는 데이터와 다음 데이터의 주소를 가지는 노드 객체가 연결되어 데이터를 저장하는 자료구조이다 ArrayList와 마찬가지로 List 컬렉션의 구현 클래스이므로 사용할 수 있는 메서드가 대부분 동일하다. ArrayList는 배열을 이용해 데이터를 저장하는 반면, LinkedList는 node라는 객체를 생성해 인접 데이터를 링크해서 체인처럼 관리한다.
List<Integer> list = new LinkedList<Integer>();
List<Integer> list = new LinkedList<>();
LinkedList의 데이터 추가 기능은 ArrayList와 동일하다. add(E e) 또는 add(int index, E e) 메서드를 이용해 데이터를 추가한다. 데이터를 추가할 때는 기존에 연결되어 있던 링크를 끊고, 추가되는 데이터에 새롭게 주소를 연결한다. 또한 추가되는 노드는 뒤에 올 데이터와 링크하여 삽입한다. ArrayList는 삽입되는 위치부터 맨 뒤의 데이터까지 이동시키고 데이터를 삽입하기 때문에 삽입 속도가 느리지만 LinkedList는 노드가 가지고 있는 다음에 오는 개체의 주소만 변경하면 되기에 빠르게 처리할 수 있다.
삭제는 ArrayList와 동일하게 remove(int index) 또는 remove(Object o) 메서드를 이용하면 된다. 삭제할 데이터와의 연결을 끊고 그 뒤의 데이터와 연결하여 쉽게 데이터를 삭제한다.
Set 컬렉션
List 컬렉션과 다르게 객체의 저장 순서를 저장하지 않는다. Set 컬렉션은 수학의 집합과 유사한 개념을 지니고 있다. List 컬렉션은 데이터 저장 시 중복을 허용하지만 Set 컬렉션은 데이터의 중복을 허용하지 않는다. 또한 데이터를 저장할 때 index를 부여하지 않기 때문에 데이터가 입력된 순서로 출력된다는 보장은 없다.
| 메서드 | 기능설명 |
| void add(E e) | 데이터를 순차적으로 삽입 |
| void remove(Object o) | 선택된 값 삭제 |
| void clear() | 모든 데이터 삭제 |
| int size() | 저장된 데이터의 개수 반환 |
| boolean contains(Object o) | 데이터의 존재 여부 확인 |
HashSet 클래스는 Set 컬렉션 클래스에서 가장 많이 사용되느 클래스로 인터페이스를 상속받아 구현한다.
Set<E> set = new HashSet<E>();
Set<E> set = new HashSet<>();
HashSet은 데이터를 저장할 때 순서를 부여하지 않고, 데이터의 중복을 허용하지 않는다. 동일한 값 또는 객체를 허용하지 않는다는 의미이다. 여기서 동일한 객체란, 꼭 같은 타입의 인스턴스를 의미하는 것은 아니다. HashSet은 데이터를 객체의 hasCode() 값을 호출하여 비교하고 같으면 equals() 메서드를 호출해 다시 비교해 두 객체가 같음을 증명한다.
데이터 삭제는 List 컬렉션과 동일하게 remove(Object O)메서드를 사용하고 index가 존재하지 않으므로 순서에 의한 삭제는 지원하지 않는다.
반복자 Iterator
Iterator<E>는 List 컬렉션에서 제공하는 인터페이스로 사전적인 의미로는 반복하다라는 뜻을 지니고 있다 List 컬렉션의 요소를 순회하여 하나씩 추출하는데 사용한다. E에는 순회할 데이터의 타입을 지정하는데 보통 순회할 컬렉션이 포함하는 데이터 타입과 동일하게 지정한다.
| 메서드 | 기능 설명 |
| boolean hashNext() | 다음에 순회할 데이터 유무 확인. 가져올 객체가 있으면 true, 없으면 false를 반환 |
| E next() | 다음 위치의 데이터로 이동하여 반환 |
Map 컬렉션
Map은 List, Set과 달리 별도로 존재하며 데이터를 List 계열의 컬렉션과 다르게 처리한다. key와 value로 구분하여 저장하는 방식을 사용한다. HashMap, TreeMap, LinkedHashMap이 있다. HashMap은 Map 이넡페이스를 구현하여 가장 많이 사용하는 대표적인 클래스이다. Map에서 key는 중복될 수 없지만, value는 중복이 가능하다. 만약 key가 중복되어 입력될 경우, key에 해당하는 value 값이 업데이트되어 저장되기 때문에 key의 중복에 유의해야 한다.
HashMap은 앞에서 다뤘던 HashSet과 마찬가지로 해싱을 통해 Key의 중복 여부를 판단한다. 즉, key로 지정된 객체의 hashCOde와 equals 메서드를 이용해 동일여부를 판단하게 된다. HashMap은 Map 인터페이스를 상속해 기능을 구현했기 때문에 Key의 중복을 허용하지 않는다
Map <KEY, V> map = new HashMap<KEY, V>():
Map <KEY, V> map = new HashMap<>():'BOOK' 카테고리의 다른 글
| [JAVA] MENTOR JAVA SECTION 18 (1) | 2025.01.25 |
|---|---|
| [JAVA] MENTOR JAVA SECTION 17 (3) | 2025.01.24 |
| [JAVA] MENTOR JAVA SECTION 15 (1) | 2025.01.22 |
| [JAVA] MENTOR JAVA SECTION 14 (1) | 2025.01.21 |
| [JAVA] MENTOR JAVA SECTION 13 (2) | 2025.01.20 |