2011-09-27 36 views
11

Tôi có đoạn code sau nhưng tôi thấy rằng lấy các giá trị từ một bản đồ trong khi iterating trên các phím Map với keySet() là một sai lầm ngay cả với FindBugs tôi nhận được cảnh báo WMI_WRONG_MAP_ITERATORmap.get Tránh (key) phương pháp

for(String elementId : mapElements.keySet()){ 

    element = mapElements.get(elementId); 

    doSomething(element); 
} 

vậy tại sao chính xác điều này là không tốt và làm thế nào tôi có thể sửa chữa nó?

Cảm ơn.

+4

Điều này tất nhiên được giải thích trong tài liệu (http://findbugs.sourceforge.net/bugDescriptions.html#WMI_WRONG_MAP_ITERATOR) –

Trả lời

23

Nếu bạn đang iterating trên mọi thứ trong một bản đồ, bạn cũng có thể làm:

for (Map.Entry<String, String> entry : mapElements.entrySet()) { 
    String key = entry.getKey(); 
    String value = entry.getValue(); 
    // Use the key and the value 
} 

Hoặc nếu bạn không thực sự cần chìa khóa, chỉ cần lặp qua các giá trị:

for (String value : mapElements.values()) { 
    doSomething(value); 
} 

EDIT: cú pháp

0

Lấy giá trị từ một bản đồ trong khi iterating trên bản đồ tự nó không phải là một vấn đề - những gì sẽ trở thành một vấn đề là khi bạn đang modiy ing bản đồ trong khi đồng thời lặp qua nó. Trong trường hợp của bạn, điều này dường như không phải là trường hợp, vì vậy đây là bản thân nó không nguy hiểm.

Khi bạn lặp qua bản đồ, trình lặp mà bạn nhận được dựa trên ảnh chụp nhanh của tất cả các mục bản đồ tại thời điểm bạn có trình lặp. Sau khi trung hòa tiếp theo, hành vi của trình lặp này trở nên không xác định. Đây là những gì không tốt. Nhưng một lần nữa, trong trường hợp của bạn, điều này không áp dụng bởi vì bạn không cập nhật bản đồ.

0

Một điểm khác là tìm kiếm giá trị của mỗi khóa có thể tốn kém nếu bản đồ lớn. Vì vậy, đề xuất của Jon Skeet hiệu quả hơn. Tuy nhiên, tôi thừa nhận mã để lặp qua bộ mục nhập của bản đồ là một chút vụng về.

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