34

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. (more specifically, ArrayList, HashSet and HashMap)

Now, when looking at the HashMap javadoc page, they only really speak about the get() and put() methods.

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...

For size() i'd also assume O(1), since a HashSet, which also has no order, has a size() method with complexity 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.

Thanks.

3
  • 1
    Btw how could values() give O(1) if it even if it just somehow "copy" the HashMap ? Commented Nov 10, 2011 at 11:09
  • by the way, your link is broken Commented Jun 10, 2015 at 9:53
  • Could you please mention the exact complexity (average or worst) you are looking for in your question ? The complexity of remove() will be different accordingly, as rightly pointed by @JavaGuy Commented Oct 6, 2015 at 10:35

6 Answers 6

41

The source is often helpful: http://kickjava.com/src/java/util/HashMap.java.htm

  • remove: O(1)
  • size: O(1)
  • values: O(n) (on traversal through iterator)
Sign up to request clarification or add additional context in comments.

3 Comments

remove has amortized complexity O(1+a), where a depends on how many items are in the slot for the hash key of the removed object
@Hengameh a - is a load factor. A load factor is a ratio between a number of elements and the number of slots the hash map has. Please refer to Introduction to Algorithms 11.2 Hash Tables for more detailed explanation.
On an average, the time complexity of a HashMap insertion, deletion, and the search takes O(1) constant time in java, which depends on the loadfactor (number of entries present in the hash table BY total number of buckets in the hashtable ) and mapping of the hash function. That is why simple searching could take O(n) time in the worst case. See my complete response @, stackoverflow.com/a/62965423/6723451
5

The code for remove(as in rt.jar for HashMap) is:

/**
 * 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).

3 Comments

While technically true, this answer could be misleading for some. This code is only O(n) if all of the keys in the HashMap have the same hashCode, which is unlikely and/or a bug. I think Tim's comment is the better truth.
Agree with @HawkeyeParker, but the point is still valid: runtime = worst case = linear. Again, this is unlikely and purely theoretical, but in the way we define efficiency of algorithms, the answer must be linear because there exists one possibility where O(n) is true.
Is that the case for all methods, that we need to report the big-o, average big-o, and amortized big-o separately? Big-o is O(n) (case when all the keys have the same hash), but average O(1).
3

Search: O(1+k/n)
Insert: O(1)
Delete: O(1+k/n) where k is the no. of collision elements added to the same LinkedList (k elements had same hashCode)

Insertion is O(1) because you add the element right at the head of LinkedList.

Amortized Time complexities are close to O(1) given a good hashFunction. If you are too concerned about lookup time then try resolving the collisions using a BinarySearchTree instead of Default implementation of java i.e LinkedList

2 Comments

"Insertion is O(1) because you add the element right at the head of LinkedList." It still has to go through the list to check if that element already exists by comparing the key along with hash (Ref - source code).
better to use lookup, put, and remove :)
3

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.

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)

Comments

1

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).

1 Comment

I'm new to Java so i have no idea about source codes, but i'll give it a try. Thanks!
1

On an average the time complexity of a HashMap insertion, deletion, the search takes O(1) constant time.

That said, in the worst case, java takes O(n) time for searching, insertion, and deletion.

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. 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 e.t.c

Java uses chaining and rehashing to handle collisions.

Chaining Drawbacks In the worst case, deletion and searching would take operation O(n). As it might happen all objects are mapped to a particular bucket, which eventually grows to the O(n) chain.

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). 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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.