23장 - 자바랭 다음으로 많이 쓰는 애들은 컬렉션 ― Part2 (Set과 Queue)
Set
- 데이터 중복 허용 x (순서 x) ➡ 데이터가 같은지 확인하는 작업이 핵심
- = 중복 방지 및 원하는 값 포함되어 있는지 확인
- equals()와 hashCode() 구현이 매우 중요
HashSet | TreeSet | LinkedHashSet |
순서 전혀 필요 없는 데이터를 해시 테이블(hash table)에 저장 Set 중 가장 성능 좋음 |
저장된 데이터의 값에 따라 정렬되는 Set red-black이라는 트리(tree) 타입으로 값이 저장됨 HashSet보다 약간 성능 느림 |
연결된 목록 타입으로 구현된 해시 테이블에 데이터 저장 저장된 순서에 따라 값이 정렬됨 성능은 가장 나쁨 |
- 성능 차이 발생 이유 : 데이터 정렬
- red-black 트리 : 각 노드 색을 붉은색 or 검은색으로 구분해 데이터를 쉽고 빠르게 찾을 수 있는 구조의 이진(binary) 트리
HashSet 클래스
HashSet 상속 관계
java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractSet<E>
java.util.HashSet<E>
- ArrayList처럼 AbstractCollection 확장함
- But HashSet은 AbstractSet을 확장
HashSet이 구현한 인터페이스
인터페이스 | 용도 |
Serializable | 원격으로 객체 전송하거나, 파일 저장할 수 있음을 지정 |
Cloneable | Object 클래스의 clone() 메서드가 제대로 수행될 수 있음을 지정 = 복제 가능한 객체임을 의미 |
Iterable<E> | 객체가 "foreach" 문장 사용할 수 있음을 지정 |
Collection<E> | 여러 개의 객체를 하나의 객체에 담아 처리할 때의 메서드 지정 |
Set<E> | Set 데이터 처리하는 것과 관련된 메서드 지정 |
- Set은 순서 없기에 get(int index)나 indexOf(Object o) 같은 메서드 없음
HashSet 생성자
생성자 | 설명 |
HashSet() | 데이터를 저장할 수 있는 16개의 공간과 0.75의 로드 팩터(load factor)를 갖는 객체 생성 |
HashSet(Collection<? extends E> c) | 매개 변수로 받은 컬렉션 객체의 데이터를 HashSet에 담음 |
HashSet(int initialCapacity) | 매개 변수로 받은 개수만큼의 데이터 저장 공간과 0.75의 로드 팩터를 갖는 객체 생성 |
HashSet(int initialCapacity, float loadFactor) | 첫 매개 변수로 받은 개수만큼의 데이터 저장 공간과 두 번째 매개 변수로 받은 만큼의 로드 팩터를 갖는 객체 생성 |
load factor (로드 팩터)
로드 팩터 = (데이터의 개수) / (저장 공간)
- 만약 데이터의 개수 증가하여 로드 팩터보다 커지면, 저장 공간의 크기는 증가되고 해시 재정리 작업(rehash)을 해야함
- 데이터가 해시 재정리 작업에 들어가면, 내부에 갖고 있는 자료 구조를 다시 생성하는 단계 거쳐야함 ➡ 성능에 영향
- 로드 팩터라는 값이 클수록 공간은 넉넉해지나, 데이터를 찾는 시간은 증가함
- ➡ 초기 공간 개수와 로드 팩터는 데이터의 크기 고려하여 산정하는 게 좋음
- ➡ 초기 크기가 (데이터의 개수) / (로드 팩터) 보다 크면 데이터를 쉽게 찾기 위한 해시 재정리 작업 발생 x
- ➡ 대량의 데이터를 여기에 담아 처리할 때 초기 크기와 로드 팩터 값을 조절하며 가장 적당한 크기를 찾아야함
HashSet 주요 메서드
리턴 타입 | 메서드 이름 및 매개 변수 | 설명 |
boolean | add(E e) | 데이터 추가 |
void | clear() | 모든 데이터 삭제 |
Object | clone() | HashSet 객체 복제 But 담겨 있는 데이터는 복제 x |
boolean | contains(Object o) | 지정한 객체가 존재하는지 확인 |
boolean | isEmpty() | 데이터가 있는지 확인 |
Iterator<E> | iterator() | 데이터를 꺼내기 위한 Iterator 객체 리턴 |
boolean | remove(Object o) | 매개 변수로 넘어온 객체 삭제 |
int | size() | 데이터 개수 리턴 |
package d.collection;
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
public class SetSample {
public static void main(String[] args) {
SetSample sample = new SetSample();
String[] cars = new String[] {
"Tico", "Sonata", "BMW", "Benz",
"Lexus", "Mustang", "Grandeure",
"The Beetle", "Mini Cooper", "i30",
"BMW", "Lexus", "Carnibal", "SM5",
"SM7", "SM3", "Tico"
};
System.out.println(sample.getCarKinds(cars));
}
//예제1
public int getCarKinds(String[] cars) {
//null인 배열을 매개 변수로 받으면 NullPointerException 발생
if(cars == null) return 0;
if(cars.length == 1) return 1;
Set<String> carSet = new HashSet<String>();
for(String car : cars) {
carSet.add(car);
}
return carSet.size();
}
//결과
//14
//예제2
public void printCarSet2(Set<String> carSet) {
Iterator<String> iterator = carSet.iterator();
while(iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
}
}
contains() | remove() |
HashSet에 해당 객체 존재하는지 확인 | HashSet에서 해당 객체 삭제 |
Queue
- FIFO (First In First Out)
- ex) 사용자들의 요청을 들어온 순서대로 처리할 때 사용
Deque (Double Ended Queue) [deck]
- Queue 인터페이스 확장함 = Queue 기능 전부 포함
- But 맨 앞 or 맨 뒤의 값을 넣거나 빼는 작업 수행 시 용이함
배열과 같은 ArrayList & Vector | LinkedList |
각 위치 정해져 있고, 그 위치로 데이터 찾음 맨 앞의 값 삭제 시 그 뒤에 있는 값들은 하나씩 앞으로 위치를 이동해야 제대로 된 위치 값 가지게 됨 |
배열의 중간에 있는 데이터가 지속적으로 삭제 및 추가될 경우 LinkedList가 배열보다 메모리 공간 측면에서 훨씬 유리 중간의 데이터 삭제 시, 지운 데이터의 앞과 뒤에 있는 데이터를 연결하면 됨(위치 맞추기 위해 값 이동할 필요 x) |
LinkedList
- List 인터페이스 + Queue 인터페이스 + Deque 인터페이스 구현
- ➡ LinkedList 자체가 List이면서 Queue, Deque도 됨
LinkedList 클래스가 구현한 인터페이스
인터페이스 | 용도 |
Serializable | 원격으로 객체 전송하거나 파일에 저장할 수 있음을 지정 |
Cloneable | Object 클래스의 clone() 메서드가 제대로 수행될 수 있음을 지정 = 복제 가능한 객체임을 의미 |
Iterable<E> | 객체가 "foreach" 문장 사용할 수 있음을 지정 |
Collection<E> | 여러 개의 객체를 하나의 객체에 담아 처리할 때의 메서드 지정 |
Deque<E> | 맨 앞과 맨 뒤의 값을 용이하게 처리하는 큐 관련 메서드 지정 |
List<E> | 목록형 데이터를 처리하는 것과 관련된 메서드 지정 |
Queue<E> | 큐를 처리하는 것과 관련된 메서드 지정 |
LinkedList의 생성자
생성자 | 설명 |
LinkedList() | 비어있는 LinkedList 객체 생성 |
LinkedList(Collection<? extends E> c) | 매개 변수로 받은 컬렉션 객체의 데이터를 LinkedList에 담음 |
LinkedList의 주요 메서드
리턴 타입 | 메서드 이름 및 매개 변수 | 설명 |
void | addFirst(Object) | LinkedList 객체의 가장 앞에 데이터 추가 |
boolean | offerFirst(Object) | |
void | push(Object) | |
boolean | add(Object) | LinkedList 객체의 가장 뒤에 데이터 추가 |
void | addLast(Object) | |
boolean | offer(Object) | |
boolean | offerLast(Object) | |
void | add(int, Object) | LinkedList 객체의 특정 위치에 데이터 추가 |
Object | set(int, Object) | LinkedList 객체의 특정 위치에 있는 데이터 수정 후, 기존에 있던 데이터 리턴 |
boolean | addAll(Collection) | 매개 변수로 넘긴 컬렉션의 데이터 추가 |
boolean | addAll(int, Collection) | 매개 변수로 넘긴 컬렉션의 데이터를 지정된 위치에 추가 |
package d.collection;
import java.util.LinkedList;
public class QueueSample {
public static void main(String[] args) {
QueueSample sample = new QueueSample();
sample.checkLinkedList1();
}
public void checkLinkedList1() {
LinkedList<String> link = new LinkedList<String>();
link.add("A");
link.addFirst("B");
System.out.println(link); // [B, A]
link.offerFirst("C");
System.out.println(link); // [C, B, A]
link.addLast("D");
System.out.println(link); // [C, B, A, D]
link.offer("E");
System.out.println(link); // [C, B, A, D, E]
link.offerLast("F");
System.out.println(link); // [C, B, A, D, E, F]
link.push("G");
System.out.println(link); // [G, C, B, A, D, E, F]
link.add(0, "H");
System.out.println(link); // [H, G, C, B, A, D, E, F]
System.out.println("Ex = " + link.set(0, "I")); // EX = H
System.out.println(link); // [I, G, C, B, A, D, E, F]
}
}
LinkedList 클래스에서 특정 위치의 데이터 꺼내는 메서드
리턴 타입 | 메서드 이름 및 매개 변수 | 설명 |
Object | getFirst() | LinkedList 객체의 맨 앞에 있는 데이터 리턴 |
Object | peekFirst() | |
Object | peek() | |
Object | element() | |
Object | getLast() | LinkedList 객체의 맨 뒤에 있는 데이터 리턴 |
Object | peekLast() | |
Object | get(int) | LinkedList 객체의 지정한 위치에 있는 데이터 리턴 |
LinkedList에 어떤 객체가 포함되어 있는지 확인하는 메서드
리턴 타입 | 메서드 이름 및 매개 변수 | 설명 |
boolean | contains(Object) | 매개 변수로 넘긴 데이터가 있을 때 true 리턴 |
int | indexOf(Object) | 매개 변수로 넘긴 데이터의 위치를 앞에서부터 검색하여 리턴, 없을 경우 -1 리턴 |
int | lastIndexOf(Object) | 매개 변수로 넘긴 데이터의 위치를 끝에서부터 검색하여 리턴, 없을 경우 -1 리턴 |
LinkedList 데이터 삭제 메서드
리턴 타입 | 메서드 이름 및 매개 변수 | 설명 |
Object | remove() | LinkedList 객체의 가장 앞에 있는 데이터 삭제 후 리턴 |
Object | removeFirst() | |
Object | poll() | |
Object | pollFirst() | |
Object | pop() | |
Object | pollLast() | LinkedList 객체의 가장 끝에 있는 데이터 삭제 후 리턴 |
Object | removeLast() | |
Object | remove(int) | 매개 변수에 지정된 위치에 있는 데이터 삭제 후 리턴 |
boolean | remove(Object) | 매개 변수로 넘겨진 객체와 동일한 데이터 중 앞에서부터 가장 처음 발견된 데이터 삭제 |
boolean | removeFirstOccurrence(Object) | |
boolean | removeLastOccurrence(Object) | 매개 변수로 넘겨진 객체와 동일한 데이터 중 끝에서부터 가장 처음 발견된 데이터 삭제 |
LinkedList 기타 메서드
size() | clear() | clone() | toArray() |
크기 확인 | 데이터 삭제 | 데이터 복제 | 배열로 만듦 |
LinkedList 객체를 하나씩 검색하기 위한 Iterator 객체
리턴 타입 | 메서드 이름 및 매개 변수 | 설명 |
ListIterator | listIterator(int) | 매개 변수에 지정된 위치부터의 데이터 검색하기 위한 ListIterator 객체 리턴 다음 데이터만 검색(next())할 수 있는 Iterator 인터페이스의 단점 보완 이전 데이터도 검색 가능(previous()) |
Iterator | descendingIterator() | LinkedList 데이터를 끝에서부터 검색하기 위한 Iterator 객체 리턴 |
정리
Collection | ||
List | Queue | Set |
목록 처리용 [장점] 배열과 유사 (But 배열은 객체 생성 시 크기를 지정해야 하는 단점 있음) List는 크기 커질 수 있음 배열처럼 데이터의 순서 중요할 때 사용 중복되는 데이터 존재 가능 [단점] 0번째 데이터 삭제 시, 그 다음 데이터부터 끝 데이터까지 위치값 바꿔야함 |
FIFO 가장 앞에 온 요청 뿐만 아니라, 가장 마지막에 온 요청도 빨리 찾을 수 있는 구조 웹 서버나 WAS 등처럼 사용자의 요청 처리하는 서버에서 사용 |
목록 처리 시 순서 중요하지 않고, 어떤 데이터가 있는지만 확인하고 싶을 때 유용함 중복되는 데이터 허용 x (동일 데이터 무시) 데이터로 검색 가능 (List에서 데이터 검색 시 0부터 하나씩 찾아야하지만 Set은 보다 빠르게 데이터 검색 가능) |
'Backend > Java' 카테고리의 다른 글
[자바의 신] 25장 (ongoing) (0) | 2022.08.18 |
---|---|
[자바의 신] 24장 (0) | 2022.08.09 |
[자바의 신] 22장 (0) | 2022.08.09 |
[자바의 신] 21장 (0) | 2022.08.09 |
[자바의 신] 20장 (0) | 2022.07.26 |
댓글