Trước hết, điều này hoàn toàn phụ thuộc vào loại Bản đồ bạn đang sử dụng. Nhưng vì chuỗi JavaRanch nói về HashMap, tôi sẽ cho rằng đó là cách triển khai mà bạn đang đề cập đến. Và hãy giả sử rằng bạn đang nói về việc triển khai API tiêu chuẩn từ Sun / Oracle.
Thứ hai, nếu bạn lo lắng về hiệu suất khi lặp lại bản đồ băm của mình, tôi khuyên bạn nên xem qua LinkedHashMap
. Từ các tài liệu:
Việc lặp lại các chế độ xem bộ sưu tập của một LinkedHashMap yêu cầu thời gian tỷ lệ thuận với kích thước của bản đồ, bất kể dung lượng của nó. Việc lặp lại trên một HashMap có thể sẽ tốn kém hơn, đòi hỏi thời gian tỷ lệ thuận với dung lượng của nó.
HashMap.entrySet ()
Mã nguồn cho việc triển khai này có sẵn. Việc thực hiện về cơ bản chỉ trả về một mới HashMap.EntrySet
. Một lớp trông như thế này:
private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return newEntryIterator();
}
}
và HashIterator
trông giống như
private abstract class HashIterator<E> implements Iterator<E> {
Entry<K,V> next;
int expectedModCount;
int index;
Entry<K,V> current;
HashIterator() {
expectedModCount = modCount;
if (size > 0) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
final Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
return e;
}
}
Vì vậy, bạn có nó ... Đó là mã quy định những gì sẽ xảy ra khi bạn lặp lại một entrySet. Nó đi qua toàn bộ mảng miễn là dung lượng bản đồ.
HashMap.keySet () và .get ()
Ở đây, trước tiên bạn cần nắm được bộ phím. Điều này cần thời gian tỷ lệ thuận với dung lượng của bản đồ (trái ngược với kích thước của LinkedHashMap). Sau khi hoàn tất, bạn gọi get()
một lần cho mỗi phím. Chắc chắn, trong trường hợp trung bình, với việc triển khai Mã băm tốt, điều này cần thời gian liên tục. Tuy nhiên, nó chắc chắn sẽ yêu cầu rất nhiều .hashCode
và .equals
cuộc gọi, điều này rõ ràng sẽ mất nhiều thời gian hơn là chỉ thực hiện một entry.value()
cuộc gọi.