2012-01-05 12 views
7

Tôi đã tìm kiếm sự khác biệt giữa hai lớp và điểm này xuất hiện trong rất nhiều câu trả lời với blog này là nguồn: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.htmlĐiều gì làm bạn có ý nghĩa chính xác bởi trình lặp của HashMap là không nhanh và điều tra của HashTable không?

Tuy nhiên tôi không hoàn toàn hiểu. Ai đó có thể xây dựng điều này? Có lẽ với một ví dụ?

Cảm ơn bạn đã tìm kiếm!

Trả lời

12

Lỗi nhanh có nghĩa là khi bạn cố gắng sửa đổi nội dung khi bạn đang lặp lại thông qua nó, nó sẽ thất bại và ném ConcurrentModificationException.

Set keys = hashMap.keySet(); 
for (Object key : keys) { 
    hashMap.put(someObject, someValue); //it will throw the ConcurrentModificationException here 
} 

Đối HashTable liệt kê:

Enumeration keys = hashTable.keys(); 
while (keys.hasMoreElements()) { 
      hashTable.put(someKey, someValue); //this is ok 
    } 
+3

Các iterator của Hastable là không nhanh. Enumerations của nó không. –

+0

Bạn đã đúng! Cảm ơn! – evanwong

3

Khi gọi iterator.next(), nếu có bất kỳ sửa đổi nào được thực hiện giữa thời điểm trình tạo vòng lặp được tạo và thời điểm next() được gọi, một ConcurrentModificationException ngay lập tức được ném. Đây là những gì không nhanh chóng có nghĩa là.

Các liệt kê được trả về bởi Hashtable không có hành vi này. Họ cho rằng bạn biết những gì bạn đang làm, và hành vi của họ, AFAIK, là không xác định nếu bạn sửa đổi bản đồ trong khi lặp qua nó bằng cách sử dụng một trong các liệt kê của nó.

3

Cách tốt nhất là có thể xem xét nguồn cho mỗi lớp như được triển khai bằng cách thực hiện JDK mở cho mỗi lớp; theo cách đó, bạn có thể nhận được câu trả lời ngay từ miệng ngựa, vì nó là :-)

Điều đó về cơ bản, "không nhanh" theo nghĩa này có nghĩa là một Iterator trên HashMap sẽ ném một ngoại lệ nếu nó phát hiện rằng một luồng khác đã sửa đổi HashMap được nhắm mục tiêu - nếu bạn tìm trong nguồn cho HashMap, bạn sẽ thấy điều này được thực hiện bằng cách chỉ cần kiểm tra một bộ đếm cho số sửa đổi dự kiến. Nếu số lượng sửa đổi khác với Iterator được mong đợi, điều đó có nghĩa là một người khác đã đến kể từ lần kiểm tra cuối cùng và làm rối tung xung quanh với HashMap, và vì vậy Iterator ném một số ConcurrentModificationException.

Iterator "không nhanh" không gặp khó khăn khi kiểm tra, và vui vẻ đi theo kinh doanh của nó trong cấu trúc dữ liệu cơ bản. Vì vậy, bạn có được một số tính linh hoạt (có thể là sự linh hoạt đáng ngờ trong trường hợp này) để đổi lấy việc có thể chạy vào các lỗi sau này; tức là cố truy cập một giá trị không còn tồn tại nữa.

Giống như tất cả các chiến lược fail-fast, ý tưởng là lỗi trước đó được phát hiện, việc khôi phục hoặc gỡ lỗi trở nên dễ dàng hơn.

+3

Không chỉ là một chủ đề. Nếu bạn sửa đổi bản đồ trong khi lặp qua nó, ngay cả trong cùng một luồng, một ConcurrentModification được ném (trừ khi bạn sử dụng bản thân trình vòng lặp để sửa đổi bản đồ) –

+0

Rất đúng! Một đôi khi nhầm lẫn sai lầm tôi đã làm bản thân mình :-) –

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