2010-07-01 42 views
7

Trong Python, bạn có thể có, các cặp giá trị quan trọng trong một cuốn từ điển nơi bạn có thể vòng qua chúng, như hình dưới đây:Vòng lặp Java HashMap như Từ điển Python?

for k,v in d.iteritems(): 
    print k,v 

Có cách nào để làm điều này với Java HashMaps?

Trả lời

20

Có - ví dụ:

Map<String, String> map = new HashMap<String, String>(); 
// add entries to the map here 

for (Map.Entry<String, String> entry : map.entrySet()) { 
    String k = entry.getKey(); 
    String v = entry.getValue(); 
    System.out.printf("%s %s\n", k, v); 
} 
+8

So sánh điều này với phiên bản Python nhắc tôi tại sao tôi đã từ bỏ Java năm trước. –

6

Các HashMap.entrySet() sẽ trở lại đậu các cặp giá trị key giống với dictionary.iteritems(). Sau đó bạn có thể lặp qua chúng.

Tôi nghĩ là điều gần nhất với phiên bản Python.

3
Set<Map.Entry> set = d.entrySet(); 
for(Map.Entry i : set){ 
    System.out.println(i.getKey().toString() + i.getValue().toString); 
} 

Something như thế ...

1

Trong Java, bạn có thể làm tương tự như sau.

HashMap<String, String> h = new HashMap<String, String>(); 
    h.put("1","one"); 
    h.put("2","two"); 
    h.put("3","three"); 

    for(String key:h.keySet()){ 
     System.out.println("Key: "+ key + " Value: " + h.get(key)); 
    } 
+0

Tại sao lại là downvote? – bragboy

+0

Tôi đã không làm điều này, nhưng cách tiếp cận này kém hiệu quả hơn so với việc lặp lại trên mục nhập. 'Get()' có thêm chi phí cho mỗi lần lặp lại. Ít nhất không phải là cách "đúng" để lặp qua bản đồ. Tôi có thể tưởng tượng rằng một downvoted vì điều đó, làm thế nào tốt ý định của bạn cũng được. – BalusC

+2

@BalusC - vâng, nhưng việc tạo trình lặp MapEntrySet là (rất có thể) đắt hơn sau đó tạo một bộ lặp ... Tôi nghi ngờ, đó là một vấn đề hiệu suất, và ngay cả khi điều này kém hiệu quả hơn, tôi sẽ không bao giờ ** cố gắng khắc phục các vấn đề hiệu suất bằng cách * tối ưu hóa * cho các vòng như thế này. (+1 từ tôi, BTW). –

6

Như đã trình bày trong các câu trả lời, về cơ bản có hai cách để lặp qua một Map (hãy giả sử Map<String, String> trong những ví dụ).

  1. lặp trên Map#entrySet():

    for (Entry<String, String> entry : map.entrySet()) { 
        System.out.println(entry.getKey() + "=" + entry.getValue()); 
    } 
    
  2. lặp trên Map#keySet() và sau đó sử dụng Map#get() để có được giá trị cho tất cả các chìa khóa:

    for (String key : map.keySet()) { 
        System.out.println(key + "=" + map.get(key)); 
    } 
    

Điều thứ hai là có thể nhiều hơn có thể đọc được, nhưng nó có chi phí hiệu suất của việc gọi không cần thiết get() trên mọi lần lặp lại. Người ta có thể lập luận rằng việc tạo trình vòng lặp keyset ít tốn kém hơn vì nó không cần tính đến các giá trị. Nhưng hãy tin hay không, số keySet().iterator() sẽ tạo và sử dụng cùng một lần lặp làm entrySet().iterator(). Sự khác biệt duy nhất là trong trường hợp của keySet(), cuộc gọi next() của trình vòng lặp trả về it.next().getKey() thay vì it.next().

Các AbstractMap#keySet()'s javadoc chứng minh điều này:

phương pháp lặp của lớp con trả về một "đối tượng wrapper" trên entrySet() iterator của bản đồ này.

Mã nguồn AbstractMap cũng chứng minh điều này. Dưới đây là một trích keySet() phương pháp (ở đâu đó xung quanh dòng 300 trong Java 1.6):

public Iterator<K> iterator() { 
    return new Iterator<K>() { 
     private Iterator<Entry<K,V>> i = entrySet().iterator(); // <----- 

     public boolean hasNext() { 
      return i.hasNext(); 
     } 

     public K next() { 
      return i.next().getKey(); // <----- 
     } 

     public void remove() { 
      i.remove(); 
     } 
    }; 
} 

Lưu ý rằng khả năng đọc nên được ưa thích hơn tối ưu hóa quá sớm, nhưng điều quan trọng là phải có này trong tâm trí.

Các vấn đề liên quan