[Java] Set 컬렉션 - HashSet, TreeSet

Bam·2024년 3월 14일
0

Java

목록 보기
65/98
post-thumbnail

이번에 소개드릴 컬렉션은 순서가 없고 중복을 허용하지 않는 Set 인터페이스를 상속한 클래스입니다. 마찬가지로 기본적인 메소드들은 지난 포스트에서 소개드렸으니 여기서는 클래스에 대한 설명과 기본적인 사용법에 대해서만 다룹니다.


HashSet

HashSet은 저장 순서를 유지하지 않는 컬렉션입니다.

HashSet<E> 변수명 = new HashSet<E>();	//지정된 타입 E 객체만 저장 가능
HashSet 변수명 = new HashSet();	//모든 타입의 객체를 저장 가능

HashSet에서 사용가능한 메소드는 다음과 같습니다.

메소드설명
boolean add(Object o)Set에 객체 저장
boolean addAll(Collection c)Set에 컬렉션 c의 모든 객체 저장
void clear()컬렉션의 모든 객체 삭제
Object clone()HashSet을 복제하고 반환
boolean conatins(Object o)지정된 객체를 Set이 포함하고 있는지 여부를 반환
boolean containsAll(Collection c)컬렉션 c의 모든 객체들을 포함하고 있는지 여부를 반환
boolean isEmpty()HashSet이 비었는지를 반환
Iterator iterator()반복자를 반환
boolean remove(Object o)객체 o를 찾아서 삭제
boolean removeAll(Collection c)컬렉션 c의 모든 객체를 찾아서 삭제
boolean retainAll(Collection c)컬렉션 c의 객체들만 남기고 나머지는 삭제
int size()HashSet의 크기 반환
Object[] toArray()HashSet의 객체들을 객체 배열로 반환
Object[] toArray(Object[] arr)HashSet의 객체들을 arr 배열에 반환

주로 사용되는 메소드들만 소개드렸습니다. 전체 내용은 공식 문서를 참조해주세요.

중복을 허용하지 않기 때문에 요소를 추가하는 연산에서 hashCode()equals()를 통해 동일 객체인지 판단을 하고 요소를 추가하게 됩니다. 그렇기 때문에 문자열의 경우에는 같은 문자열을 가진다면 동일 객체로 취급됩니다.

다음 코드는 HashSet으로 삽입, 삭제, 검색 연산을 수행하는 코드입니다.

주의해서 봐야할 것은 검색인데요. Set은 순서가 없기 때문에 인덱스로 검색을 수행하는 indexOf()와 같은 검색 메소드가 존재하지 않습니다. 그래서 향상된 for를 통해 객체를 하나씩 가져와서 비교 후 찾는 방법을 사용하게 됩니다.

public class Main {
    public static void main(String[] args) {
        HashSet<String> hs = new HashSet<String>();

        hs.add("apple");	//요소 삽입
        hs.add("banana");
        hs.add("apple");	//중복요소는 저장하지 않음!!!
        hs.add("pineapple");
        System.out.println("HashSet의 크기: " + hs.size());

        for (String value: hs) {	//향상된 for문을 이용한 요소 검색
            if (value.equals("pineapple")) {
                System.out.println("pineapple이 컬렉션 내부에 있음");
            }
        }

        hs.remove("pineapple");	//pineapple 삭제
        System.out.println("HashSet의 크기: " + hs.size());
    }
}

LinkedHashSet

HashSet은 순서가 없기 때문에 저장한 순서와 실제로 저장된 순서가 다른 경우가 발생합니다.

public class Main {
    public static void main(String[] args) {
        HashSet<String> hs = new HashSet<String>();

        hs.add("apple");
        hs.add("banana");
        hs.add("pineapple");

        System.out.println(hs);
    }
}

만약 저장한 순서를 유지하고 싶다면 LinkedHashSet을 사용하면 됩니다.

public class Main {
    public static void main(String[] args) {
        LinkedHashSet<String> hs = new LinkedHashSet<String>();

        hs.add("apple");
        hs.add("banana");
        hs.add("pineapple");

        System.out.println(hs);
    }
}

기본적인 사용법은 HashSet과 동일합니다. 전체 내용은 공식 문서에서 확인하실 수 있습니다.


TreeSet

TreeSet이진 검색 트리 자료구조를 이용한 Set 컬렉션입니다. 이진 검색 트리는 정렬과 검색에서 아주 뛰어난 성능을 보여주는 자료구조입니다.

트리에 대한 기본 개념은 해당 포스트를 참조해주세요.

이진 검색 트리를 요약하자면 다음과 같습니다.

  • 각 노드는 최대 2개의 자식 노드를 갖는다.
  • 왼쪽 자식 노드 값은 부모 노드의 값보다 작고, 오른쪽 자식 노드 값은 부모 노드의 값보다 크다.
  • 순차가 없어서 노드 삽입 삭제 연산에 시간이 소요된다.
  • 검색과 정렬에서 효율이 높다.

더 정확하게는 이진 검색 트리의 성능을 끌어올린 레드-블랙 트리를 구현해서 사용하고 있습니다. 역시 Set을 구현했기 때문에 중복이 없고 순서도 없는 컬렉션이기도 합니다.

TreeSet에서 사용되는 메소드들은 다음과 같습니다.

메소드설명
boolean add(Object o)TreeSet에 객체 o 저장
boolean addAll(Collection c)TreeSet에 컬렉션 c의 객체들 모두 저장
void clear()저장된 모든 객체를 삭제
Object clone()TreeSet을 복제하고 반환
Comparator comparator()Comporator 반환
boolean contains(Object o)지정된 객체 o가 TreeSet에 있는지 여부를 반환
boolean conatainsAll(Collection c)컬렉션 c의 객체들이 TreeSet에 있는지 여부를 반환
Object first()첫 번째 객체를 반환
SortedSet headSet(Object o)객체 o보다 작은 값의 객체 반환
boolean isEmpty()TreeSet이 비었는지 확인
Iterator iterator()반복자 반환
Object last()마지막 객체를 반환
boolean remove(Object o)객체 o를 찾아서 삭제
boolean retainAll(Collection c)컬렉션 c의 객체와 일치하는 객체만 남기고 나머지 삭제
int size()TreeSet 크기 반환
SortedSet subSet(Object from, Object to)from과 to 객체 사이의 요소들을 반환
SortedSet tailSet(Object o)객체 o보다 큰 객체들을 반환
Object[] toArray()저장된 객체를 배열로 반환
Object[] toArray(Object[] arr)저장된 객체를 배열 arr에 반환

Comporator는 정렬에 사용되는 기준을 제공하기 위한 비교자입니다. 이 역시 추후에 더 자세히 다룰예정입니다.

마찬가지로 전체적인 내용은 공식 문서를 참조해주세요.

public class Main {
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<String>();

        ts.add("apple");
        ts.add("banana");
        ts.add("pineapple");
        ts.add("kiwi");
        System.out.println("TreeSet의 크기: " + ts.size());
        
        for (String value: ts) {
            if (value.equals("pineapple")) {
                System.out.println("TreeSet에 pineapple이 존재합니다.");
            }
        }
    }
}

0개의 댓글