LinkedHashMap
Tahmin edilebilir bir yineleme sırası (ekleme sırası) olduğunu biliyorum . Does Set
tarafından döndürülen LinkedHashMap.keySet()
ve Collection
döndürdüğü LinkedHashMap.values()
de bu düzeni korumak?
LinkedHashMap
Tahmin edilebilir bir yineleme sırası (ekleme sırası) olduğunu biliyorum . Does Set
tarafından döndürülen LinkedHashMap.keySet()
ve Collection
döndürdüğü LinkedHashMap.values()
de bu düzeni korumak?
Yanıtlar:
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,HashMap
sı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ı ).
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 Map
ve LinkedHashMap
garanti.
Ne de olsa bu sınıfın amacı budur.
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 LinkedHashMap
durumda, LinkedValues
LinkedHashMap.java içinde özel bir sınıf olan bir örneği döndürüyor.
Map
Bir 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.
Kaynağa bakıldığında, öyle görünüyor. keySet()
, values()
ve entrySet()
hepsi dahili olarak aynı giriş yineleyiciyi kullanır.
Set ile karıştırmayın LinkedHashMap.keySet()
ve LinkedHashMap.entrySet()
geri dönmeyin ve bu nedenle sipariş garantisi olmamalıdır!
Set
olan bir arabirim HashSet
, TreeSet
vb varlıklar olan uygulamaları. HashSet
Uygulanması Set
arayüzünde sipariş garanti etmez. Ama TreeSet
öyle. Ayrıca LinkedHashSet
yapar.
Bu nedenle , geri dönen Set referansının siparişi garanti edip etmeyeceğini bilmek nasıl Set
uygulandığı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 Set
yani 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 LinkedHashMap
ve bu ile karşılaştırmak HashMap
hangi arasındaki temel fark vurgular HashMap
ve LinkedHashMap
.
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.
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.
Arayüze baktığımızda bir Set
değ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.
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.
LinkedHashMap
Sı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.
values()
sıra sırakeySet()
, ben genişlettik soru şu eklemeyi. Bu, bunun kopyaları olarak daha fazla sorunun kapatılabileceği anlamına gelir.