개발자 노트

Collection 정리 - Set Interface 본문

컴퓨터 언어/Java

Collection 정리 - Set Interface

jurogrammer 2022. 7. 14. 22:42

관련 글

Set 인터페이스란?

중복된 elements를 담지 않는 Collection

특징

  • 수학의 집합을 모델 삼음
  • 오직 Collection의 메서드만 상속받고, 중복된 element를 금지하는 제약만 추가.
    • 이미 collection에 존재하는 element를 추가할 경우 add method의 반환 값은 false이다.
    • equals hashCode operation에 대한 강한 제약사항을 두었음.
  • Set 구현체의 타입이 다르더라도 Set inatance간 의미있는 비교 가능.
  • 두 Set간 동일한 elements를 지닐 경우, 두 set은 동일하다고 한다.

다용도 Set 구현체들

  • HashSet
    • hash table에 elements를 저장
    • 가장 성능이 좋음
    • 하지만, 순회(iteration)시 순서를 보장하지 않음.
  • TreeSet
    • red-black tree에 elements를 저장
    • values에 따라 정렬되어 있음.
    • 잠재적으로 HashSet보다는 느림
  • LinkedHashSet
    • hash table에서 linked list로 구현
    • set에 삽입되는 순서로 정렬되어 있음 (insertion-order)
    • client가 사용할 때 set을 순회시 알 수 없는 순서로 부터 혼동을 겪지 않아도 됨
      • 여기서 client란, Set interface를 이용하는 개발자
      • insertion 순서가 보장되어 있기 때문에 하는 말
    • HashSet보다 성능이 조금 떨어짐

Set의 특징을 이용한 여러 트릭들

(1) 중복 제거

Collection<Type> noDups = new HashSet<Type>(c);

c: Collection

c의 중복된 element는 HashSet 생성시 생성자에 c를 입력해주면 중복제거가 가능함.

(2) 중복제거 - Stream API 버전

c.stream()
.collect(Collectors.toSet()); // no duplicates

(3) 객체의 속성중복 제거하여 정렬한 후 담기

Set<String> set = people.stream()
.map(Person::getName)
.collect(Collectors.toCollection(TreeSet::new));

(4) 중복 제거 후, Collection에 담겨져있는 순서대로 담기

Collection<Type> noDups = new LinkedHashSet<Type>(c);

(5) (4)의 제너릭 메서드 버전

public static <E> Set<E> removeDups(Collection<E> c) {
    return new LinkedHashSet<E>(c);
}

Set Interface의 기본 연산

  • size
    • set에 있는 elments의 수를 반환 (cardinality 반환)
  • isEmpty
    • 비어 있는지
  • add
    • set에 특정한 element를 추가
    • 만약에 이미 존재한다면 false반환. (즉, element가 새로 추가되었는지? 에 대한 답)
    • returns a boolean indicating whether the element was added
  • remove
    • set에 특정한 elment 삭제
    • 만약 elment가 없었다면 false 반환 (즉, element가 존재했었는지? 에 대한 답) 과거형
    • returns a boolean indicating whether the element was present
  • interator
    • Set에 대한 Iterator 반환

Argument List에서 유니크한 words를 출력하는 예제

Stream 버전

import java.util.*;
import java.util.stream.*;

public class FindDups {
    public static void main(String[] args) {
        Set<String> distinctWords = Arrays.asList(args).stream()
        .collect(Collectors.toSet()); 
        System.out.println(distinctWords.size()+ 
                           " distinct words: " + 
                           distinctWords);
    }
}

for-each 버전

import java.util.*;

public class FindDups {
    public static void main(String[] args) {
        Set<String> s = new HashSet<String>();
        for (String a : args)
               s.add(a);
        System.out.println(s.size() + " distinct words: " + s);
    }
}

Set Interface bulk Operations

일반적인 수학의 집합에 대한 연산을 수행함

  • s1.containsAll(s2)
    • s2가 s1의 부분집합일 경우 true반환
  • s1.addAll(s2)
    • s1을 s1과 s2에 대한 합집합으로 변환함
  • s1.retainAll(s2)
    • s1을 s1과 s2의 교집합으로 변환함
  • s1.removeAll(s2)
    • s1을 s1에 대한 s2의 차집합으로 변환함 (s1 - s2)

한편, 위 연산들은 s1을 수정함. (without modifying either set), (nondestructively)

s1을 변경하지 않고 각 연산의 결과를 얻으려면 반드시 s1을 copy해야 함

Set<Type> union = new HashSet<Type>(s1);
union.addAll(s2);

Set<Type> intersection = new HashSet<Type>(s1);
intersection.retainAll(s2);

Set<Type> difference = new HashSet<Type>(s1);
difference.removeAll(s2);

입력한 값 중 유일한 값, 중복된 값을 구분지어 출력하는 예제

import java.util.*;

public class FindDups2 {
    public static void main(String[] args) {
        Set<String> uniques = new HashSet<String>();
        Set<String> dups    = new HashSet<String>();

        for (String a : args)
            if (!uniques.add(a))
                dups.add(a);

        // Destructive set-difference
        uniques.removeAll(dups);

        System.out.println("Unique words:    " + uniques);
        System.out.println("Duplicate words: " + dups);
    }
}

Set Interface Array Operations

Set 인터페이스는 Collection와 다르게 array와 관련하여 어떠한 연산도 제공해주지 않음.

cf. Collection

c.toArray();

c.toArray(new String[0]);
반응형

'컴퓨터 언어 > Java' 카테고리의 다른 글

stream api - peek  (0) 2022.12.13
Collection 정리 - Collection Interface  (0) 2022.07.06
Collection 정리 - Implementations  (0) 2022.07.04
Collections정리 - Interfaces  (0) 2022.06.30
Collection 정리  (0) 2022.06.30
Comments