LinkedHashMap nesnesinden anahtarların ve değerlerin döndürülmesi için sipariş garanti ediliyor mu?


162

LinkedHashMapTahmin edilebilir bir yineleme sırası (ekleme sırası) olduğunu biliyorum . Does Settarafından döndürülen LinkedHashMap.keySet()ve Collectiondöndürdüğü LinkedHashMap.values()de bu düzeni korumak?


1
Tüm cevaplar konusunu ele beri values()sıra sıra keySet(), ben genişlettik soru şu eklemeyi. Bu, bunun kopyaları olarak daha fazla sorunun kapatılabileceği anlamına gelir.
Duncan Jones

Yanıtlar:


226

Harita arayüzü, bir haritanın içeriğinin bir anahtar kümesi, değer koleksiyonu veya anahtar / değer eşlemesi kümesi olarak görüntülenmesini sağlayan üç koleksiyon görünümü sağlar . Sipariş Haritanın haritanın toplama görüşlerine yineleyiciler kendi elemanları dönmek sırayla olarak tanımlanır. TreeMap Sınıf gibi bazı harita uygulamaları, siparişleri konusunda belirli garantiler verir; diğerleri, HashMapsınıf gibi değil.

- Harita

Bu bağlantılı liste, normalde anahtarların haritaya yerleştirildiği sıra olan yineleme sırasını tanımlar ( ekleme sırası ).

- LinkedHashMap

Yani, evet, keySet(), values()ve entrySet()sırayla iç bağlantılı liste kullanır dönüş değerleri (üç koleksiyon görünümler söz). Ve evet, JavaDoc için Mapve LinkedHashMapgaranti.

Ne de olsa bu sınıfın amacı budur.


8
harita üzerindeki yineleme, LinkedHashMap kullanılarak HashMap'ten daha hızlı yapılır.
Thierry

2
değerleri () bir koleksiyon döndürür. Liste değil. nasıl düzenli tutuyor?
Dejell

7
@Dejel Collection, hangi değerlerin () döndürdüğü için yalnızca temel sınıftır. İade ettiği Koleksiyonun uygulanması hala tarafından kontrol edilmektedir LinkedHashMap. Bu LinkedHashMapdurumda, LinkedValuesLinkedHashMap.java içinde özel bir sınıf olan bir örneği döndürüyor.
Powerlord

2
Benim durumumda bir LinkedHashMap tuş takımı, haritada gösterilen sırada DEĞİLDİR. Bu çok şaşkın.
Amalgovinus

2
MapBir haritanın sırasını, haritanın koleksiyon görünümlerindeki yineleyicilere açıkça bağlayan belgelere (kaynağından ) bağladığınız (ve bu koleksiyon görünümlerinin ne olduğunu açıkça belirttiğiniz) için teşekkür ederiz . Bu benim için eksik olan parça.
LarsH


6

Set ile karıştırmayın LinkedHashMap.keySet()ve LinkedHashMap.entrySet()geri dönmeyin ve bu nedenle sipariş garantisi olmamalıdır!

Setolan bir arabirim HashSet, TreeSetvb varlıklar olan uygulamaları. HashSetUygulanması Setarayüzünde sipariş garanti etmez. Ama TreeSetöyle. Ayrıca LinkedHashSetyapar.

Bu nedenle , geri dönen Set referansının siparişi garanti edip etmeyeceğini bilmek nasıl Setuygulandığına bağlıdır LinkedHashMap. Kaynak kodundan geçtim, LinkedHashMapşöyle görünüyor:

private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}

Böylece LinkedHashMap / HashMap Setyani ie kendi uygulaması vardır KeySet. Böylece bunu karıştırmayın HashSet.

Ayrıca, elemanların kepçeye nasıl sokulduğuna göre düzen korunur. Bak addEntry(..)yöntemine LinkedHashMapve bu ile karşılaştırmak HashMaphangi arasındaki temel fark vurgular HashMapve LinkedHashMap.


4
Bu cevap kesinlikle faydalı bilgiler sunarken, soruyu gerçekten cevaplamıyor. Temel olarak, tahmin edilebilir yineleme sırasına sahip olabileceklerini söylüyor.
Tuupertunut

5

Bunu kabul edebilirsiniz. Javadoc 'öngörülebilir yineleme düzeni' diyor ve bir harita mevcut tek yineleyiciler olan () anahtar kümesi (), entrySet () ve değerler için olanlar.

Bu nedenle, başka bir yeterlilik bulunmadığında, bu yineleyicilerin tümüne açıkça uygulanması amaçlanmıştır.


0

AFAIK belgelenmediği için "resmen" kabul edemezsiniz. Bununla birlikte, mevcut uygulamanın değişmesi olası değildir.

Siparişi sağlamak istiyorsanız, harita girişleri üzerinde yineleme yapmak ve bunları seçtiğiniz bir sipariş işlevine sahip sıralı bir sete eklemek isteyebilirsiniz, ancak doğal olarak bir performans maliyeti ödersiniz.


Yani inputSet (), keySet () tarafından siparişi garanti eder mi?
user256239

1
@kknight: Emin değilim. javadoc şunu belirtir: "Bu bağlantılı liste, normalde anahtarların haritaya eklenme sırası (ekleme sırası) olan yineleme sırasını tanımlar.". Ancak, JDK için JavaDoc'lar genel olarak çok belirsizdir.
Uri

5
EntrySet () bile yineleme sırasını garanti etmezse, LinkedHashMap ve HashMap arasındaki fark nedir? LinkedHashMap örneğinde öngörülebilir yineleme sırasından nasıl yararlanabiliriz?
user256239

1
Bu kesinlikle bir belgelenmiş. Cevap tamamen yanlış.
Lorne Marquis

-3

Arayüze baktığımızda bir Setdeğil, bir düz döndürür SortedSet. Yani hiçbir garanti yok.

Uygulamaya (her zaman kötü bir fikir) bakarak örtük bir garanti kabul etmeden önce, diğer tüm Java uygulamalarındaki uygulamalara da bakın :)

Örneğin yapıcıda keySet ile bir TreeSet oluşturabilirsiniz.


3
Belgelere daha yakından baktığımızda, gerçekten garantiler var. Birisinin zaten yazdığı gibi, bu sınıfın asıl noktası budur.
glglgl

-4

KeySet () ve değerlerin () sırasını alabileceğinizi sanmıyorum.

Map'de tanımlanan ve HashMap'te geçersiz kılınan bu iki yöntemin sözleşmesine bağlı kaldığım sürece, size sırasız keySet () ve değerleri () döndüren LinkedHashMap uygulamasını kolayca yazabilirim.


6
LinkedHashMapSınıfın tüm amacı , haritayı yinelerken öğelerin sırasını korumaktır ve bu davranış iyi tanımlanmıştır. Temel sınıf belirtimine uymadan bir alt sınıf yazarsanız, çok yanlış bir şey yapıyorsunuz demektir.
18:18
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.