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?
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?
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.
TreeMapSı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ı ).
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.
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.
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.
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!
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.
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 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.
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.
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.
values()sıra sırakeySet(), ben genişlettik soru şu eklemeyi. Bu, bunun kopyaları olarak daha fazla sorunun kapatılabileceği anlamına gelir.