관리 메뉴

나만을 위한 블로그

[DS] Set이란? HashSet, TreeSet, LinkedHashSet 사용법 정리 본문

개인 공부/Data structure

[DS] Set이란? HashSet, TreeSet, LinkedHashSet 사용법 정리

참깨빵위에참깨빵 2021. 11. 6. 21:10
728x90
반응형

Set의 사전적 정의는 아래와 같다.

 

(두 개 이상의 물건으로 된) 한 조(組)

 

최소한 둘 이상의 것이 하나로 뭉쳤단 뜻이다. 위키백과에선 Set을 아래와 같이 말한다.

 

https://en.wikipedia.org/wiki/Set_(abstract_data_type) 

 

Set (abstract data type) - Wikipedia

In computer science, a set is an abstract data type that can store unique values, without any particular order. It is a computer implementation of the mathematical concept of a finite set. Unlike most other collection types, rather than retrieving a specif

en.wikipedia.org

Set은 특별한 순서 없이 고유한 값을 저장할 수 있는 추상 자료구조다. 유한 집합의 수학적 개념을 컴퓨터로 구현한 것이다. 대부분의 다른 컬렉션 유형과 달리 집합에서 특정 요소를 검색하는 대신 일반적으로 집합의 구성원 자격에 대한 값을 테스트한다. 일부 집합 자료구조는 구성된 후 변경되지 않는 고정 집합 또는 고정 집합을 위해 설계됐다. 정적 집합은 주어진 값이 집합에 있는지 확인하거나, 랜덤하게 값을 열거하는 것과 같은 요소에 대한 쿼리 작업만 허용한다. 동적 또는 변경 가능한 집합(mutable set)이라 하는 다른 변형을 사용하면 집합에서 요소를 삽입, 삭제할 수도 있다. 다중 집합(multiset)은 요소가 여러 번 나타낼 수 있는 특별한 집합이다

 

고유한 값을 저장한다면 중복되는 값은 집어넣을 수 없단 것 같다.

Set에 대해 설명하는 다른 글을 찾아봤다.

 

https://www.codejava.net/java-core/collections/java-set-collection-tutorial-and-examples

 

Java Set Collection Tutorial and Examples

 

www.codejava.net

Set은 중복 요소를 허용하지 않는 컬렉션 유형이다. 즉 요소는 Set에서 한 번만 존재할 수 있다. 수학에서 Set 추상화를 모델링한다. Set의 특징은 아래와 같다.
- 중복 요소를 허용하지 않는다
- 요소는 순서대로 저장되지 않는다. 즉, Set의 요소를 반복할 때 어떤 순서로든 정렬된 요소를 기대할 수 없다.

Set은 아래 경우에 사용한다.
- 중복 또는 고유한 요소 없이 요소를 뚜렷하게 저장할 때
- 요소의 순서를 신경 쓰지 않을 때
예를 들어 Set을 써서 고유한 정수를 저장하거나 카드 게임에서 카드를 무작위로 저장할 수 있다

 

https://blog.naver.com/PostView.nhn?blogId=heartflow89&logNo=220994601249&parentCategoryNo=&categoryNo=28&viewDate=&isShowPopularPosts=false&from=postView 

 

[JAVA/자바] Set - HashSet, TreeSet, LinkedHashSet

이전에 알아본 List(ArrayList, Vector, LinkedList) 컬렉션과는 다른 특징들을 갖는 Set 컬렉션에 ...

blog.naver.com

Set은 List와 다르게 객체(데이터)를 중복 저장할 수 없다. 또한 저장된 객체(데이터)를 인덱스로 관리하지 않기 때문에 저장 순서가 보관되지 않는다. 수학의 집합과 비슷하다. Set 컬렉션을 구현한 대표적인 클래스는 HashSet, TreeSet, LinkedHashSet 등이 있다. Set 컬렉션을 구현하는 클래스들이 공통적으로 쓰는 주요 메서드는 add, iterator, size, remove, clear 등이 있다. Set은 인덱스로 객체(데이터)를 관리하지 않기 때문에 데이터를 검색하려면 iterator()로 iterator(반복자)를 만들고 데이터를 가져와야 한다.

 

Set을 구현한 자바 소스를 찾지 못해서 자바에서 제공하는 Set 인터페이스를 사용해 HashSet, TreeSet, LinkedHashSet의 사용법을 정리하는 것으로 대신한다. 사용하는 메서드는 위에서 말한 add, addAll, iterator, size, remove, clear만 사용한다.

먼저 HashSet 사용법은 아래와 같다.

 

import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetPrac {
    public static void main(String[] args) {
        Set<Object> set = new HashSet<>();
        Set<Object> set2 = new HashSet<>(10);
        // loadFactor : 부하율. 용량이 자동으로 증가하기 전 HashSet이 얼마나 가득차게 허용하는지를 규정한다. 기본값은 75%
        Set<Object> set3 = new HashSet<>(10, 0.5f);
        Set<Object> set4 = new HashSet<>(Arrays.asList(100, 200, 300));

        /* add() 사용 */
        set.add(1);
        set.add(2);
        set.add(3);
        System.out.println(set);

        set2.add(4);
        set2.add(5);
        set2.add(6);
        /* addAll() 사용 : 매개변수로 받은 Set을 메서드 호출객체인 Set 안에 넣는다 */
        set.addAll(set2);
        System.out.println(set);

        /* iterator() 사용 - for문으로 iterator 활용 */
        Iterator<Object> iterator = set.iterator();
        for (int i = 0; i < set.size(); i++) {
            System.out.println("for iterator : " + iterator.next());
        }

        /* while문으로 iterator 활용 */
        while (iterator.hasNext()) {
            System.out.println("while iterator : " + iterator.next());
        }

        /* size() 사용 */
        System.out.println("set.size() : " + set.size());

        /* remove() 사용 */
        set.remove(6);
        System.out.println("set.remove(1) 후 : " + set);

        /* clear() 사용 */
        set.clear();
        System.out.println("set.clear() 후 : " + set);
    }
}

 

Set의 선언은 저렇게 다양하게 할 수 있는데, 0.5f를 넣어서 선언한 경우는 Set의 초기용량을 지정한 것이다.

왜냐면 List처럼 Set도 값이 추가되면 저장공간을 늘리는데 한 칸씩 늘리는 게 아니라 2배로 저장용량을 늘리기 때문이라고 한다. 출처는 아래다.

https://coding-factory.tistory.com/554

 

[Java] 자바 HashSet 사용법 & 예제 총정리

HashSet이란? HashSet은 Set 인터페이스의 구현 클래스입니다. 그렇기에 Set의 성질을 그대로 상속받습니다. Set은 객체를 중복해서 저장할 수 없고 하나의 null 값만 저장할 수 있습니다. 또한 저장 순

coding-factory.tistory.com

 

또한 인덱스가 없기 때문에 당연히 get()도 없어서 반복문과 iterator()를 활용해 Set 안의 값들을 가져와야 한다.

아래 링크는 Set에 대해 설명하는 자바 독스 페이지다.

https://docs.oracle.com/javase/8/docs/api/java/util/Set.html

 

Set (Java Platform SE 8 )

A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction. The Set inter

docs.oracle.com

 


 

 

다음은 TreeSet이다. 위키백과엔 설명이 너무 적게 되어 있어서 다른 사람들은 TreeSet을 어떻게 말하는지 찾아봤다.

 

https://www.tutorialspoint.com/java/java_treeset_class.htm

 

Java - The TreeSet Class

Java - The TreeSet Class TreeSet provides an implementation of the Set interface that uses a tree for storage. Objects are stored in a sorted and ascending order. Access and retrieval times are quite fast, which makes TreeSet an excellent choice when stori

www.tutorialspoint.com

TreeSet은 저장을 위해 트리를 사용하는 Set 인터페이스의 구현을 제공한다. 객체는 정렬된 오름차순으로 저장된다. 접근, 검색 시간이 매우 빠르기 때문에 신속하게 찾아야 하는 정렬된 정보를 대량 저장할 때 TreeSet이 좋다.

 

https://hbase.tistory.com/130

 

[Java] TreeSet 사용법 및 예제

TreeSet TreeSet 클래스 역시 Set 인터페이스를 구현한 클래스다. Set 인터페이스를 구현했기 때문에 데이터에 대한 중복 저장을 하지 않으며, 저장된 순서를 유지하지 않는다. 해시코드를 이용해서

hbase.tistory.com

TreeSet 클래스 역시 Set 인터페이스를 구현한 클래스다. Set 인터페이스를 구현했기 때문에 데이터를 중복해 저장하지 않고, 저장 순서를 유지하지 않는다.
해시코드를 써서 내부 해시 테이블에 데이터를 저장하는 HashSet과 달리 TreeSet은 내부에 데이터 저장을 위한 Red/Black Tree 자료구조를 갖고 있다. RB 트리는 이진 탐색 트리(Binary Search Tree)의 일종으로 저장된 값들이 트리 전체에 골고루 저장되게 해서 비정상적으로 트리 높이가 높아지는 현상이 없게 만든 균형 트리(Balanced Tree)다. 내부에 RB 트리를 써서 값을 저장하기 때문에 현재까지 저장된 값 중 최소값 혹은 최대값을 출력할 수 있고 특정 값보다 큰 값을 빠르게 찾아낼 수 있다. 삽입과 삭제 연산에서 RB 트리의 밸런스를 맞추는 동작이 호출되어 약간의 성능 손해를 보면서 탐색에서의 이점을 가져간 자료구조다

 

https://devlog-wjdrbs96.tistory.com/108

 

[Java] TreeSet 이란?

TreeSet은 이름 그대로 Tree구조를 이루고 중복을 허용하지 않는다는 것은 알 수 있다. 그래도 자세히 한번 알아보자. TreeSet 이란? Set인터페이스를 구현한 클래스이다 (중복허용 x , 순서유지 x , 정

devlog-wjdrbs96.tistory.com

TreeSet이란?
- Set 인터페이스를 구현한 클래스(중복x, 순서x, 정렬저장o)
- 이진 트리(Binary Tree) 구조
- 데이터 추가, 삭제 시마다 이진 트리 구조를 유지해야 해서 시간이 걸림(검색에 유리)

 

Red-Black Tree와 이진 트리라는 키워드가 나오는데, 이것은 나중에 알아보고 TreeSet의 사용법을 예제 코드로 확인해본다. 마찬가지로 add, addAll, iterator, size, remove, clear()를 위주로 확인한다.

 

import java.util.Arrays;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetPrac {
    public static void main(String[] args) {
        Set<Object> set = new TreeSet<>();
        Set<Object> set2 = new TreeSet<>(Arrays.asList(7, 8, 9));

        /* add() 사용 */
        set.add(3);
        set.add(1);
        set.add(2);
        System.out.println(set);    // [1, 2, 3]
        System.out.println(set2);   // [7, 8, 9]

        set2.add(4);
        set2.add(5);
        set2.add(6);
        /* addAll() 사용 */
        set.addAll(set2);
        System.out.println(set);    // [1, 2, 3, 4, 5, 6, 7, 8, 9]

        /* iterator() 사용 - for문으로 iterator 활용 */
        Iterator<Object> iterator = set.iterator();
        for (int i = 0; i < set.size(); i++) {
            System.out.println("for iterator : " + iterator.next());
        }

        System.out.println("================================");

        /* for-each문으로 iterator 활용 */
        for (Object o : set) {
            System.out.println("for-each iterator : " + o);
        }

        /* while문으로 iterator 활용 */
        Iterator<Object> iterator2 = set.iterator();
        while (iterator2.hasNext()) {
            System.out.println("while iterator : " + iterator2.next());
        }

        /* size() 사용 */
        System.out.println("set.size() : " + set.size());

        /* remove() 사용 */
        set.remove(1);
        System.out.println("set.remove(1) 후 : " + set);

        /* clear() 사용 */
        set.clear();
        System.out.println("set.clear() 후 : " + set);
    }
}

 

특이하게도 3, 1, 2 순으로 TreeSet에 추가했는데 출력해보면 1, 2, 3 순서대로 출력되는 걸 볼 수 있다.

이는 TreeSet이 기본적으로 오름차순으로 데이터를 정렬하는 특징이 있기 때문이다.

 


 

마지막으로 LinkedHashSet이다.

 

https://www.tutorialspoint.com/java/java_linkedhashset_class.htm

 

Java - The LinkedHashSet Class

Java - The LinkedHashSet Class This class extends HashSet, but adds no members of its own. LinkedHashSet maintains a linked list of the entries in the set, in the order in which they were inserted. This allows insertion-order iteration over the set. That i

www.tutorialspoint.com

이 클래스는 HashSet을 확장하지만 자체 멤버를 추가하지 않는다. LinkedHashSet은 삽입된 순서대로 집합에 있는 항목의 연결 목록을 유지관리한다. 이것은 Set에 대한 삽입 순서 반복을 허용한다. 즉, 반복자를 써서 LinkedHashSet을 순환할 때 요소는 삽입된 순서대로 반환된다. 그 다음 해시 코드는 키와 관련된 데이터가 저장되는 인덱스로 사용된다. 키를 해시코드로 바꾸는 작업은 자동 수행된다.

 

LinkedHashSet은 괜찮아 보이는 글을 찾지 못해서 바로 예제 코드로 넘어간다.

 

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetPrac {
    public static void main(String[] args) {
        Set<Object> set = new LinkedHashSet<>();
        Set<Object> otherSet = new LinkedHashSet<>(set);
        Set<Object> set3 = new LinkedHashSet<>(Arrays.asList(4, 5, 6));

        /* add() 사용 */
        set.add(3);
        set.add(1);
        set.add(2);
        System.out.println(set);    // [3, 1, 2]
        System.out.println(set3);   // [4, 5, 6]

        /* addAll() 사용 */
        set.addAll(set3);
        System.out.println(set);

        /* iterator() 사용 - for문으로 iterator 활용 */
        Iterator<Object> iterator = set.iterator();
        for (int i = 0; i < set.size(); i++) {
            System.out.println("for iterator : " + iterator.next());
        }

        System.out.println("================================");

        /* for-each문으로 iterator 활용 */
        for (Object o : set) {
            System.out.println("for-each iterator : " + o);
        }

        /* while문으로 iterator 활용 */
        Iterator<Object> iterator2 = set.iterator();
        while (iterator2.hasNext()) {
            System.out.println("while iterator : " + iterator2.next());
        }

        /* size() 사용 */
        System.out.println("set.size() : " + set.size());

        /* remove() 사용 */
        set.remove(1);
        System.out.println("set.remove(1) 후 : " + set);

        /* clear() 사용 */
        set.clear();
        System.out.println("set.clear() 후 : " + set);
    }
}

 

LinkedHashSet은 TreeSet과 달리 출력 시 입력된 순서대로 데이터를 보여준다.

HashSet, TreeSet, LinkedHashSet을 표로 비교하면 아래와 같다.

 

이름 데이터 중복 여부 순서 보장 여부 기타
HashSet 데이터 중복 x 순서 보장 x -
TreeSet 오름차순으로 데이터 정렬
(1~9, a~z)
LinkedHashSet 입력된 순서대로 데이터 관리 -

 

 

 

참고한 사이트)

 

https://blog.naver.com/PostView.nhn?blogId=heartflow89&logNo=220994601249&parentCategoryNo=&categoryNo=28&viewDate=&isShowPopularPosts=false&from=postView 

 

[JAVA/자바] Set - HashSet, TreeSet, LinkedHashSet

이전에 알아본 List(ArrayList, Vector, LinkedList) 컬렉션과는 다른 특징들을 갖는 Set 컬렉션에 ...

blog.naver.com

 

https://velog.io/@gillog/HashSet

 

Set 컬렉션 - HashSet, TreeSet, LinkedHashSet

HashSet은 Set 인터페이스의 구현 클래스이다. Set 컬렉션은 객체를 중복해서 저장할 수 없고, 하나의 null만 저장 할 수 있다.또한 저장 순서가 유지되지 않는다. 만약 요소의 저장 순서를 유지해야

velog.io

 

반응형
Comments