본문 바로가기
Backend/Java

[자바의 신] 23장

by unknownomad 2022. 8. 9.

23장 - 자바랭 다음으로 많이 쓰는 애들은 컬렉션 ― Part2 (Set과 Queue)


Set

  • 데이터 중복 허용 x (순서 x) ➡ 데이터가 같은지 확인하는 작업이 핵심
  • = 중복 방지 및 원하는 값 포함되어 있는지 확인
  • equals()와 hashCode() 구현이 매우 중요

Set

 

HashSet TreeSet LinkedHashSet
순서 전혀 필요 없는 데이터를 해시 테이블(hash table)에 저장
Set 중 가장 성능 좋음
저장된 데이터의 값에 따라 정렬되는 Set
red-black이라는 트리(tree) 타입으로 값이 저장됨
HashSet보다 약간 성능 느림
연결된 목록 타입으로 구현된 해시 테이블에 데이터 저장
저장된 순서에 따라 값이 정렬됨
성능은 가장 나쁨
  • 성능 차이 발생 이유 : 데이터 정렬
  • red-black 트리 : 각 노드 색을 붉은색 or 검은색으로 구분해 데이터를 쉽고 빠르게 찾을 수 있는 구조의 이진(binary) 트리

https://ko.wikipedia.org/wiki/%EB%A0%88%EB%93%9C-%EB%B8%94%EB%9E%99_%ED%8A%B8%EB%A6%AC


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

  • 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

댓글