코딩항해기

[JAVA] 컬렉션 프레임워크 (+Generic, Iterator) 본문

JAVA

[JAVA] 컬렉션 프레임워크 (+Generic, Iterator)

miniBcake 2024. 7. 15. 17:39

 

컬렉션 프레임워크

Collection Framework

 

자료구조 중 하나로 클래스들의 집합

많은 데이터를 쉽고 효과적으로 관리할 수 있는 표준화 된 방법

 


 

 

자료구조

의미없는 데이터를 하나의 정보로 만들어주는 알고리즘들의 집합이다.

수집한 자료를 저장하는 방법이다.

 

 

컬렉션 프레임워크 (Collection Framework)

자료구조 많은 데이터를 쉽고 효과적으로 관리할 수 있는 표준화된 방법을 제공하는 클래스들의 집합

Collection 특징 구현클래스
List 순서를 유지하고 저장 (index)
중복 저장 가능
ArrayList, LinkedList, Voctor
Set 순서를 유지하지 않고 저장
중복 저장 불가능
HashSet, TreeSet
Map 키와 값으로 구성된 엔트리 저장
키값은 중복될 수 없다. (PK와 동일)
HashMap, Hashtable, Properties

 

Generic < >

 

컬렉션 프레임워크처럼 자료형이 규정되어 있지 않을 때 이를 강제하는 역할을 해준다.

꺽쇠 괄호 안에는 Wrapper class가 들어갈 수 있다. (정수형 Integer, 실수형 Double 등...)

클래스명<T> 변수 = new 생성자<T>();

//T는타입의 약자
//변수를 선언할 때 동일한 타입으로 호출하고 싶다면 생성자 호출시에
//타입을 명시하지 않고<>만 붙일 수 있다

클래스명<T> 변수 = new 생성자<>();

 

 

Iterator (반복자)

자바의 제네릭 프로그램을 지원하는 인터페이스 중 하나로, 자바 컬렉션 프레임워크에서 많이 사용된다.

특히 컬렉션 내부의 요소들을 반복(iterate)하고자 할 때 사용한다.

 

컬렉션에 저장된 데이터를 순회하고 가져오기 위해 사용되며, 컬렉션의 종류와 상관없이 동일한 방식으로 데이터를 가져올 수 있기 때문에 컬렉션 프레임워크를 일관된 방식으로 다룰 수 있다.

 

Iterator를 통해 값을 가져올 때는 커서 (cursor)를 이용하여 컬렉션을 순회하면서,

다음 값을 가리키고 값을 가져올 수 있다.

 

Iterator<E> 메소드

메소드 기능 반환값
hasNext() Iterator에 다음 요소가 있는지 확인하여,
요소가 있으면 true, 없으면 false를 반환한다.
boolean
next() Iterator의 다음 요소를 반환한다.
요소가 없으면 NoSuchElementException 예외가 발생한다.
E (요소)
remove() 현재 Iterator가 가리키는 요소를 삭제한다.
적절한 next() 호출 없이 remove()를 호출하면 예외가 발생한다.
void
forEachRemaining() Iterator의 남은 요소들에 대해 지정된 동작을 수행한다. void

 

 

Iterator<E> 문법

Set<E> set = new HashSet<>();
Iterator<E> iterator = set.iterator();

 

Iterator에 저장해 준 뒤, Iterator 메소드를 사용해줄 수 있다.

이후 set(HashSet 컬렉션프레임워크)를 조회하여도 반영되어있다.

 

 


 

ArrayList (배열 리스트)

 

데이터의 순서를 보장하고, 중복된 값을 허용한다

배열과 동일하게 인덱스로 데이터를 관리한다.

추가, 삭제는 상대적으로 느리지만 탐색(검색)이 빠르다.

 

배열과 ArrayList 차이

배열은 길이에 제한을 두어야할 때 자주 사용되고, ArrayList는 몇 개의 데이터가 들어올 지 알 수 없을 때 사용한다

 

ArrayList 메소드

메소드 기능 반환타입
add(E e) 지정된 요소를 리스트의 끝에 추가 boolean
add(int index, E element) 지정된 위치에 요소를 삽입 void
addAll(Collection<? extends E> c) 지정된 컬렉션의 모든 요소를 리스트의 끝에 추가 boolean
addAll(int index, Collection<? extends E> c) 지정된 위치에 컬렉션의 모든 요소를 삽입 boolean
clear() 리스트의 모든 요소를 제거 void
contains(Object o) 리스트에 지정된 요소가 포함되어 있는지 확인 boolean
get(int index) 지정된 위치의 요소를 반환 E
indexOf(Object o) 리스트에서 지정된 요소의 첫 번째 발생 위치를 반환 int
lastIndexOf(Object o) 리스트에서 지정된 요소의 마지막 발생 위치를 반환 int
isEmpty() 리스트가 비어 있는지 확인 boolean
remove(int index) 지정된 위치의 요소를 제거 E
remove(Object o) 리스트에서 지정된 요소의 첫 번째 발생을 제거 boolean
removeAll(Collection<?> c) 리스트에서 지정된 컬렉션에 포함된 모든 요소를 제거 boolean
retainAll(Collection<?> c) 리스트에서 지정된 컬렉션에 포함된 요소만을 유지하고 나머지는 제거 boolean
set(int index, E element) 지정된 위치의 요소를 지정된 요소로 대체 E
size() 리스트의 요소 개수를 반환 int
toArray() 리스트의 모든 요소를 포함하는 배열을 반환 Object[]
toArray(T[] a) 리스트의 모든 요소를 포함하는 지정된 타입의 배열을 반환 T[]
subList(int fromIndex, int toIndex) 리스트의 지정된 부분을 반환 List<E>
iterator() 리스트의 요소에 대한 반복자를 반환 Iterator<E>
listIterator() 리스트의 요소에 대한 리스트 반복자를 반환 ListIterator<E>
listIterator(int index) 지정된 위치에서 시작하는 리스트 반복자를 반환 ListIterator<E>

*e 는 element data의 약자 (요소)

 


HashSet

데이터의 순서를 보장하지 않으며, 데이터의 중복을 허용하지 않는다. (중복되는 값을 저장하면 무시한다.)

인덱스가 존재하기 않아 순서를 보장하지 않기 때문에 ArrayList와 같이 인덱스 방식으로 값을 가져오는 것이 불가능하다.

 

hashCode()가 반환하는 해시코드를 시용해서 데이터를 처리하기 때문에 속도가 상대적으로 빠르다.

값의 존재 여부를 파악할 때나 중복을 제거할 때 사용하기 좋은 자료구조이다.

 

HashSet 메소드

메소드 기능 반환타입
add(E e) 지정된 요소를 셋에 추가 boolean
addAll(Collection<T> c) 지정된 컬렉션의 모든 요소를 셋에 추가 boolean
clear() 셋의 모든 요소를 제거 void
contains(Object o) 지정된 요소가 셋에 포함되어 있는지 확인 boolean
isEmpty() 셋이 비어 있는지 확인 boolean
iterator() 셋의 요소에 대한 반복자를 반환 Iterator<E>
remove(Object o) 셋에서 지정된 요소를 제거 boolean
removeAll(Collection<T> c) 셋에서 지정된 컬렉션에 포함된 모든 요소를 제거 boolean
retainAll(Collection<T> c) 셋에서 지정된 컬렉션에 포함된 요소만을 유지하고 나머지는 제거 boolean
size() 셋의 요소 개수를 반환 int
toArray() 셋의 모든 요소를 포함하는 배열을 반환 Object[]
toArray(T[] a) 셋의 모든 요소를 포함하는 지정된 타입의 배열을 반환 T[]
clone() 셋의 얕은 복사본을 반환 Object
spliterator() 셋의 요소에 대한 Spliterator를 반환 Spliterator<E>

 

 

+ 중복 기준 수정하기!

객체의 중복여부를 판단하기 위해 사용되는 메소드는 Object클래스의 hashCode(), equals()이다.

equals()는 두 객체가 논리적으로 동일한지를 판단하고, hashCode()는 객체의 해시코드 값을 반환한다.

 

equals()를 오버라이딩(재정의)하여 기준을 변경해주었다면, hashCode()도 오버라이딩(재정의) 해주어야한다.

일관성과 검색 효율성이 저하되는 것을 방지하기 위함이다.


HashMap

데이터의 순서를 보장하지 않으며, 데이터를 Key와 Value 한 쌍으로 저장하여 Key로 데이터에 접근할 수 있다.

그러므로 Key는 index, PK와 비슷한 역할을 하며 Key값의 중복을 허용하지 않는다. (Value는 중복 허용)

 

hashCode()가 반환하는 해시코드를 이용하며, 검색속도가 상대적으로 빠르다.

이미 저장된 key를 가진 한 쌍의 데이터를 넣으면 가장 마지막에 넣은 Value로 수정된다.

저장되지 않는 key를 가진 한 쌍의 데이터를 넣으면 새롭게 추가된다.

 

키(key)

키(key)는 해시함수(has function)을 통해서 해시(hash)로 변경되고, 값(Value)과 매칭되어 저장된다.

키는 다양한 길이의 값이 될 수 있는데 이 상태로 최종 저장소에 저장이 되면 다양한 길이 만큼의 저장소를 구성해두어야한다. 때문에 해시함수로 값을 바꾸어 저장이 되어야만 공간의 효율성을 추구할 수 있다.

 

해시함수(Hash Function)

키(key)를 해시(hash)로 바꿔주는 역할을 한다.

다양한 길이를 가지고 있는 키(key)를 일정한 길이를 가지는 해시(hash)로 변경하여 저장소를 효율적으로 운영할 수 있다.

서로 다른 키(key)가 같은 해시(hash)가 되는 경우를 해시 충돌(Hash Collision)이라고 하는데, 해시 충돌을 일으키는 확률을 최대한 줄이는 함수를 만드는 것이 중요하다. 

Object클래스의 hashCode() 객체의 내용을 기준으로 해시코드를 생성한다.

일관성, 고유성, 고속성을 지킨 해시함수가 좋은 해시함수이다.

 

해시(Hash)

해시함수의 결과물 저장소(bucket, slot)에서 값(value)과 매칭되어 저장된다.

맵처럼 Key와 value로 이루어져있다. key를 Hash Function에 넣어서 특정 정수값을 산출한다. (해싱)

얻어낸 정수값을 저장소의 인덱스 번호로 사용하여 value를 저장한다.

value를 검색할 때도 key를 넘겨주면 해싱을 통해 해당 인덱스를 즉시 찾아간다.

 

값(Value)

저장소(bucket, slot)에 최종적으로 저장되는 값 키와 매칭되어 저장, 삭제, 검색, 접근이 가능해진다.

 

HashMap 메소드

메소드 기능 반환타입
put(K key, V value) 지정된 키와 값을 맵에 추가 V
putAll(Map<K, V> m) 지정된 맵의 모든 매핑을 이 맵에 복사 void
putIfAbsent(K key, V value) 지정된 키에 매핑된 값이 없을 경우에만 키와 값을 맵에 추가 V
get(Object key) 지정된 키에 매핑된 값을 반환 V
remove(Object key) 지정된 키에 매핑된 값을 제거 V
remove(Object key, Object value) 지정된 키와 값이 매핑된 항목을 제거 boolean
clear() 모든 매핑을 제거 void
containsKey(Object key) 지정된 키가 맵에 포함되어 있는지 확인 boolean
containsValue(Object value) 지정된 값이 맵에 포함되어 있는지 확인 boolean
isEmpty() 맵이 비어 있는지 확인 boolean
size() 맵의 매핑 개수를 반환 int
keySet() 맵의 모든 키를 포함하는 Set을 반환 Set<K>
values() 맵의 모든 값을 포함하는 Collection을 반환 Collection<V>
entrySet() 맵의 모든 매핑을 포함하는 Set을 반환 Set<Map.Entry<K, V>>
getOrDefault(Object key, V defaultValue) 지정된 키가 없을 경우 기본값을 반환 V
replace(K key, V value) 지정된 키의 값을 새로운 값으로 대체 V
replace(K key, V oldValue, V newValue) 지정된 키의 값이 주어진 값일 때만 새로운 값으로 대체 boolean
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) 지정된 키의 값을 병합하여 새로운 값으로 대체 V

'JAVA' 카테고리의 다른 글

[JAVA] 생성자 (+this, this())  (0) 2024.07.20
[JAVA] 배열 (+index, Arrays)  (1) 2024.07.17
[JAVA] 연산자  (0) 2024.07.14
[JAVA] 인터페이스 (+Adapter, 마커인터페이스)  (0) 2024.07.13
[JAVA] 자바 프로그래밍의 기초  (0) 2024.07.12