HashSet ve LinkedHashSet karşılaştırması


154

Onların arasındaki fark ne? bunu biliyorum

LinkedHashSet, HashSet'in sıralı bir sürümüdür ve tüm öğeler arasında çift bağlantılı bir Liste sağlar. Yineleme sırasını önemsediğinizde HashSet yerine bu sınıfı kullanın. Bir HashSet üzerinden yinelediğinizde, sipariş tahmin edilemezken, LinkedHashSet öğeleri yerleştirildikleri sırayla yinelemenize izin verir.

Ancak LinkedHashSet'in kaynak kodunda sadece HashSet'in çağrı yapıcıları vardır. Peki çift bağlantılı Liste ve ekleme sırası nerede?


2
cevabı izlemek için Intellij (Ctrl + B) seçeneğini kullanın. :)
Delta

Tabii ki ekli kaynak koduna ihtiyacınız var. :)
Delta

Yanıtlar:


65

Cevap, hangiLinkedHashSet sınıfın temel sınıfı oluşturmak için kullanıldıklarıdır:

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);
}

Ve (bir örnek) bir HashSetboole argümanı alan bir kurucu açıklanır ve şöyle görünür:

/**
 * 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
Bir alt sınıf için açıkça işlevselliğe sahip bir üst sınıf, ayırt etmek için göz ardı edilen bir argüman
Traubenfuchs

5
Yapıcı belirsizlik için kukla bir parametre kullanarak tam olarak temiz bir tasarım değil.
Eric J.

8
API temiz olduğu için oldukça temiz bir tasarımdır (bu HashSet yapıcısı paket özeldir). Uygulama ayrıntıları sınıf kullanıcıları için önemli değildir. Bu kodu korumak daha zor olabilir, ancak java.util sınıflarında, çok küçük performans geliştirmeleri bile bunu haklı çıkarabilir.
lbalazscs

25

LinkedHashSetadlı kullanıcının yapıcıları aşağıdaki temel sınıf yapıcısını çağırır:

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

Gördüğünüz gibi, iç harita bir LinkedHashMap. İçeri bakarsanız LinkedHashMap, aşağıdaki alanı keşfedeceksiniz:

private transient Entry<K, V> header;

Bu, söz konusu bağlantılı listedir.


24

HashSet olan sırasız ve sıralanmamış Seti.
LinkedHashSet , HashSet'in sıralı sürümüdür .

HashSet ve LinkedHashSet arasındaki tek fark şudur:
LinkedHashSet , ekleme sırasını korur.

Bir HashSet üzerinden yinelediğimizde , sipariş LinkedHashSet durumunda öngörülebilirken öngörülemez .

Nasıl sebebi LinkedHashSet kampanya siparişini kendisine ait orijinal:
altta yatan kullanılan veri yapısıdır Çifte Bağlantılı-List .


9

Sen kaynağına bakmak gerekir HashSeto çağıran yapıcı ... Bu destek kılan özel bir yapıcı olduğunu Mapbir LinkedHashMapyerine sadece HashMap.


Teşekkürler, HashSet içinde LinkedHashSet denilen LinkedHashMap oluşturmak için yapıcı vardır ve tüm mantık LinkedHashMap
Shikarn-O

6

Genel olarak daha iyi performansaLinkedHashSet sahip olduğu için çoğu zaman kullanmanızı öneririm ):

  1. Öngörülebilir yineleme sırası LinkedHashSet (Oracle)
  2. LinkedHashSet, eklemeler için HashSet'ten daha pahalıdır;
  3. Genel olarak biraz daha iyi performans HashMap, çünkü çoğu zaman yineleme için Set yapıları kullanıyoruz.

Performans testleri:

------------- 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

Kaynak test sayfasını burada görebilirsiniz: Son Performans Testi Örneği


2
Bu "kıyaslama ölçütlerinden" önce JVM'de herhangi bir ısınma görmüyorum, bu yüzden bu verilerin hiçbirini ciddiye almam. Devamını oku
Felix S

3

HashSet: Aslında sıralanmamış. eğer parametre geçiyorsa

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

Çıktı: 2,1,3Tahmin edilemeyebilir. bir dahaki sefere başka bir sipariş.

LinkedHashSet() hangi FIFO Sipariş üretmek.


3

HashSet ekleme öğesinin sırasını korumak yok ekleme öğesinin sırasını
LinkedHashSet korumak

Misal

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 çıktı

1
ab
2

LinkedHashSet çıktı

2
1
ab

2

HashSet:

Altı çizili veri yapısı Hashtable'dir. Yinelenen nesnelere izin verilmez. Ekleme sırası korunmaz ve nesnelerin karma kodunu temel alır. Boş yerleştirme mümkündür (yalnızca bir kez). Serileştirilebilir, Klonlanabilir ancak RandomAccess arabirimini uygular. HashSet, en sık kullanılan işlemin arama işlemi olup olmadığını seçmektir.

HashSet'te kopyalara izin verilmez. Kullanıcılar herhangi bir derleme veya çalışma zamanı istisnası almadığımızda kopyalar eklemeye çalışıyorsa. add yöntemi yalnızca false değerini döndürür.

Kurucular:

HashSet h = yeni HashSet (); varsayılan başlangıç ​​kapasitesi 16 olan boş bir HashSet nesnesi oluşturur ve varsayılan doldurma oranı (Yükleme faktörü) 0,75'tir.

HashSet h = yeni HashSet (int initialCapacity); belirtilen initialCapacity ile boş bir HashSet nesnesi oluşturur ve varsayılan dolgu oranı 0,75'tir.

HashSet h = yeni HashSet (int initialCapacity, float fillRatio);

HashSet h = yeni HashSet (Koleksiyon c); verilen koleksiyon için eşdeğer bir HashSet nesnesi oluşturur. Bu kurucu, toplama nesnesi arasında ara dönüşüm anlamına geliyordu.

LinkedHashSet:

HashSet öğesinin alt sınıfıdır. aşağıdaki farklılıklar dışında (Yapıcılar ve Yöntemler) dahil HashSet ile tamamen aynıdır.

HashSet Farkları:

  1. Altı çizili veri yapısı Hashtable'dir.
  2. Ekleme talimatı korunmuyor.
  3. 1.2 sürümünü tanıttı.

LinkedHashSet:

  1. Altı çizili veri yapısı, LinkedList ve Hashtable'ın bir birleşimidir.
  2. Ekleme talimatı korunur.
  3. 1.4 sürümünde üretildi.

1

Sınıftan çağrılan yapıcılara bakarsanız, LinkedHashSetdahili olarak bunun LinkedHashMapdestek amacıyla kullanılan bir olduğunu göreceksiniz .


0

Tüm Yöntemler ve yapıcılar aynıdır, ancak LinkedHashset, ekleme sırasını koruyacak ancak yinelemelere izin vermeyecek tek bir farktır.

Hashset herhangi bir kampanya siparişi saklamaz. Liste ve Set basit kombinasyonu :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.