[자바 무료 강의] Collection - Set - 코드라떼
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의Collection - Set최종수정일 2021-11-21
아이콘약 15분

노트 강의

자바의 강력한 도구인 Set에 대해 배우는 시간입니다. 구조와 원리에 대해서는 “Java로 배우는 자료구조” 코스에서 좀 더 깊게 이해를 하실 수 있습니다. 이 강의에서는 어떤 도구들이 있고 어떤 특징이 있는지, 어떻게 사용하는지에 대해서만 알아봅니다.


목차


  1. Set<E>

  2. HashSet<E>

  3. TreeSet<E>

  4. LinkedHashSet<E>

  5. [추가] 합집합, 교집합, 차집합, 여집합, 부분집합

1. Set<E>


Java의 Collection에는 집합(Set)이라는 자료구조가 있습니다. 집합처럼 중복되지 않는 원소들의 모음을 만들 수 있는 자료구조를 Set이라고 합니다.

set1 이러한 Set의 특징은 집합에 있는 동일한 원소를 저장하더라도 Set에는 중복된 원소가 존재하지 않는다는 점입니다.

set2

Set의 구조가 왜 필요할까요? 수학과 관련된 일이 아니면 써먹을 일이 없지 않을까요? 라고 생각할 수도 있습니다. 간단한 예시로 고민해 봅시다.

접속 날짜

접속 시간

아이디

2020-01-01

10:00

roka

2020-01-01

20:00

코드라떼

2020-01-02

13:00

roka

2020-01-02

13:30

코드라떼

2020-01-02

14:00

roka

2020-01-02

15:00

카페라떼

2020-01-02

18:00

카페라떼

해당 표는 특정 아이디가 어떤 서비스에 접속한 날짜와 시간이라고 가정합니다.


그리고 해당 표를 이용하여 우리는 두 가지 문제를 풀어야 한다고 가정합니다.

  • 2020-01-01 ~ 2020-01-02 까지 접속한 아이디의 수

  • 2020-01-01 ~ 2020-01-02 까지 접속한 아이디

이 문제를 어떻게 풀 수 있을까요?


혹시 눈으로 슥~ 보면서 풀고계시진 않으신가요?


이럴 때 Set구조를 이용하면 간단하게 풀 수 있습니다.


Set에는 크게 TreeSet, HashSet, LinkedHashSet이 있습니다.


우리는 각 Set과 관련된 클래스들을 살펴보며 장점과 단점은 무엇인지 그리고 어떤 특징이 있는지 살펴볼 예정입니다.


2. HashSet<E>


HashSet은 데이터 저장을 Hash Table을 이용하는 구조로 저장하는 Set입니다.


Set의 특징을 가지고 있으며, 동일한 원소를 저장하더라도 저장소에 중복된 값이 존재하지 않습니다.


HashSet은 HashTable 구조를 이용한 HashMap을 이용하여 만들어져 있습니다.

// HashSet의 생성자
public HashSet() {
    map = new HashMap<>();
}

public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size() / 0.75f) + 1, 16));
}

HashSet의 생성자를 보면 HashMap을 이용하여 Set 구조를 만드는 것을 확인할 수 있습니다.

// 더미 Object
public static final Object PRESENT = new Object();

// HashSet의 데이터 add 메서드
public boolean add(E e) {
    return map.put(e, PRESENT) == null;
}

Map의 특성 중 하나인 중복 key는 존재할 수 없다는 특징을 이용하여, key를 Set의 값으로, value에는 더미 Object를 저장 방식으로 데이터를 추가합니다.


즉, HashSet을 이해하려면 HashMap에 대해서 먼저 알아야 합니다.


특징

  • Hash Table 구조 기반이다.

  • HashMap을 이용하여 구현되므로, HashMap의 장점과 특징을 그대로 계승한다.

사용용도

  • index가 아닌 key를 이용하여 데이터 저장과 접근이 필요할 경우 사용한다.

  • 데이터의 크기가 어느 정도 예상되는 경우 사용한다.

  • 삽입 삭제가 빈번할 경우 사용한다.

HashSet의 생성

import java.util.HashSet;

HashSet<String> texts = new HashSet<>();

HashSet의 데이터 삽입

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("코드라떼");
set.add("codelatte");

HashSet.add(value) 메서드를 이용하여 데이터를 저장할 수 있습니다.


HashSet 값 포함 여부 확인

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("코드라떼");
set.add("codelatte");

boolean isExist = set.contains("codelatte");
// 있으면 true, 없으면 false

HashSet 값 삭제

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("코드라떼");
set.add("codelatte");
set.add("카페라떼");

// 데이터 삭제
set.remove("카페라떼");

HashSet 값 출력

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("1");
set.add("23");
set.add("2");
set.add("14");
set.add("2");
set.add("5");

for (String value : set) {
    System.out.println(value);
}

// "1", "23", "2", "14", "5"

HashMap을 이용하여 만들어졌으므로, 저장된 값은 정렬되어 있지 않습니다.


3. TreeSet<E>


TreeSet은 논리적인 Tree 구조로 데이터를 저장하는 Set입니다.


Set의 특징을 가지고 있으며, 동일한 원소를 저장하더라도 저장소에는 중복된 값이 존재하지 않습니다.

또한 TreeSet은 Tree 구조를 이용한 TreeMap을 이용하여 만들어져 있습니다.

// TreeSet의 생성자
public TreeSet() {
    this(new TreeMap<E, Object>());
}

TreeSet의 생성자를 보면 TreeMap을 이용하여 Set 구조를 만드는 것을 확인할 수 있습니다.

// 더미 Object
public static final Object PRESENT = new Object();

// TreeSet의 데이터 add 메서드
public boolean add(E e) {
    return m.put(e, PRESENT) == null;
}

Map의 특성 중 하나인 중복 key는 존재할 수 없다는 특징을 이용하여, key를 Set의 값으로, value에는 더미 Object를 저장 방식으로 데이터를 추가합니다.


즉, TreeSet을 이해하려면 TreeMap에 대해서 먼저 알아야 합니다.


특징

  • Tree 구조 기반이다.

  • TreeMap을 이용하여 구현되므로, TreeMap의 장점과 특징을 그대로 계승한다.

사용용도

  • 저장되는 데이터의 개수가 몇 개인지 예상되지 않는 경우 사용한다.

  • 삽입과 삭제가 빈번하지 않을 때 사용한다.

  • 정렬된 값이 필요할 때 사용한다.

TreeSet의 생성

import java.util.TreeSet;

TreeSet<String> texts = new TreeSet<>();

TreeSet의 데이터 삽입

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

TreeSet.add(value) 메서드를 이용하여 데이터를 저장할 수 있습니다.


TreeSet 값 포함 여부 확인

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

boolean isExist = set.contains("코드라떼");
// 있으면 true, 없으면 false

TreeSet 값 삭제

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

// 데이터 삭제
set.remove("코드라떼");

TreeSet 값 출력

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("1");
set.add("3");
set.add("2");
set.add("4");
set.add("2");
set.add("5");

for (String value : set) {
    System.out.println(value);
}

// "1", "2", "3", "4", "5"

TreeMap을 이용하여 만들어졌으므로, 저장된 값은 오름차순으로 정렬되어 출력할 수 있습니다.


4. LinkedHashSet<E>


LinkedHashSetHashSet을 상속하여 만들어진 클래스입니다.


그러므로 HashSet의 특징을 가지고 있습니다.

// LinkedHashSet은 HashSet을 상속 받는다
public LinkedHashSet<E> extends HashSet<E>// LinkedHashSet의 생성자
public LinkedHashSet() {
    super(16, .75f, true);
}

LinkedHashSet의 생성자를 보면 HashSet을 상속받은 것을 확인할 수 있습니다.


다만 주의할 점은 super 키워드를 사용하여 호출할 때, HashSetdefault 접근 제어 지시자의 생성자를 호출합니다.

// HashSet의 default 접근 제어 지시자 생성자
HashSet(int initialCapacity, float loadFactor, boolean dummy {
    map = new LinkedHashMap<>(initialCapacity, loadFactor)
}

HashSet에는 LinkedHashMap을 이용하는 코드가 작성되어있습니다.


즉 정리하면, HashSet 클래스에는 기본적으로는 HashMap을 이용하도록 구현되어 있으나 HashSet 클래스를 상속받아 구현할 때는, java.util 패키지 내에서 default 접근 제어 지시자로 작성된 HashSet 생성자를 super 키워드를 이용하여 호출 가능하기 때문에 LinkedHashMap으로 사용할 수 있도록 구현되어 있습니다.


특징

  • HashSet을 상속받아 구현되나, LinkedHashMap을 이용하며 LinkedHashMap의 특징을 그대로 계승한다.

사용용도

  • 값의 저장된 순서가 중요할 때 사용한다.

LinkedHashSet의 생성

import java.util.LinkedHashSet;

LinkedHashSet<String> texts = new LinkedHashSet<>();

LinkedHashSet의 데이터 삽입

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

LinkedHashSet.add(value) 메서드를 이용하여 데이터를 저장할 수 있습니다.


LinkedHashSet 값 포함 여부 확인

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

boolean isExist = set.contains("roka");
// 있으면 true, 없으면 false

LinkedHashSet 값 삭제

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");
set.add("카페라떼");

// 데이터 삭제
set.remove("카페라떼");

LinkedHashSet 값 출력

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("1");
set.add("23");
set.add("3");
set.add("14");
set.add("2");
set.add("5");

for (String value : set) {
    System.out.println(value);
}

// "1", "23", "3", "14", "2", "5"

LinkedHashMap을 이용하므로, 저장된 값은 저장된 순서대로 출력됩니다.


5. [추가] 합집합, 교집합, 차집합, 여집합, 부분집합


추가적으로 합집합, 교집합, 차집합, 여집합, 부분집합을 연산하거나 확인하고 싶을 때 보시면 됩니다.


지금 당장 필요하지 않다면 후 순위로 미뤄두시는 것이 낫습니다.


set example


세 개의 집합이 존재합니다.


A = {1, 2, 3, 4, 5}

B = {3, 4, 5, 6, 7}

C = {3, 4}


우리는 Java에서 이 세 개의 집합을 어떻게 표현하며 합집합, 교집합, 차집합, 여집합, 부분집합 여부를 어떻게 연산하는지 확인해볼 예정입니다.

// A 집합
List<String> set1 = Arrays.asList("1", "2", "3", "4", "5");
TreeSet<String> A = new TreeSet<>(set1);

// B 집합
List<String> set2 = Arrays.asList("3", "4", "5", "6", "7");
TreeSet<String> B = new TreeSet<>(set2);

// C 집합
List<String> set3 = Arrays.asList("3", "4");
TreeSet<String> C = new TreeSet<>(set3);

C 집합이 A 집합의 부분집합인지 확인 방법 (C ⊂ A)

boolean isContainAll = B.containsAll(C);
System.out.println("C ⊂ B ? "+isContainAll);

Set.containsAll(set) 메서드를 이용하여 부분집합 여부를 확인할 수 있습니다.

부분집합이면 true, 부분집합이 아니면 false를 반환합니다.


원소의 포함여부 확인 방법 (x ∈ B)

boolean isContain = B.contains("7");
System.out.println("7 ⊂ B ? "+ isContain);

Set.contains(value) 메서드를 이용하여 해당 집합에 원소가 포함되는지 확인할 수 있습니다.

원소가 포함되면 true, 원소가 포함되지 않으면 false를 반환합니다.


A 교집합 B 추출 방법 (A ∩ B)

TreeSet<String> cloneA = new TreeSet<>(set1);
boolean isModified = cloneA.retainAll(B);
System.out.println("A ∩ B ? "+cloneA);

Set.retainAll(collection) 메서드를 이용하여 교집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.retainAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 손실을 원하지 않는다면 원본을 복사해서 사용해야 합니다.


A 합집합 B 추출 방법 (A ∪ B)

TreeSet<String> cloneA = new TreeSet<>(set1);
boolean isModified = cloneA.addAll(B);
System.out.println("A ∪ B ? "+cloneA);

Set.addAll(collection) 메서드를 이용하여 합집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.addAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 변경을 원하지 않는다면 원본을 복사해서 사용해야 합니다.


A 차집합 B 추출 방법 (A - B)

TreeSet<String> cloneA = new TreeSet<>(set1);
boolean isModified = cloneA.removeAlll(B);
System.out.println("A - B ? "+cloneA);

Set.removeAll(collection) 메서드를 이용하여 차집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.removeAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 변경을 원하지 않는다면 원본을 복사해서 사용해야 합니다.

도전자 질문
아이콘upqnu(2022-06-13 17:18 작성됨)
실습도구에서 합집합, 교집합, 차집합은 구현에 문제가 없지만, 나머지 3개는 각각의 주석만 풀고 실행시켰을 때 에러가 나옵니다. (코드의 다른 부분을 수정하지 않았습니다.) 확인을 부탁드립니다.
아이콘코드라떼(2022-06-14 05:59 작성됨)
안녕하세요. 코드라떼입니다 :)

패키지가 import되지 않아서 발생한 문제로 import 구문을 추가한 코드를 업로드했습니다.

감사합니다 :)
아이콘넬준(2021-10-21 15:18 작성됨)
'LinkedHashSet값 출력'부분에서 마지막 결과 값 순서가

1 23 3 14 2 5 인건가요? 저장된 순서대로 출력되는거니까
아이콘코드라떼(2021-10-21 16:35 작성됨)
안녕하세요. 코드라떼입니다 :)

"1" "23" "3" "14" "2" "5"가 맞습니다.
뭐라 드릴 말씀이 없군요.. 감사합니다!

ps. 추가로 넬준님 메일로 프로모션 코드를 제공해드렸습니다.

확인 부탁드립니다. 감사합니다 :)
아이콘자바배움이(2021-07-09 13:13 작성됨)
추가노트 마지막 문단에 아래와 같이 써있는데, 오타가 있어요!

/*
Set.removeAll(collection) 메서드를 이용하여 합집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.addAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 변경을 원하지 않는다면 원본을 복사해서 사용해야 합니다.
*/

첫번째 줄 : 합집합 -> 차집합
마지막 줄 : Set.addAll(collection) -> Set.removeAll(collection)
아이콘코드라떼(2021-07-09 20:31 작성됨)
자바배움이님 감사합니다.^^ 수정했습니다.

ps.자바배움이 님이 꼼꼼하게 공부하시는 것에 감명 깊어 이후에 나올 코스를 무료로 수강하실 수 있도록 출시 후에 별도로 연락드리겠습니다.^^
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io
사업자등록번호 : 824-06-01921
통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호
파일
파일파일
Root
파일

Output
root$
Lesson List button
코스자바로 배우는 프로그래밍
hamburger button
강의Collection - Set최종수정일 2021-11-21
아이콘약 15분

노트 강의

자바의 강력한 도구인 Set에 대해 배우는 시간입니다. 구조와 원리에 대해서는 “Java로 배우는 자료구조” 코스에서 좀 더 깊게 이해를 하실 수 있습니다. 이 강의에서는 어떤 도구들이 있고 어떤 특징이 있는지, 어떻게 사용하는지에 대해서만 알아봅니다.


목차


  1. Set<E>

  2. HashSet<E>

  3. TreeSet<E>

  4. LinkedHashSet<E>

  5. [추가] 합집합, 교집합, 차집합, 여집합, 부분집합

1. Set<E>


Java의 Collection에는 집합(Set)이라는 자료구조가 있습니다. 집합처럼 중복되지 않는 원소들의 모음을 만들 수 있는 자료구조를 Set이라고 합니다.

set1 이러한 Set의 특징은 집합에 있는 동일한 원소를 저장하더라도 Set에는 중복된 원소가 존재하지 않는다는 점입니다.

set2

Set의 구조가 왜 필요할까요? 수학과 관련된 일이 아니면 써먹을 일이 없지 않을까요? 라고 생각할 수도 있습니다. 간단한 예시로 고민해 봅시다.

접속 날짜

접속 시간

아이디

2020-01-01

10:00

roka

2020-01-01

20:00

코드라떼

2020-01-02

13:00

roka

2020-01-02

13:30

코드라떼

2020-01-02

14:00

roka

2020-01-02

15:00

카페라떼

2020-01-02

18:00

카페라떼

해당 표는 특정 아이디가 어떤 서비스에 접속한 날짜와 시간이라고 가정합니다.


그리고 해당 표를 이용하여 우리는 두 가지 문제를 풀어야 한다고 가정합니다.

  • 2020-01-01 ~ 2020-01-02 까지 접속한 아이디의 수

  • 2020-01-01 ~ 2020-01-02 까지 접속한 아이디

이 문제를 어떻게 풀 수 있을까요?


혹시 눈으로 슥~ 보면서 풀고계시진 않으신가요?


이럴 때 Set구조를 이용하면 간단하게 풀 수 있습니다.


Set에는 크게 TreeSet, HashSet, LinkedHashSet이 있습니다.


우리는 각 Set과 관련된 클래스들을 살펴보며 장점과 단점은 무엇인지 그리고 어떤 특징이 있는지 살펴볼 예정입니다.


2. HashSet<E>


HashSet은 데이터 저장을 Hash Table을 이용하는 구조로 저장하는 Set입니다.


Set의 특징을 가지고 있으며, 동일한 원소를 저장하더라도 저장소에 중복된 값이 존재하지 않습니다.


HashSet은 HashTable 구조를 이용한 HashMap을 이용하여 만들어져 있습니다.

// HashSet의 생성자
public HashSet() {
    map = new HashMap<>();
}

public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size() / 0.75f) + 1, 16));
}

HashSet의 생성자를 보면 HashMap을 이용하여 Set 구조를 만드는 것을 확인할 수 있습니다.

// 더미 Object
public static final Object PRESENT = new Object();

// HashSet의 데이터 add 메서드
public boolean add(E e) {
    return map.put(e, PRESENT) == null;
}

Map의 특성 중 하나인 중복 key는 존재할 수 없다는 특징을 이용하여, key를 Set의 값으로, value에는 더미 Object를 저장 방식으로 데이터를 추가합니다.


즉, HashSet을 이해하려면 HashMap에 대해서 먼저 알아야 합니다.


특징

  • Hash Table 구조 기반이다.

  • HashMap을 이용하여 구현되므로, HashMap의 장점과 특징을 그대로 계승한다.

사용용도

  • index가 아닌 key를 이용하여 데이터 저장과 접근이 필요할 경우 사용한다.

  • 데이터의 크기가 어느 정도 예상되는 경우 사용한다.

  • 삽입 삭제가 빈번할 경우 사용한다.

HashSet의 생성

import java.util.HashSet;

HashSet<String> texts = new HashSet<>();

HashSet의 데이터 삽입

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("코드라떼");
set.add("codelatte");

HashSet.add(value) 메서드를 이용하여 데이터를 저장할 수 있습니다.


HashSet 값 포함 여부 확인

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("코드라떼");
set.add("codelatte");

boolean isExist = set.contains("codelatte");
// 있으면 true, 없으면 false

HashSet 값 삭제

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("코드라떼");
set.add("codelatte");
set.add("카페라떼");

// 데이터 삭제
set.remove("카페라떼");

HashSet 값 출력

import java.util.HashSet;

// String value
HashSet<String> set = new HashSet<>();

// 데이터 삽입
set.add("1");
set.add("23");
set.add("2");
set.add("14");
set.add("2");
set.add("5");

for (String value : set) {
    System.out.println(value);
}

// "1", "23", "2", "14", "5"

HashMap을 이용하여 만들어졌으므로, 저장된 값은 정렬되어 있지 않습니다.


3. TreeSet<E>


TreeSet은 논리적인 Tree 구조로 데이터를 저장하는 Set입니다.


Set의 특징을 가지고 있으며, 동일한 원소를 저장하더라도 저장소에는 중복된 값이 존재하지 않습니다.

또한 TreeSet은 Tree 구조를 이용한 TreeMap을 이용하여 만들어져 있습니다.

// TreeSet의 생성자
public TreeSet() {
    this(new TreeMap<E, Object>());
}

TreeSet의 생성자를 보면 TreeMap을 이용하여 Set 구조를 만드는 것을 확인할 수 있습니다.

// 더미 Object
public static final Object PRESENT = new Object();

// TreeSet의 데이터 add 메서드
public boolean add(E e) {
    return m.put(e, PRESENT) == null;
}

Map의 특성 중 하나인 중복 key는 존재할 수 없다는 특징을 이용하여, key를 Set의 값으로, value에는 더미 Object를 저장 방식으로 데이터를 추가합니다.


즉, TreeSet을 이해하려면 TreeMap에 대해서 먼저 알아야 합니다.


특징

  • Tree 구조 기반이다.

  • TreeMap을 이용하여 구현되므로, TreeMap의 장점과 특징을 그대로 계승한다.

사용용도

  • 저장되는 데이터의 개수가 몇 개인지 예상되지 않는 경우 사용한다.

  • 삽입과 삭제가 빈번하지 않을 때 사용한다.

  • 정렬된 값이 필요할 때 사용한다.

TreeSet의 생성

import java.util.TreeSet;

TreeSet<String> texts = new TreeSet<>();

TreeSet의 데이터 삽입

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

TreeSet.add(value) 메서드를 이용하여 데이터를 저장할 수 있습니다.


TreeSet 값 포함 여부 확인

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

boolean isExist = set.contains("코드라떼");
// 있으면 true, 없으면 false

TreeSet 값 삭제

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

// 데이터 삭제
set.remove("코드라떼");

TreeSet 값 출력

import java.util.TreeSet;

// String value
TreeSet<String> set = new TreeSet<>();

// 데이터 삽입
set.add("1");
set.add("3");
set.add("2");
set.add("4");
set.add("2");
set.add("5");

for (String value : set) {
    System.out.println(value);
}

// "1", "2", "3", "4", "5"

TreeMap을 이용하여 만들어졌으므로, 저장된 값은 오름차순으로 정렬되어 출력할 수 있습니다.


4. LinkedHashSet<E>


LinkedHashSetHashSet을 상속하여 만들어진 클래스입니다.


그러므로 HashSet의 특징을 가지고 있습니다.

// LinkedHashSet은 HashSet을 상속 받는다
public LinkedHashSet<E> extends HashSet<E>// LinkedHashSet의 생성자
public LinkedHashSet() {
    super(16, .75f, true);
}

LinkedHashSet의 생성자를 보면 HashSet을 상속받은 것을 확인할 수 있습니다.


다만 주의할 점은 super 키워드를 사용하여 호출할 때, HashSetdefault 접근 제어 지시자의 생성자를 호출합니다.

// HashSet의 default 접근 제어 지시자 생성자
HashSet(int initialCapacity, float loadFactor, boolean dummy {
    map = new LinkedHashMap<>(initialCapacity, loadFactor)
}

HashSet에는 LinkedHashMap을 이용하는 코드가 작성되어있습니다.


즉 정리하면, HashSet 클래스에는 기본적으로는 HashMap을 이용하도록 구현되어 있으나 HashSet 클래스를 상속받아 구현할 때는, java.util 패키지 내에서 default 접근 제어 지시자로 작성된 HashSet 생성자를 super 키워드를 이용하여 호출 가능하기 때문에 LinkedHashMap으로 사용할 수 있도록 구현되어 있습니다.


특징

  • HashSet을 상속받아 구현되나, LinkedHashMap을 이용하며 LinkedHashMap의 특징을 그대로 계승한다.

사용용도

  • 값의 저장된 순서가 중요할 때 사용한다.

LinkedHashSet의 생성

import java.util.LinkedHashSet;

LinkedHashSet<String> texts = new LinkedHashSet<>();

LinkedHashSet의 데이터 삽입

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

LinkedHashSet.add(value) 메서드를 이용하여 데이터를 저장할 수 있습니다.


LinkedHashSet 값 포함 여부 확인

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");

boolean isExist = set.contains("roka");
// 있으면 true, 없으면 false

LinkedHashSet 값 삭제

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("codelatte");
set.add("코드라떼");
set.add("카페라떼");

// 데이터 삭제
set.remove("카페라떼");

LinkedHashSet 값 출력

import java.util.LinkedHashSet;

// String value
LinkedHashSet<String> set = new LinkedHashSet<>();

// 데이터 삽입
set.add("1");
set.add("23");
set.add("3");
set.add("14");
set.add("2");
set.add("5");

for (String value : set) {
    System.out.println(value);
}

// "1", "23", "3", "14", "2", "5"

LinkedHashMap을 이용하므로, 저장된 값은 저장된 순서대로 출력됩니다.


5. [추가] 합집합, 교집합, 차집합, 여집합, 부분집합


추가적으로 합집합, 교집합, 차집합, 여집합, 부분집합을 연산하거나 확인하고 싶을 때 보시면 됩니다.


지금 당장 필요하지 않다면 후 순위로 미뤄두시는 것이 낫습니다.


set example


세 개의 집합이 존재합니다.


A = {1, 2, 3, 4, 5}

B = {3, 4, 5, 6, 7}

C = {3, 4}


우리는 Java에서 이 세 개의 집합을 어떻게 표현하며 합집합, 교집합, 차집합, 여집합, 부분집합 여부를 어떻게 연산하는지 확인해볼 예정입니다.

// A 집합
List<String> set1 = Arrays.asList("1", "2", "3", "4", "5");
TreeSet<String> A = new TreeSet<>(set1);

// B 집합
List<String> set2 = Arrays.asList("3", "4", "5", "6", "7");
TreeSet<String> B = new TreeSet<>(set2);

// C 집합
List<String> set3 = Arrays.asList("3", "4");
TreeSet<String> C = new TreeSet<>(set3);

C 집합이 A 집합의 부분집합인지 확인 방법 (C ⊂ A)

boolean isContainAll = B.containsAll(C);
System.out.println("C ⊂ B ? "+isContainAll);

Set.containsAll(set) 메서드를 이용하여 부분집합 여부를 확인할 수 있습니다.

부분집합이면 true, 부분집합이 아니면 false를 반환합니다.


원소의 포함여부 확인 방법 (x ∈ B)

boolean isContain = B.contains("7");
System.out.println("7 ⊂ B ? "+ isContain);

Set.contains(value) 메서드를 이용하여 해당 집합에 원소가 포함되는지 확인할 수 있습니다.

원소가 포함되면 true, 원소가 포함되지 않으면 false를 반환합니다.


A 교집합 B 추출 방법 (A ∩ B)

TreeSet<String> cloneA = new TreeSet<>(set1);
boolean isModified = cloneA.retainAll(B);
System.out.println("A ∩ B ? "+cloneA);

Set.retainAll(collection) 메서드를 이용하여 교집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.retainAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 손실을 원하지 않는다면 원본을 복사해서 사용해야 합니다.


A 합집합 B 추출 방법 (A ∪ B)

TreeSet<String> cloneA = new TreeSet<>(set1);
boolean isModified = cloneA.addAll(B);
System.out.println("A ∪ B ? "+cloneA);

Set.addAll(collection) 메서드를 이용하여 합집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.addAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 변경을 원하지 않는다면 원본을 복사해서 사용해야 합니다.


A 차집합 B 추출 방법 (A - B)

TreeSet<String> cloneA = new TreeSet<>(set1);
boolean isModified = cloneA.removeAlll(B);
System.out.println("A - B ? "+cloneA);

Set.removeAll(collection) 메서드를 이용하여 차집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.removeAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 변경을 원하지 않는다면 원본을 복사해서 사용해야 합니다.

도전자 질문
아이콘upqnu(2022-06-13 17:18 작성됨)
실습도구에서 합집합, 교집합, 차집합은 구현에 문제가 없지만, 나머지 3개는 각각의 주석만 풀고 실행시켰을 때 에러가 나옵니다. (코드의 다른 부분을 수정하지 않았습니다.) 확인을 부탁드립니다.
아이콘코드라떼(2022-06-14 05:59 작성됨)
안녕하세요. 코드라떼입니다 :)

패키지가 import되지 않아서 발생한 문제로 import 구문을 추가한 코드를 업로드했습니다.

감사합니다 :)
아이콘넬준(2021-10-21 15:18 작성됨)
'LinkedHashSet값 출력'부분에서 마지막 결과 값 순서가

1 23 3 14 2 5 인건가요? 저장된 순서대로 출력되는거니까
아이콘코드라떼(2021-10-21 16:35 작성됨)
안녕하세요. 코드라떼입니다 :)

"1" "23" "3" "14" "2" "5"가 맞습니다.
뭐라 드릴 말씀이 없군요.. 감사합니다!

ps. 추가로 넬준님 메일로 프로모션 코드를 제공해드렸습니다.

확인 부탁드립니다. 감사합니다 :)
아이콘자바배움이(2021-07-09 13:13 작성됨)
추가노트 마지막 문단에 아래와 같이 써있는데, 오타가 있어요!

/*
Set.removeAll(collection) 메서드를 이용하여 합집합을 추출할 수 있습니다.

반환값은 cloneA 변경 여부를 반환합니다.

cloneA에 원소가 존재하지 않는 경우를 제외하고는 항상 true를 반환한다고 보시면 됩니다.

그리고 Set.addAll(collection) 메서드는 원본의 데이터를 변경하므로, 원본의 데이터 변경을 원하지 않는다면 원본을 복사해서 사용해야 합니다.
*/

첫번째 줄 : 합집합 -> 차집합
마지막 줄 : Set.addAll(collection) -> Set.removeAll(collection)
아이콘코드라떼(2021-07-09 20:31 작성됨)
자바배움이님 감사합니다.^^ 수정했습니다.

ps.자바배움이 님이 꼼꼼하게 공부하시는 것에 감명 깊어 이후에 나올 코스를 무료로 수강하실 수 있도록 출시 후에 별도로 연락드리겠습니다.^^
이용약관|개인정보취급방침
알유티씨클래스|대표, 개인정보보호책임자 : 이병록
이메일 : cs@codelatte.io|운영시간 09:00 - 18:00(평일)
사업자등록번호 : 824-06-01921|통신판매업신고 : 2021-성남분당C-0740
주소 : 경기도 성남시 분당구 대왕판교로645번길 12, 9층 24호(경기창조혁신센터)
파일
파일파일
Root
파일

Output
root$