2017-07-24 53 views
5

Değerin null olduğu tüm girdileri kaldırmaya çalışıyorum. kodudur:Map.vaules üzerindeki yineleyici HashMap # Girişini kaldırmak için neden kullanılabilir?

sorum iterator map.values bağlanan edilir
Map<String, String> map = new HashMap<>(); 
map.put("one", null); 
map.put("two", null); 
map.put("three", "THREE"); 

Iterator iterator = map.values().iterator(); 
while (iterator.hasNext()) 
{ 
    if (iterator.next() == null) { 
     iterator.remove(); 
    } 
} 

for (Map.Entry<String, String> e : map.entrySet()) { 
    System.out.println(e.getKey() + ":" + e.getValue()); 
} 

, neden bütün girdiyi kaldırabilirim?

+0

Sadece onaylamak için kodunuz çalışıyor ancak nedenini anlamaya çalışıyorsunuz. Doğru? – shmosel

+0

Evet. Kök sebebini bulmaya çalışıyorum. – caisil

cevap

8

mümkündür. Resmi Java-Doc of Map#values itibaren

:

bu haritada yer alan değerlerin bir koleksiyonu görünümünü verir. Koleksiyon harita tarafından desteklenir, bu nedenle haritaya yapılan değişiklikler koleksiyona yansıtılır ve bunun tersi de geçerlidir. [...] Koleksiyon Iterator.remove, Collection.remove, removeAll, retainAll ve işlemleri temizle, haritadan karşılık gelen eşleme kaldırır eleman kaldırma destekler. Ekleme veya addAll işlemlerini desteklemiyor. En harita uygulamaları uzandığı AbstractMap sınıf, ek bir alan transient volatile Collection<V> values vardır ve o oraya olacak tam olarak ne olduğunu


Not. Gördüğünüz gibi, koleksiyon harita tarafından dahili olarak kullanılıyor ve bundan dolayı da haritada değişiyor. Ayrıca bakınız: Source code of AbstractMap


Eğer ayrıntılı olarak gitmek kaynak kodunda AbstractMap#values yöntemle bakmak istiyorsanız. Orada orijinal harita üzerinde çalışan bir sarıcı olarak değerleri-topluluğunu oluştururlar. Örneğin, next yöntemi, Haritanın Entry<K, V> girişlerini yineler ancak yalnızca değerlerini Entry#getValue vb. Ile döndürür.
Ayrıca, görebildiğiniz gibi remove yöntemi, Entry<K, V> yineleyicisine iletilir, böylece çıkartma sonunda orijinal harita üzerinde tekrar yürütülür.

2

açıklamalar zabuza tarafından verilen, ancak öğeleri kaldırmak için uygun bir yolu yoktur, çünkü ben yazıyorum edilmiştir:


kullanabilirsiniz boş değere sahip Entry kaldırmak için Streams:

map = map.entrySet() 
     .stream() 
     .filter(entry -> entry.getValue()!=null) 
     .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue)); 

veya tek satırlık: map.entrySet().removeIf(e -> e.getValue()==null);

Veya : Map#values harita tarafından desteklenen olan değerlerin bir görünüm verir çünkü map.values().removeIf(v -> v == null)

+1

Veya 'map.values ​​(). RemoveIf (v -> v == null)'. Ama sanırım sorunun cevabını kaçırdın. – shmosel

+0

@shmosel evet Ben sadece "Collection.removeIf" kodundan ^^ – azro

+0

@azo @shmosel, fark, ben aslında 'removeIf' yöntemi benim örnek kodda kullanılan yöntem ile aynı olduğunu düşünüyorum, her ikisi de 'yineleyici' dayanmaktadır . – caisil