2016-01-25 20 views
5

Belirli bir tip Map için, keySet, values ve entries yöntemlerinin döndürdüğü Toplama görünümleri üzerinde yineleme yöntemlerinin aynı sırayla yinelenen herhangi bir garantisi var mı?Belirli bir Haritanın farklı Koleksiyon görünümleri boyunca yineleme sırası tutarlı mı?

Arka plan: Ben

public static void doSomethingForEachEntry(Map<String, Integer> someMap) { 

    for (String key : someMap.keySet()) { 
     doSomething(someMap.get(key)); 
    }  
} 

public static void doSomethingForEachEntry(Map<String, Integer> someMap) { 

    for (Integer value : someMap.values()) { 
     doSomething(value); 
    }  
} 

için değişmeden iterasyon düzeni sağlamak için garanti edilir dönüştüren olup olmadığını merak ediyorum.

+0

Başlıktaki soru görünür ve yayınınızda aynı değildir. Tam olarak neyi bilmek istiyorsun? Anahtarların iade edilmesi, değerlerin sıralanmasıyla aynı mı?Ya da ikinci aramadaki sipariş ilk aramayla aynı mı olacak? – Tunaki

+1

Yineleme sırasına güvenmemelisiniz (TreeMap gibi bazı düzenli Haritaları kullanmıyorsanız). Örneğin, bir HashMap kullanıyorsanız, Haritanın mevcut durumu için olsa bile, her ikisi de() 've' keySet() 'aynı yineleme sırasını verir, HashMap'e eleman ekledikten sonra sipariş değişebilir. – Eran

+0

@Tunaki Benim sorularım, kod snippet'lerinin her ikisinin de aynı sırayla değerleri işleyeceği anlamında, değerlerin sırasına göre tuşların sıralanması ile aynı olacaktır. – Hulk

cevap

7

Eğer güvenemez doğru olmakla birlikte Map uygulama açıkça tanımlamadıkça, harita ve tüm toplama görünümleri için tek bir paylaşılan sipariş yoktur ima cümle in the API documentation var emreden bir özel:

bir harita ait sipariş haritanın toplama görüşlerine yineleyiciler kendi elemanları dönmek sırayla olarak tanımlanır.

(vurgu bana ait)

bu tatmin olması için bir harita (o belirtilemez bile, ve harita değiştirilir olarak değişebilir) doğal bir düzen vardır ve tüm koleksiyon görünümleri gerekir bu sıraya karşılık gelir. Bunun bir garanti teşkil edip etmediği ve özellikle de tüm üçüncü taraf harita uygulamalarının bunu onaylamasının bir başka sorun olduğu. Eğer keySet gelen bir öğe kaldırırsanız

Bu açıkça harita ile desteklenmektedir görünümleri olarak Map arabirimde tanımlanan belirtmekte değer, (örneğin karşılık gelen Map giriş zorunluluk kaldırılacak harita). Bu, gerçekte, doğru bir Map uygulamasından farklı siparişler alacağınızın, örneğin, koleksiyon görünümlerinin sığ kopyalarını oluşturduğunuzdan daha düşük olması anlamına gelir.

Tüm bunları söyledikten sonra, eğer soru "bu güvenli bir refaktör mü?" o zaman cevap "evet, orijinal kodun kendisi bozuk olduğu sürece" dir. Yöntem belirli bir sıralamaya ve bu nedenle belirli bir Map uygulamasına dayanıyorsa, yöntem yalnızca bu tür Map türünü kabul edecek şekilde bildirilmelidir. Aksi halde, altta yatan Map uygulamasının satırdan aşağı inmesi durumunda potansiyel bir timebomb'iniz vardır (ve bir JDK güncellemesinden dolayı gerçek hayatta yazılımın koptuğunu gördüm). O zaman bunun bir sipariş Map uygulanmasını geçen biliyor çünkü belirli bir arayan belirli sipariş güvenmek durumunda

, ne ala ve bu siparişi, Refactor sonra korunacaktır.

+1

İyi puanlar. Ve henüz herhangi bir karşı örnek bulamadım. CodeBase'imde kullanılan tüm Map'-Types türleri için testler ekledim, ancak bu dönüşümün (statik analiz araçlarının önerdiği ve büyük olasılıkla hem okunabilirliği hem de performansı artıracağı) güvenli olup olmayacağını bilmek iyi olacaktır. – Hulk

+0

@Hulk, "güvende olmayı garantiledi" sorusu üzerine bazı sözler ekledi - zaten farkında olmadığınız bir şey yok, ama yine de – CupawnTae

+0

diyerek değerinde daha fazla araştırma yaptıktan sonra, kabul ediyorum. [SortedMaps] için (https://docs.oracle.com/javase/8/docs/api/java/util/SortedMap.html) ek teminat da vardır. * Daha fazla anahtar içeren bir harita. Harita, anahtarlarının doğal düzenine göre veya sıralanan harita oluşturma zamanında sağlanan bir Karşılaştırıcı tarafından sipariş edilir. ** Sıralanan haritanın koleksiyon görünümleri (entrySet, keySet ve değerler yöntemleri tarafından döndürülen) üzerinde yinelendiğinde bu sıra yansıtılır. **. Siparişten yararlanmak için birkaç ek işlem sağlanmıştır. * – Hulk

0

Yineleme sırası kullandığınız Haritanın özel uygulamasına bağlıdır. Harita türünü biliyorsanız, belgelere bakın. Eğer yapmazsanız, herhangi bir yineleme emrine güvenmeyin.