简体   繁体   English

HashMap 方法的时间复杂度

[英]Time Complexity of HashMap methods

Since i'm working around time complexity, i've been searching through the oracle Java class library for the time complexity of some standard methods used on Lists, Maps and Classes.由于我正在研究时间复杂度,因此我一直在 Oracle Java 类库中搜索用于列表、映射和类的一些标准方法的时间复杂度。 (more specifically, ArrayList, HashSet and HashMap) (更具体地说,ArrayList、HashSet 和 HashMap)

Now, when looking at theHashMap javadoc page , they only really speak about the get() and put() methods.现在,当查看HashMap javadoc 页面时,他们只真正谈论get()put()方法。

The methods i still need to know are:我还需要知道的方法是:

remove(Object o)
size()
values()

I think that remove() will be the same complexity as get() , O(1) , assuming we don't have a giant HashMap with equal hashCodes, etc etc...我认为remove()将与get()O(1)具有相同的复杂性,假设我们没有具有相同 hashCodes 等的巨大 HashMap 等等......

For size() i'd also assume O(1) , since a HashSet, which also has no order, has a size() method with complexity O(1) .对于size()我也假设O(1) ,因为一个 HashSet 也没有顺序,有一个size()复杂度为O(1)

The one i have no idea of is values() - I'm not sure whether this method will just somehow "copy" the HashMap, giving a time complexity of O(1) , or if it will have to iterate over the HashMap, making the complexity equal to the amount of elements stored in the HashMap.我不知道的是values() - 我不确定这个方法是否会以某种方式“复制”HashMap,给出O(1)的时间复杂度,或者它是否必须遍历 HashMap,使复杂性等于存储在 HashMap 中的元素数量。

Thanks.谢谢。

The source is often helpful: http://kickjava.com/src/java/util/HashMap.java.htm来源通常很有帮助: http : //kickjava.com/src/java/util/HashMap.java.htm

  • remove: O(1) remove: O(1)
  • size: O(1) size: O(1)
  • values: O(n) (on traversal through iterator) values: O(n)(遍历迭代器)

The code for remove(as in rt.jar for HashMap) is: remove 的代码(如 rt.jar 中的 HashMap)是:

/**
 * Removes and returns the entry associated with the specified key
 * in the HashMap.  Returns null if the HashMap contains no mapping
 * for this key.
 */
final Entry<K,V> removeEntryForKey(Object key) {
    int hash = (key == null) ? 0 : hash(key.hashCode());
    int i = indexFor(hash, table.length);
    Entry<K,V> prev = table[i];
    Entry<K,V> e = prev;

    while (e != null) {
        Entry<K,V> next = e.next;
        Object k;
        if (e.hash == hash &&
            ((k = e.key) == key || (key != null && key.equals(k)))) {
            modCount++;
            size--;
            if (prev == e)
                table[i] = next;
            else
                prev.next = next;
            e.recordRemoval(this);
            return e;
        }
        prev = e;
        e = next;
    }

    return e;
}

Clearly, the worst case is O(n).显然,最坏的情况是 O(n)。

Search: O(1+k/n)搜索:O(1+k/n)
Insert: O(1)插入:O(1)
Delete: O(1+k/n) where k is the no.删除:O(1+k/n) 其中 k 是编号。 of collision elements added to the same LinkedList (k elements had same hashCode)添加到同一个 LinkedList 的碰撞元素(k 个元素具有相同的 hashCode)

Insertion is O(1) because you add the element right at the head of LinkedList.插入是 O(1),因为您将元素添加到 LinkedList 的头部。

Amortized Time complexities are close to O(1) given a good hashFunction.给定一个好的 hashFunction,摊销时间复杂度接近 O(1)。 If you are too concerned about lookup time then try resolving the collisions using a BinarySearchTree instead of Default implementation of java ie LinkedList如果您太在意查找时间,请尝试使用 BinarySearchTree 而不是 Java 的默认实现(即 LinkedList)来解决冲突

You can always take a look on the source code and check it yourself.您可以随时查看源代码并自行检查。
Anyway... I once checked the source code and what I remember is that there is a variable named size that always hold the number of items in the HashMap so size() is O(1) .无论如何...我曾经检查过源代码,我记得有一个名为size的变量,它始终保存HashMap的项目数,因此size()O(1)

Just want to add a comment regarding to the above comment claimed worst case scenario that HashMap may go to O(n) in deletion & search, that will never happen as we are talking about Java HashMap implementation.只想添加有关上述评论的评论,声称最坏的情况是 HashMap 在删除和搜索中可能会达到 O(n),这在我们谈论 Java HashMap 实现时永远不会发生。

for a limited number (below 64 of entries), the hashMap is backed up by array, so with a unfortunate enough case, but still very unlikely, it is linear, but asymptotically speaking, we should say in worse case, HahsMap O(logN)对于有限数量(低于 64 个条目),hashMap 由数组备份,因此在足够不幸的情况下,但仍然不太可能,它是线性的,但渐近地说,我们应该说在更坏的情况下,HahsMap O(logN )

On an average the time complexity of a HashMap insertion, deletion, the search takes O(1) constant time.平均而言,HashMap 插入、删除、搜索的时间复杂度为O(1)常数时间。

That said, in the worst case, java takes O(n) time for searching, insertion, and deletion.也就是说,在最坏的情况下,java 需要O(n)时间来进行搜索、插入和删除。

Mind you, the time complexity of HashMap apparently depends on the loadfactor n/b ( the number of entries present in the hash table BY the total number of buckets in the hashtable ) and how efficiently the hash function maps each insert.请注意,HashMap 的时间复杂度显然取决于负载因子n/b哈希表中存在的条目数乘以哈希表中的桶总数)以及哈希函数映射每个插入的效率。 By efficient I mean, a hash function might map two very different objects to the same bucket ( this is called a collision ) in case.我的意思是,哈希函数可能将两个非常不同的对象映射到同一个存储桶(这称为碰撞)以防万一。 There are various methods of solving collisions known as collision resolution technique such as有多种解决冲突的方法,称为冲突解决技术,例如

  • Using a better hashing function使用更好的散列函数
  • Open addressing开放寻址
  • Chaining etc链接等

Java uses chaining and rehashing to handle collisions. Java 使用链接重新散列来处理冲突。

Chaining Drawbacks In the worst case, deletion and searching would take operation O(n) .链接缺点在最坏的情况下,删除和搜索将执行O(n) As it might happen all objects are mapped to a particular bucket, which eventually grows to the O(n) chain.可能会发生所有对象都映射到特定存储桶的情况,该存储桶最终会增长到O(n)链。

Rehashing Drawbacks Java uses an efficient load factor (n/b) of 0.75 as a rehashing limit ( to my knowledge chaining apparently requires lookup operations on average O(1+(n/b)) . If n/b < 0.99 with rehashing is used, it is constant time ).重新散列的缺点Java 使用0.75的有效负载因子(n/b)作为重新散列限制(据我所知,链接显然需要平均O(1+(n/b))查找操作。如果n/b < 0.99 与重新散列是使用,它是恒定的时间)。 Rehashing goes off-hand when the table is massive, and in this case, if we use it for real-time applications, response time could be problematic.当表很大时,重新散列会变得多余,在这种情况下,如果我们将它用于实时应用程序,响应时间可能会出现问题。

In the worst case, then, Java HashMap takes O(n) time to search, insert, and delete.在最坏的情况下,Java HashMap 需要O(n)时间来搜索、插入和删除。

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

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