해시 세트 대 링크 된 해시 세트


153

그들 사이의 차이점은 무엇입니까? 알아

LinkedHashSet은 모든 요소에서 이중 연결 List를 유지 관리하는 HashSet의 정렬 버전입니다. 반복 순서를 염려 할 때 HashSet 대신이 클래스를 사용하십시오. HashSet을 반복하면 순서를 예측할 수 없지만 LinkedHashSet을 사용하면 요소를 삽입 한 순서대로 요소를 반복 할 수 있습니다.

그러나 LinkedHashSet의 소스 코드에는 HashSet의 호출 생성자 만 있습니다. 이중 연결 목록과 게재 신청서는 어디에 있습니까?


2
답변을 추적하려면 Intellij (Ctrl + B) 옵션을 사용하십시오. :)
델타

물론 소스 코드가 첨부되어 있어야합니다. :)
델타

답변:


65

답은 생성자LinkedHashSet사용하여 기본 클래스를 구성하는 데 있습니다.

public LinkedHashSet(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor, true);      // <-- boolean dummy argument
}

...

public LinkedHashSet(int initialCapacity) {
    super(initialCapacity, .75f, true);            // <-- boolean dummy argument
}

...

public LinkedHashSet() {
    super(16, .75f, true);                         // <-- boolean dummy argument
}

...

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

그리고 (의 일례) HashSet과 같이 설명한다 부울 인수를 취하고, 외모 생성자 :

/**
 * Constructs a new, empty linked hash set.  (This package private
 * constructor is only used by LinkedHashSet.) The backing
 * HashMap instance is a LinkedHashMap with the specified initial
 * capacity and the specified load factor.
 *
 * @param      initialCapacity   the initial capacity of the hash map
 * @param      loadFactor        the load factor of the hash map
 * @param      dummy             ignored (distinguishes this
 *             constructor from other int, float constructor.)
 * @throws     IllegalArgumentException if the initial capacity is less
 *             than zero, or if the load factor is nonpositive
 */
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
}

2
자식 클래스를 위해 명시 적으로 기능을 갖는 부모 클래스, 구별하기위한 무시 된 인수
Traubenfuchs

5
생성자 명확성을 위해 더미 매개 변수를 사용하는 깔끔한 디자인은 아닙니다.
Eric J.

8
API가 깨끗하기 때문에 디자인이 합리적입니다 (이 HashSet 생성자는 개인 패키지입니다). 구현 세부 사항은 클래스 사용자에게는 중요하지 않습니다. 이 코드를 유지 관리하는 것은 어려울 수 있지만 java.util 클래스의 경우 아주 작은 성능 향상만으로도이를 정당화 할 수 있습니다.
lbalazscs

25

LinkedHashSet의 생성자는 다음 기본 클래스 생성자를 호출합니다.

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
  map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);
}

보시다시피 내부지도는입니다 LinkedHashMap. 내부를 살펴보면 LinkedHashMap다음 필드를 발견 할 수 있습니다.

private transient Entry<K, V> header;

해당 링크 목록입니다.


24

HashSet정렬되지 않고 정렬되지 않은 집합입니다.
LinkedHashSet 은 HashSet 의 주문 버전 입니다.

HashSetLinkedHashSet 의 유일한 차이점은 다음 과 같습니다.
LinkedHashSet 은 게재 신청서를 유지합니다.

우리가 HashSet 을 반복 할 때 , LinkedHashSet의 경우 예측 가능한 반면 순서는 예측할 수 없습니다 .

LinkedHashSet이 삽입 순서를 유지 하는 방법 은 다음과 같습니다
. 기본 사용 된 데이터 구조는 Doubly-Linked-List 입니다.


9

당신은의 소스를 보라 HashSet는 호출 생성자 ... 그것을지지 해주는 특별한 생성자의 대신에 단지를 .MapLinkedHashMapHashMap


고맙게도, HashSet에는 LinkedHashSet에서 생성되는 LinkedHashMap을 생성하는 생성자가 있으며 모든 논리는 LinkedHashMap
Shikarn-O

5

전반적인 성능LinkedHashSet향상 되기 때문에 대부분의 시간 을 사용하는 것이 좋습니다 .

  1. 예측 가능한 반복 순서 LinkedHashSet (Oracle)
  2. LinkedHashSet은 HashSet보다 삽입에 더 비쌉니다.
  3. 일반적으로 HashMap반복에 Set 구조를 사용하기 때문에 일반적으로보다 약간 더 나은 성능 을 제공합니다.

성능 테스트 :

------------- TreeSet -------------
 size       add  contains   iterate
   10       746       173        89
  100       501       264        68
 1000       714       410        69
10000      1975       552        69
------------- HashSet -------------
 size       add  contains   iterate
   10       308        91        94
  100       178        75        73
 1000       216       110        72
10000       711       215       100
---------- LinkedHashSet ----------
 size       add  contains   iterate
   10       350        65        83
  100       270        74        55
 1000       303       111        54
10000      1615       256        58

여기서 소스 테스트 페이지를 볼 수 있습니다 : 최종 성능 테스트 예


2
"벤치 마크"이전의 JVM 워밍업을 보지 못하므로 해당 데이터를 심각하게 고려하지 않습니다. 더 읽기
Felix S

3

HashSet : 실제로 순서가 없습니다. U가 매개 변수를 전달하면

Set<Integer> set=new HashSet<Integer>();
for(int i=0;i<set.length;i++)
{
  SOP(set)`enter code here`
}

출력 : 2,1,3예측할 수 없습니다. 다음에 또 다른 주문.

LinkedHashSet() FIFO 주문을 생성합니다.


3

HashSet 삽입 항목의 순서를 유지하지 마십시오 삽입 항목 의 순서를
LinkedHashSet 유지 하십시오

Set<String> set = ...;// using new HashSet<>() OR new LinkedHashSet<>()
set.add("2");
set.add("1");
set.add("ab");
for(String value : set){
   System.out.println(value);
}  

HashSet 산출

1
ab
2

LinkedHashSet 산출

2
1
ab

2

해시 세트 :

밑줄이 그어진 데이터 구조는 Hashtable입니다. 중복 객체는 허용되지 않으며 삽입 순서는 유지되지 않으며 객체의 해시 코드를 기반으로합니다. 널 삽입이 가능합니다 (한 번만). Serializable, Clonable이지만 RandomAccess 인터페이스는 구현하지 않습니다. 빈번한 작업이 검색 작업 인 경우 HashSet을 선택하는 것이 가장 좋습니다.

HashSet에서는 중복이 허용되지 않습니다. 컴파일 또는 런타임 예외가 발생하지 않을 때 사용자가 중복을 삽입하려고하면. add 메소드는 단순히 false를 리턴합니다.

생성자 :

HashSet h = 새로운 HashSet (); 기본 초기 용량이 16이고 기본 채우기 비율 (부하 계수)이 0.75 인 빈 HashSet 객체를 만듭니다.

HashSet h = 새로운 HashSet (int initialCapacity); 지정된 initialCapacity를 가진 빈 HashSet 객체를 만들고 기본 채우기 비율은 0.75입니다.

HashSet h = 새로운 HashSet (int initialCapacity, float fillRatio);

HashSet h = 새로운 HashSet (컬렉션 c); 주어진 컬렉션에 대해 동등한 HashSet 객체를 만듭니다. 이 생성자는 컬렉션 개체 간의 상호 변환을 의미합니다.

LinkedHashSet :

HashSet의 자식 클래스입니다. 다음과 같은 차이점을 제외하고는 (Constructors and Methods)를 포함하여 HashSet과 정확히 동일합니다.

차이점 HashSet :

  1. 밑줄이 그어진 데이터 구조는 Hashtable입니다.
  2. 삽입 순서는 유지되지 않습니다.
  3. 1.2 버전이 도입되었습니다.

LinkedHashSet :

  1. 밑줄이 그어진 데이터 구조는 LinkedList와 Hashtable의 조합입니다.
  2. 삽입 순서가 유지됩니다.
  3. 1.4 버전으로 도입되었습니다.

1

LinkedHashSet클래스 에서 호출 된 생성자를 살펴보면 내부적 LinkedHashMap으로 백업 목적으로 사용되는 것을 볼 수 있습니다.


0

모든 메소드와 생성자는 동일하지만 한 가지 차이점은 LinkedHashset은 삽입 순서를 유지하지만 중복은 허용하지 않는다는 것입니다.

해시 셋은 게재 신청서를 유지하지 않습니다. List와 Set의 조합입니다. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.