Tôi có một Bản đồ.TreeMap iterator.remove() sửa đổi Mục nhập cuối cùng
Map<Integer,String> map = ...
bản đồ có n yếu tố (cho phép lấy ví dụ này, những 9)
map.put(1,"one");
map.put(2,"two");
map.put(3,"three");
map.put(4,"four");
map.put(5,"five");
map.put(6,"six");
map.put(7,"seven");
map.put(8,"eigth");
map.put(9,"nine");
Bây giờ tôi muốn để lặp qua bản đồ này, và loại bỏ các yếu tố n-th sử dụng iterator.
private void remove(int num, final Map<Integer, String> map) {
Iterator<Map.Entry<Integer,String>> it = map.entrySet().iterator();
Map.Entry<Integer,String> entry;
while(it.hasNext()){
entry = it.next();
if(Integer.valueOf(num).equals(entry.getKey())){
it.remove();
System.out.println(entry.getValue());
// vs
// System.out.println(entry.getValue());
// it.remove();
}
}
}
Từ javadoc, tôi giả sử, ngữ nghĩa của loại bỏ được xác định rõ.
Nhưng tùy thuộc vào việc thực hiện bản đồ - ví dụ: HashMap vs TreeMap có sự khác biệt liệu it.remove()
được thực hiện trước khi hoặc sauentry.getValue()
.
cho HashMaps map = new HashMap<>()
hành vi này là
...
remove(4, map); //output: four
//or
remove(5, map); //output: five
cho TreeMap map = new TreeMap<>()
hành vi này là cùng, khi tôi loại bỏ các mục hiện tại từ iterator sau Tôi đã truy cập nó:
System.out.println(entry.getValue());
it.remove();
kết quả trong
remove(4, map); //output: four
//or
remove(5, map); //output: five
cho đến nay rất tốt, nhưng nếu tôi loại bỏ các yếu tố trước tôi truy cập vào các mục:
it.remove();
System.out.println(entry.getValue());
Đầu ra là bất ngờ
remove(4, map); //output: five !!!
//or
remove(5, map); //output: five ok
Rõ ràng, it.remove()
của TreeMap
đổi các Entries
, bởi vì TreeMap
được tạo thành từ Entries
và trình vòng lặp thực sự trả về các phần tử thực tế của bản đồ. Và tùy thuộc vào vị trí hiện tại trong cây, các tham chiếu bên trong của điểm nhập vào phần tử tiếp theo hoặc phần tử hiện tại (đã loại bỏ).
Nhưng tôi không chắc liệu đây có phải là lỗi hay không hoặc nếu điều này là cố ý. Nếu trường hợp sau là trường hợp, tôi tự hỏi về lý do đằng sau?
Edit: Source code của TreeMap iterator.remove()
Tôi không nhận được hành vi bạn mô tả trong bản đồ ... bạn sử dụng phiên bản Java nào? Điều gì sẽ xảy ra nếu bạn xuất giá trị của mục nhập cả trước và sau khi xóa()? – daniu
jdk1.8.0_121 ... nó có thể tái sản xuất với TreeMap chỉ với 3 mục (1,2,3), loại bỏ phần tử ở giữa (2). Nhưng nó không hiển thị trong HashMap –
in nó ra trước và sau khi kết quả trong "hai, ba" –