Is HashMap internally implemented in Java using LinkedList or Array? - Stack Overflow
Java Hashmap - Please explain how hash maps work - Stack Overflow
MOOC Part 12: Creating your own implementation of a HashMap
i wanna implement a hash map without importing it from the standard java library
It basically looks like this:
this is the main array
↓
[Entry] → Entry → Entry ← here is the linked-list
[Entry]
[Entry] → Entry
[Entry]
[null ]
[null ]
So you have the main array where each index corresponds to some hash value (mod'ed* to the size of the array).
Then each of them will point to the next entry with the same hash value (again mod'ed*). This is where the linked-list comes in.
*: As a technical note, it's first hashed with a different function before being mod'ed, but, as a basic implementation, just modding will work.
Each HashMap has an Array and in that Array it places each Entry in a position according to its key's hash code (e.g. int position = entry.getKey().hashCode() % array.length). The position where an Entry is stored is called a bucket.
If more than one Entry ends up in the same bucket, those Entries are combined in a LinkedList (also see @Dukeling's answer). Thus the bucket metaphor: each Array index is a "bucket" where you dump in all matching keys.
You have to use an Array for the buckets in order to achieve the desired constant time performance for random access. Within a bucket you have to traverse all elements to find the desired key anyways, so you can use a LinkedList as it is easier to append to (no resize needed).
This also shows the need for a good hash function, because if all keys hash to only a few values you will get long LinkedLists to search and a lot of (fast to access) empty buckets.
You're confusing the behaviour of a Map with the implementation of a HashMap.
In a Map, there is only one value for a key -- if you put a new value for the same key, the old value will be replaced.
HashMaps are implemented using 'buckets' -- an array of cells of finite size, indexed by the hashCode of the key.
It's possible for two different keys to hash to the same bucket, a 'hash collision'. In case of a collision, one solution is to put the (key, value) pairs into a list, which is searched when getting a value from that bucket. This list is part of the internal implementation of the HashMap and is not visible to the user of the HashMap.
This is probably what you are thinking of.
Your basic understanding is correct: maps in general and hashmaps in particular only support one value per key. That value could be a list but that's something different. put("a", 2) will replace any value for key "a" that's already in the list.
So what are you missing?
Every explanation says that in case there is more than a single value per key, the values are being linked listed to the bucket.
Yes, that's basically the case (unless the list is replaced by a tree for efficiency reasons but let's ignore that here).
This is not about putting values for the same key into a list, however, but for the same bucket. Since keys could be mapped to the same bucket due to their hash code you'd need to handle that "collision".
Example:
Key "A" has a hash code of 65, key "P" has a hash code of 81 (assuming hashCode() just returns the ascii codes).
Let's assume our hashmap currently has 16 buckets. So when I put "A" into the map, which bucket does it go to? We calculate bucketIndex = hashCode % numBuckets (so 65 % 16) and we get the index 1 for the 2nd bucket.
Now we want to put "P" into the map. bucketIndex = hashCode % numBuckets also yields 1 (81 % 16) so the value for a different key goes to the same bucket at index 1.
To solve that a simple implementation is to use a linked list, i.e. the entry for "A" points to the next entry for "P" in the same bucket.
Any get("P") will then look for the bucket index first using the same calculation, so it gets 1. Then it iterates the list and calls equals() on each entry's key until it hits the one that matches (or none if none match).
Okay, so I'm currently on part 12 of the University of Helsinki's MOOC. This whole section about creating your own List and HashMap implementation is really interesting, and I want to grasp all the concepts correctly.
So a HashMap is basically an array that contains lists where the pairs are stored? I think I got that correctly... But still not sure.
And when you want to add a new pair, you have to generate a hashvalue that should be inside the extension of the array but also randomized from the hashcode of the key of the pair itself so that it somehow ends up in whatever list of the array so that it's a bit more evenly distributed across the entire array of lists? (not sure if I'm actually saying something real there lol, but I do think that the randomness of the hashvalue obtained has to do with something about the pairs not accumulating on a particular list of the array).
I'm also trying to understand the relationships between the grow(), copy() and add() methods that are proposed. If I understand correctly, add() checks for the space and if the array is more than 75% full then it calls grow(), creating a bigger array, and then copy() which basically reassings new hashvalues to each pair that is already present on each of the lists inside the array but with the bigger space now added in the formula to get it.
I'm a bit confused on the role that the variable firstFreeIndex takes here as well. It seems to be increased every single time a new pair is added... Meaning that it doesn't really care about what list in the array that pair went, but it is rather a representation of how much space is theoretically taken by each new pair. And then it gets to a point where that theoretical space needs to be expanded so that the evenly distributed pairs inside the lists of the array have a bigger space where it is harder for them to get a hashcode collision? (The collisions are a topic I stumbled upon while doing research about all of this too).
Sorry if this is too long, and if I messed up the entire point somewhere, but this is the topic that has had me the most intrigued and confused out of all the mooc so far...