简体   繁体   English

HashSet迭代

[英]HashSet iteration

I have a query regarding iterator of HashSet in Java. 我有一个关于Java中HashSet迭代器的查询。 In book "Java Generics and Collections", following is stated: 在“ Java泛型和集合”一书中指出:

The chief attraction of a hash table implementation for sets is the (ideally) constanttime performance for the basic operations of add, remove, contains, and size. 集的哈希表实现的主要吸引力在于添加,删除,包含和大小的基本操作的(理想)恒定时间性能。 Its main disadvantage is its iteration performance; 它的主要缺点是迭代性能。 since iterating through the table involves examining every bucket, its cost is proportional to the table size regardless of the size of the set it contains. 由于遍历表涉及检查每个存储桶,因此其成本与表的大小成正比,而与它包含的集合的大小无关。

It states that iterator looks in every bucket of underlying table. 它指出迭代器在基础表的每个存储桶中查找。 But going through actual implementation(JDK 8), I see that HashIterator stores next node reference. 但是通过实际实现(JDK 8),我看到HashIterator存储了下一个节点引用。 So it seems iterator doesn't need to visit every single bucket. 因此,似乎迭代器不需要访问每个存储桶。

Is book wrong here OR my understanding is wrong? 这里的书错了还是我的理解错了?

The document is right. 该文件是正确的。 Although KeyIterator indeed calls nextNode().key , like this 虽然KeyIterator确实会调用nextNode().key ,像这样

final class KeyIterator extends HashIterator implements Iterator<K> {
    public final K More ...next() {
        return nextNode().key;
    }
}

the code for nextNode() in the base class HashIterator has the loop that the documentation is talking about: 基类HashIterator nextNode()的代码具有文档所讨论的循环:

final Node<K,V> nextNode() {
    Node<K,V>[] t;
    Node<K,V> e = next;
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    if (e == null)
        throw new NoSuchElementException();
    if ((next = (current = e).next) == null && (t = table) != null) {
        do {} while (index < t.length && (next = t[index++]) == null);
    }
    return e;
}

The do / while loop with an empty body traverses the buckets one by one, looking for the next entry. 空主体的do / while循环逐个遍历各个存储桶,以查找下一个条目。

The only time this may be relevant is when you iterate over a hash set which you pre-allocated with a large number of buckets, but have not populated with a large number of items yet. 唯一可能与此相关的时间是当您遍历散列集时,该散列集已预先分配有大量存储桶,但尚未填充大量项目。 When you let your HashSet grow by itself as you add more items, the number of buckets will be proportional to the number of items that you inserted so far, so the slowdown would not be significant. 当您添加更多项目时让HashSet自身增长时,存储桶的数量将与您到目前为止插入的项目数量成正比,因此速度下降不会很明显。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM