IT/Java

[Java] Set Collection

Huitopia 2024. 3. 27. 21:13
728x90

Set Collection

  • List Collection은 저장 순서를 유지하지만, Set Collection은 요소의 저장 순서를 유지하지 않는다.
  • 저장할 때와 값을 찾을 때 순서가 다를 수 있다.
  • 같은 요소의 중복 저장이 불가능하며, 하나의 null만 저장 가능하다.
  • 인덱스로 관리하지 않기 때문에 인덱스를 매개값으로 갖는 메소드는 없다.

 

Set Method

 

Set (Java SE 21 & JDK 21)

Type Parameters: E - the type of elements maintained by this set All Superinterfaces: Collection , Iterable All Known Subinterfaces: EventSet, NavigableSet , SequencedSet , SortedSet All Known Implementing Classes: AbstractSet, ConcurrentHashMap.KeySetView

docs.oracle.com

 

공통적으로 사용 가능한 Set Method

기능 메소드 설명
객체 추가 boolean add(E e) 주어진 객체를 성공적으로 저장하면 true 리턴하고 중복 객체면 false 리턴
객체 검색 boolean contains(Object o) 주어진 객체가 저장되어 있으면 true 아니면 false 리턴
isEmpty() 컬렉션이 비어있으면 true 아니면 flase
Iterator<E> iterator() 저장된 객체를 한 번씩 가져오는 반복자 리턴
int size() 저장되어 있는 전체 객체 수 리턴
객체 삭제 void clear() 저장된 모든 객체 삭제
boolean remove(Object o) 주어진 객체 삭제

 

1. HashSet<E>

  • HashSet Class는 내부적으로 HashMap Instance를 이용하여 요소를 저장한다.
  • Set Interface를 구현하므로, 요소를 순서에 상관 없이 저장하고 중복된 값(동등 객체)은 저장하지 않는다.

 

1-1. HashSet의 요소 파악 과정

  1. 해당 요소의 hashCode() 메소드 호출 후 반환된 hash값(다른 값이면 저장)으로 검색할 범위 결정
  2. 같은 hash 값이면 해당 범위 내의 요소들을 equals() 메소드로 비교
  3. equals() 메소드의 리턴 값이 true면 동등 객체로 저장 안함
  4. false면 다른 객체이므로 저장함

같은 문자열을 갖는 String 객체는 hashCode()의 리턴값이 같고 equals의 리턴값이 true이기 때문에 동등 객체로 간주한다.

// HashSet Collection 생성
Set<T> set = new HashSet<T>();

 

1-2. hashCode(), eqauls() 재정의

  • new instance로 객체를 생성했을 경우 값이 같더라도 hashCode가 다르기 때문에 다른 객체라 판단한다.
  • 값이 중복되지 않게 하기 위해서는 두 객체를 같도록 해야하는데 그럴때 hashCode(), equals()를 재정의 한다.
  • equals()를 재정의한 클래스에는 hashCode()도 반드시 재정의한다.

예제 코드

더보기
package ch15.sec03.exam02;
import java.util.Objects;
public class Member {
    public String name;
    public int age;
    
    public Member(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // name, age 같으면 true return
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Member member = (Member) o;
        return age == member.age && Objects.equals(name, member.name);
    }
    // name, age 같으면 동일한 hashCode return
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
package ch15.sec03.exam02;

import java.util.HashSet;
import java.util.Set;

public class HashSetExample {
    public static void main(String[] args) {
        // HashSet 컬렉션 생성
        Set<Member> set = new HashSet<>();
        // Member 에 객체 저장
        /* 인스턴스는 다르지만 동등 객체이므로 객체 1개만 저장 (equals, hashSet method 재정의함)*/
        set.add(new Member("성이름", 30));
        set.add(new Member("성이름", 30));
        // 저장된 객체 수 출력
        System.out.println("set.size() = " + set.size()); // 1
    }
}

2. TreeSet<E>

데이터가 정렬된 상태로 저장된는 이진 검색 트리(binary search tree)의 형태로 요소를 저장한다.

더보기
  • 이진 트리(binary tree): 여러 개의 노드(node)가 트리 형태로 연결된 구조
  • 루트 노드(root node): 루트 노드라고 불리는 하나의 노드에서 시작해 각 노드에 최대 2개의 노드를 연결할 수 있는 구조
  • 레드-블랙 트리 : 부모 노드보다 작은 값을 가지는 노드는 왼쪽 자식으로, 큰 값을 가지는 노드는 오른쪽 자식으로 배치하여 데이터의 추가나 삭제 시 트리가 한쪽으로 치우쳐지지 않도록 균형을 맞추어준다.
  • HashSet 보다 데이터의 추가와 삭제는 시간이 더 걸리지만(비교 횟수 증가) 검색과 정렬에 유리하다.
  • Set Interface를 구현하므로, 요소를 순서에 상관 없이 저장하고 중복된 값(동등 객체)은 저장하지 않는다.
  • 순서에 상관 없이 저장하지만 TressSet Instance에 저장되면 자동으로 정렬된다.
  • 이진 검색 트리 형태로 데이터를 저장하기에 기본적으로 nature ordering을 지원하며, 생성자의 매개변수로 Comparator 객체를 입력하여 정렬 방법을 임의로 지정 가능하다.
// TreeSet생성
TreeSet<Integer> set1 = new TreeSet<Integer>();
// new에서 type parameter 생략 가능
TreeSet<Integer> set2 = new TreeSet<>();
// set1의 모든 값을 가진 TreeSet 생성
TreeSet<Integer> set3 = new TreeSet<Integer>(set1);
// 초기값 지정
TreeSet<Integer> set4 = new TreeSet<Integer>(Arrays.asList(1,2,3));

3. LinkedHashSet

HashSet과는 다르게 저장된 순서에 따라 순서가 결정된다.

 

 

 

 

728x90