개발/Java

java.util.collections 총정리 set편

728x90

java.util에 존재하는 collection들을 이번 글에서는 Set부터 정리해보자.

javadoc, 구현 코드를 중심 분석해볼 예정

java8 java.util에 존재하는 Collection

 

간단하게 java.util에 존재하는 Collection들을 알아보고 Set에 대해서 알아보자.

 

우선 상속과 구현된 구조를 살펴보자

 

인터페이스 구조

  • Collection 인터페이스
    • Set<E>
      • SortedSet<E>
      • NavigableSet<E>
    • Queue<E>
      • Deque<E>
    • List<E>
  • AbstractCollection<E>
    • Collection 인터페이스를 구현한 추상 클래스 
    • 중복을 허용함
    • 실제 저장 구조와 관계된 함수는 미구현됨.
    • AbstractSet<E>
      • HashSet<E>
        • LinkedHashSet<E>
      • TreeSet<E>
      • EnumSet<E>
    • AbstractList<E>
      • ArrayList<E>
      • AbstractSequentialList<E>
        • LinkedList<E>
      • Vector<E>
        • Stack<E>
    • AbstractQueue<E>
      • PriorityQueue<E>
    • ArrayDeque<E>
  • Set<E> 인터페이스
    • 중복을 허용하지 않는 Collection. 
    • SortedSet<E>
      • NavigableSet<E>
    • AbstractSet<E>
      • HashSet<E>
  • List<E>
    • AbstractList<E>
  •  
  • Queue<E>
    • Deque<E>
      • public interface Deque<E> extends Queue<E>
        • Cloneable, Serialzable 구현
      • ArrayDeque<E>
    • AbstractQueue<E>
      • ProrityQueue<E>

 

 

이제 본격적우로 Set에 대해 알아보자.

모두 Collection에 구현되어 있는 메소드

 

특이사항은

default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}

중복된 원소가 없고, 

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

 

  • SortedSet
    • Set을 extends한 인터페이스
public interface SortedSet<E> extends Set<E>

모든 원소를 정렬하여 제공하고, 정렬하는 기준은 다음과 같다.

 

1. Comparable인터페이스를 구현하고 있는 클래스의 객체를 원소로 사용

2. Comparator 인터페이스를 구현한 대소 판단을 위한 로직을 SortedSet 객체 생성시에 넘길수있다.

그리고 comparator()를 통해 사용하고 있는 comparator를 리턴받을 수 있다.

 

 * A {@link Set} that further provides a <i>total ordering</i> on its elements.
 * The elements are ordered using their {@linkplain Comparable natural
 * ordering}, or by a {@link Comparator} typically provided at sorted
 * set creation time.  The set's iterator will traverse the set in
 * ascending element order. Several additional operations are provided
 * to take advantage of the ordering.  (This interface is the set
 * analogue of {@link SortedMap}.)

*Comparable - 이 인터페이스를 구현한 객체 스스로에게 부여하는 한 가지 기본 정렬 규칙을 설정하는 목적으로 사용됨

아래 하나의 메소드만 포함하고 있다. 매개변수로 비교 대상의 오브젝트를 넘기면, 대소관계에 따라 -1, 0, 1중 하나를 리턴함.

    public int compareTo(T o);

*Comparator - 이 인터페이스를 구현한 클래스를 정렬 규칙 자체를 의미하고, 기본 정렬 규칙과 다르게 정렬 규칙을 커스텀 할 수 있다.

 A comparison function, which imposes a <i>total ordering</i> on some
 * collection of objects.  Comparators can be passed to a sort method (such
 * as {@link Collections#sort(List,Comparator) Collections.sort} or {@link
 * Arrays#sort(Object[],Comparator) Arrays.sort}) to allow precise control
 * over the sort order.  Comparators can also be used to control the order of
 * certain data structures (such as {@link SortedSet sorted sets} or {@link
 * SortedMap sorted maps}), or to provide an ordering for collections of
 * objects that don't have a {@link Comparable natural ordering}.<p>

 

AbstractSet

Set을 구현하는 데 필요한 뼈대를 제공하여. 이 인터페이스를 구현하는데 필요한 비용을 최소화한다.

 * This class provides a skeletal implementation of the <tt>Set</tt>
 * interface to minimize the effort required to implement this
 * interface. <p>
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E>

특이점은 equals와 hashCode()가 아래와 같이 구현되어 있다.

    public boolean equals(Object o) {
        if (o == this)
            return true;

        if (!(o instanceof Set))
            return false;
        Collection<?> c = (Collection<?>) o;
        if (c.size() != size())
            return false;
        try {
            return containsAll(c);
        } catch (ClassCastException unused)   {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }
    }
    public int hashCode() {
        int h = 0;
        Iterator<E> i = iterator();
        while (i.hasNext()) {
            E obj = i.next();
            if (obj != null)
                h += obj.hashCode();
        }
        return h;
    }

 

 

NavigableSet

말 그대로 탐색 가능한 set, sorted된 set를 탐색할 수 있다.

탐색을 돕는 메소드들이 정의되어 있고,  lower, floor, ceiling, higher 등을 통해 미만, 이하, 이상, 초과하는 원소를 리턴해준다.

내림차순 혹은 오름차순으로 탐색하고, 

public interface NavigableSet<E> extends SortedSet<E>
 * A {@link SortedSet} extended with navigation methods reporting
 * closest matches for given search targets. Methods {@code lower},
 * {@code floor}, {@code ceiling}, and {@code higher} return elements
 * respectively less than, less than or equal, greater than or equal,
 * and greater than a given element, returning {@code null} if there
 * is no such element.
A {@code NavigableSet} may be accessed and
 * traversed in either ascending or descending order.  The {@code
 * descendingSet} method returns a view of the set with the senses of
 * all relational and directional methods inverted.
* <p> The return values of navigation methods may be ambiguous in
 * implementations that permit {@code null} elements. However, even
 * in this case the result can be disambiguated by checking
 * {@code contains(null)}. To avoid such issues, implementations of
 * this interface are encouraged to <em>not</em> permit insertion of
 * {@code null} elements. (Note that sorted sets of {@link
 * Comparable} elements intrinsically do not permit {@code null}.)

 

TreeSet

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
* A {@link NavigableSet} implementation based on a {@link TreeMap}.
 * The elements are ordered using their {@linkplain Comparable natural
 * ordering}, or by a {@link Comparator} provided at set creation
 * time, depending on which constructor is used.
 *

 

EnumSet

1.5에 소개 특히 enum 타입들을 사용하기 위해 특화된 클래스. 추가적으로 Cloneable, Serializable을 구현하고 있다.

내부적으로는 단순화와 성능을 위해 bit 벡터들로 표현된다. 예전의 int 기반의 bit flags 방식보다 공간, 시간측면에서 높은 성능을 보여주고 typefase하다. 그리고 containsAll. retainAll같은 메소들도 매개변수가 enumset이면 매우 빠르게 동작한다.

 

null인 원소는 허용되지 않는다.

스레드 세이프 하지 않다. 동시에 여러 스레드가 접근할 ㅅ ㅜ있다. 적어도 하나의 스레드가 set을 수정하면 , 외부적으로 synchornized되어야 한다.

 

public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
    implements Cloneable, java.io.Serializable
A specialized {@link Set} implementation for use with enum types.  All of
 * the elements in an enum set must come from a single enum type that is
 * specified, explicitly or implicitly, when the set is created.
Enum sets
 * are represented internally as bit vectors.  This representation is
 * extremely compact and efficient. The space and time performance of this
 * class should be good enough to allow its use as a high-quality, typesafe
 * alternative to traditional <tt>int</tt>-based "bit flags."  Even bulk
 * operations (such as <tt>containsAll</tt> and <tt>retainAll</tt>) should
 * run very quickly if their argument is also an enum set.

 

HashSet

 

LinkedHashSet

Set인터페이스를 통해 구현된 예측 가능한 iterator 순서로 되어있는 해시테이블 이면서 링크드리스트이다.

이 구현은 treeset의 비용없이 원소를 정렬된채로 유지시켜준다. 원래 set의 구현에 상관없이, set을 복사할 때 원래 순서를 유지할 때 사용된다.

 

4개의 생성자와, spliteratror()가 정의되어 있다

  • public LinkedHashSet(int initialCapacity, float loadFactor)  : 초기 크기와, 로드팩터를 받아 비어있는 set 생성
  • public LinkedHashSet(int initialCapacity) {
    super(initialCapacity, .75f, true);
    } : 로드팩터가 0.75로 비어있는 set를 생성.
  • public LinkedHashSet() {
    super(16, .75f, true);
    } : 초기 크기가 16, 로드팩터가 0.75인 set 생성
  • public LinkedHashSet(Collection<? extends E> c) : 매개변수로 넘긴 collection과 같은 원소를 가지는 set를 생성한다. 로드팩터는 0.75로 초기화함.
    • super(Math.max(2*c.size(), 11), .75f, true)
      • 컬렉션 크기의 2배 혹은 11중에 큰 값을 초기 사이즈로 할당한다.
      •  
  • public Spliterator<E> spliterator() 
public class LinkedHashSet<E>
    extends HashSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
 * <p>Hash table and linked list implementation of the <tt>Set</tt> interface,
 * with predictable iteration order.  This implementation differs from
 * <tt>HashSet</tt> in that it maintains a doubly-linked list running through
 * all of its entries.  This linked list defines the iteration ordering,
 * which is the order in which elements were inserted into the set
 * (<i>insertion-order</i>).  Note that insertion order is <i>not</i> affected
 * if an element is <i>re-inserted</i> into the set.  (An element <tt>e</tt>
 * is reinserted into a set <tt>s</tt> if <tt>s.add(e)</tt> is invoked when
 * <tt>s.contains(e)</tt> would return <tt>true</tt> immediately prior to
 * the invocation.)
 * <p>This implementation spares its clients from the unspecified, generally
 * chaotic ordering provided by {@link HashSet}, without incurring the
 * increased cost associated with {@link TreeSet}.  It can be used to
 * produce a copy of a set that has the same order as the original, regardless
 * of the original set's implementation:
 
 * This technique is particularly useful if a module takes a set on input,
 * copies it, and later returns results whose order is determined by that of
 * the copy.  (Clients generally appreciate having things returned in the same
 * order they were presented.)

사진출처 : www.falkhausen.de/Java-8/java.util/Collection-List.html

 

 

'개발 > Java' 카테고리의 다른 글

Netty란?  (0) 2021.05.14
Lombok의 동작원리  (1) 2021.05.13
Lombok 이란?  (0) 2021.05.12
mixin이란  (0) 2021.05.11
hashCode()  (0) 2021.05.08