Set

JDK 1.2부터 도입된 컬렉션 프레임워크는 자료구조&알고리즘과 이를 구현한 표준 인터페이스를 제공한다.

png

컬렉션 프레임워크는 Set 인터페이스를 제공한다. Set을 구현한 클래스에는 HashSet, LinkedHashSet, TreeSet, AbstractSet, EnumSet 등이 있으나 가장 자주 쓰이는 HashSet, LinkedHashSet, TreeSet만 알아볼 예정이다(자바 내부 코드는 JDK 17 버전이다).

Set

Set은 중복을 허용하지 않는 자료구조이다.

1. HashSet

HashSet은 Set을 구현한 컬렉션이다.

1.1. 기본설정

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    private transient HashMap<E,Object> map;
    private static final Object PRESENT = new Object();
}

HashSet은 HashMap의 key만 사용해서 데이터를 저장한다. PRESENT는 HashMap의 value로 저장되는 더미 값이다.

1.2. 생성

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    public HashSet() {
        map = new HashMap<>();
    }

    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

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

HashSet은 HashSet 내부 코드에서 정의한 네 개의 생성자로 생성할 수 있다.

  1. 빈 값으로 생성

  2. 용량을 지정해서 생성

  3. 용량과 Load Factor를 지정해서 생성

  4. 다른 컬렉션을 복사해서 생성

1.3. 추가

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
}

HashSet에 값을 추가할 때는 add 메서드를 호출한다. add 메서드는 내부적으로 HashMap의 put 메서드를 호출한다. HashSet은 key만 사용하므로 value에는 PRESENT가 들어간다.

1.4. 삭제

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }
}

HashSet에 값을 삭제할 때는 remove 메서드를 호출한다. remove 메서드는 HashMap의 remove 메서드를 호출한다.

2. LinkedHashSet

LinkedHashSet은 HashSet을 확장해서 구현한 컬렉션으로 순서를 가지는 HashSet을 생성한다.

2.1. 생성

public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable {

    public LinkedHashSet() {
        super(16, .75f, true);
    }

    public LinkedHashSet(int initialCapacity) {
        super(initialCapacity, .75f, true);
    }

    public LinkedHashSet(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor, true);
    }

    public LinkedHashSet(Collection<? extends E> c) {
        super(Math.max(2*c.size(), 11), .75f, true);
        addAll(c);
    }
}

LinkedHashSet은 LinkedHashSet 내부 코드에서 정의한 네 개의 생성자로 생성할 수 있다.

  1. 빈 값으로 생성

  2. 용량을 지정해서 생성

  3. 용량과 Load Factor를 지정해서 생성

  4. 다른 컬렉션을 복사해서 생성

2.2. 추가 및 삭제

HashSet과 동일하다.

3. TreeSet

TreeSet은 NavigableSet을 구현한 컬렉션이다.

3.1. 기본설정

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable {

    private transient NavigableMap<E,Object> m;
    private static final Object PRESENT = new Object();
}

HashSet은 NavigableMap의 key만 사용해서 데이터를 저장한다. PRESENT는 HashMap의 value로 저장되는 더미 값이다.

3.2. 생성

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable {

    public TreeSet() {
        this(new TreeMap<>());
    }

    public TreeSet(SortedSet<E> s) {
        this(s.comparator());
        addAll(s);
    }

    public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }

    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
}

TreeSet은 TreeSet 내부 코드에서 정의한 네 개의 생성자로 생성할 수 있다.

  1. 빈 값으로 생성

  2. 다른 정렬된 Set을 복사해서 생성

  3. 다른 컬렉션을 복사해서 생성

  4. comparator(비교자)를 지정해서 생성

3.3. 추가

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable {

    public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }
}

TreeSet에 값을 추가할 때는 add 메서드를 호출한다. add 메서드는 내부적으로 NavigableMap의 put 메서드를 호출한다. HashSet은 key만 사용하므로 value에는 PRESENT가 들어간다.

3.4. 삭제

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable {

    public boolean remove(Object o) {
        return m.remove(o)==PRESENT;
    }
}

TreeSet에 값을 삭제할 때는 remove 메서드를 호출한다. remove 메서드는 NavigableMap의 remove 메서드를 호출한다.

Last updated