HashMaps/HashTable explanation [duplicate] - java

This question already has answers here:
how does weakhashmap work? [duplicate]
(2 answers)
Closed 9 years ago.
I have read up quite a bit on these and am still rather confused on one aspect.
HashMaps take in a K,V pair. Why is this necessary?
For example I want to add "abracadabra" to HashMap myMap.
Would it not use String.hashCode() function as the key, and then "abracadabra" as the value?
And then if I were trying to lookup if "abracadabra" is there it would check if the 'bucket' for that hashCode is nonempty, and if it is then iterate through everything in that 'bucket' (At worst O(n)...but not in reality). So what I am saying is wouldn't the objects .hashCode() function be the key and the object is the hashcode? Why is an explicit Key necessary to be declared?
What is the purpose of having K,V pair? I have had this explained to me multiple times and have read multiple articles/examples/etc. and I still can't get it through my thick skull.

A hashmap is a mapping from key (in your case abracadabra) to an object. This is useful if you get the key from somewhere else, e.g. an id identifying an user and you need to load additional data for that user.
What you described sounds more like a HashSet

You are looking a the wrong object: HashMaps are not ment to store a single object (e.g. the string "abracadabra"), they are indeed ment to store key-value pairs, where both parts are of importance - an easy example would be a property store: The property name is the key, the property value the value.
If you want to really store just one object, look at other structures. HashSet comes to mind.

If I am getting you right, you want the functionality of a HashSet being accomplished by a HashMap. Have a look on the HashSet documentation, probably that is what you are searching for.
HashMaps work different, to give you a hint: you can store the same string (with equal hashCode) with different keys:
String myString = "hallo";
HashMap<String,String> map = new HashMap<String,String>();
map.put("key1", myString);
map.put("key2", myString);

A hashCode by itself is not enough to look up a value: different keys can have the same hashCode. The point of having a hashCode is only to quickly narrow down the places where the hash table would have the entry for that key and that value.

Related

O(1) method of getting K using V with a java hashmap? [duplicate]

This question already has answers here:
Bidirectional Map
(9 answers)
Closed 4 years ago.
In Java 8 is there an O(1) method of getting the K by using V for a hashmap? Would I have to use two hashmaps(KV and VK) and if so would that defeat the purpose of having O(1)?
For context, I am trying to find the most efficient way of getting (String userName, Integer userIdentifier) using either value or key.
As a general note - there's a hidden assumption here that the values are also unique. Otherwise, you won't be able to retrieve a single key by a value, but a list of keys, although even if you take that into consideration it won't change the answer much. Additionally, with your usecase of userName and userId, this may be a moot point altogether.
As you alluded, a simple HashMap won't be enough - that would mean you'd need to iterate over the entries to find an entry with a specific key, which would be an O(n) operation.
Using two HashMaps (name to id and id to name) is a good approach. While this would mean you'd have to perform two operations instead of one each time you add/remove/modify a user, it won't affect the order of magnitude (since you're still performing a constant number of constant-time operations), and you'll retain the O(1) insertion time.
This is in fact a pretty common approach, and if you can introduce third-party libraries to your project, there are pretty solid implementations of this concept out there, like Apache Commons Collections' DualHashBidiMap.
Maps are meant for searching by key, so you won't get O(1) lookup by value, unless you use a second map.
What serves your use case is a BiMap avaliable from Google Guava
BiMap<String, Integer> nameidmap = HashBiMap.create();
Integer id = nameidmap.get("name");
String name = nameidmap.inverse().get(12345);
Internally Guava also maintains two hash tables, but it does the heavy lifting of keeping the two maps in sync. You can find full Javadoc for Bimap here.
If you want to use only single hashmap, you can do
map.put(key, value) and then map.put(value, key)
Assuming values are unique and also not equal to any key

How hashmap works with Integer as keys [duplicate]

This question already has answers here:
HashMap is already sorted by key?
(3 answers)
Closed 8 years ago.
Map<Integer,String> m1 = new HashMap<>();
m1.put(5, "gfd");
m1.put(1,"sandy");
m1.put(3, "abc");
m1.put(2, "def");
m1.put(1, "ijk");
m1.put(10, "bcd");
m1.put(0, "ssdfsd");
When I Print the map, the output is {0=ssdfsd, 1=ijk, 2=def, 3=abc, 5=gfd, 10=bcd}.
But, how the output is in sorted order even though I have used HashMap()??
You can easily see this in the implementation. If you look into the source of HashMap.put(), you can see that the hash table index of the object is determined like this:
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
The methods hash() and indexFor() only ensure that there are not too many collisions of hash values and they don't exceed the length of the hash table.
Now if you take a look at Integer.hashCode(), you'll see that the hash is the integer itself:
public int hashCode() {
return value;
}
So the integer which has the value 0 ends up in index 0 of the hash table and so on. At least as long as the hash table is big enough.
The toString() method of HashMap iterates over the hash table and the elements in each index of the hash table. So in your case the order is preserved.
As others mentioned correctly, this behavior is not ensured by implementations of Map. It just works in this special case.
A Map provides you with the interface of storing and retrieving objects into a map with a key attached to them.
What each implementation does internally is fully up to it, including in which order the key/value pairs are stored in the internal structure. See #Seshoumaro's answer for the quote from the javadoc.
HashMap hashes the key (which is an Integer in this case) and uses that hash as an array index. Since the hashCode for Integer is fairly simple to write yourself, it's not surprising that the array indices for each one are in the same order as the key itself.
What all that means is: you shouldnt be surprised that the HashMap is acting this way.
The HashMap provides no guarantee as to the order of the items stored. It may even be in order in some cases. Taken from the javadoc:
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
So it's working as intended. If you're curious as to why this particular example is placed in order, you could check out the source code itself.
Its not just restricted to keys of Integers you may obtain the same with Strings at times.
It just so happens to be at times and you would find numerous instances of the same.
As suggested by others HashMap never guarantees the insertion order while fetching.Since the official doc says to not rely you might find occasions when it would not retain the order so better code likewise.
See this for more

Mechanism of Java HashMap

Reading Algorithms book, need to grasp the concept of a hashtable. They write about hashing with separate chaining and hashing with linear probing. I guess Java's HashMap is a hashtable, therefore I'm wondering what mechanism does HashMap use (chaining or probing)?
I need to implement simplest HashMap with get, put, remove. Could you point me at the good material to read that?
When the unique keys used for the Map are custom objects, we need to implement hashCode() function inside the corresponding type. Did I get it right or when is hashCode() needed?
Unfortunately the book does not answer all questions, even though I understand that for many of you these questions are low level.
1: before java 1.8 HashMap uses separate chaining with linked lists to resolve collisions. There is a linked list for every bucket.
2: hmmmmmm maybe this one?
3: yes, you are right, hashCode() is used to calculate the hash of the Key. Then the hash code will be transformed to a number between 0 and number of buckets - 1.
This is a Most Confusing Question for many of us in Interviews.But its not that complex.
We know
HashMap stores key-value pair in Map.Entry (we all know)
HashMap works on hashing algorithm and uses hashCode() and equals() method in put() and get() methods. (even we know this)
When we call put method by passing key-value pair, HashMap uses Key **hashCode()** with hashing to **find out the index** to store the key-value pair. (this is important)
The Entry is **stored in the LinkedList**, so if there are already existing entry, it uses **equals() method to check if the passed key already exists** (even this is important)
if yes it overwrites the value else it creates a new entry and store this key-value Entry.
When we call get method by passing Key, again it uses the hashCode() to find the index in the array and then use equals() method to find the correct Entry and return it’s value. (now this is obvious)
THIS IMAGE WILL HELP YOU UNDERSTAND:
HashMap works on the principle of Hashing. Its working is two fold.
First, it maintains a Linked List to store objects of similar values, that means ones which are "equal".
Second it has a collection of these linked list whose headers are present in a array.
For more information refer blog Java Collection Internal Working

Java why use hashSet? [duplicate]

This question already has answers here:
Difference between HashSet and HashMap?
(20 answers)
Closed 4 years ago.
I am a beginner in Java, so this may be a dumb question.
Why we need hashSet in Java?
I just learned that Java hashSet is actually implemented with HashMap. In my understanding, whenever we use hashSet, we can always use hashmap, so why we need hashSet in java?
Thanks
You can google differences between HashMap and HashSet to understand more.
HashMap is an implementation of Map interface;
HashSet is an implementation of Set Interface;
HashMap stores data in form of key value pair;
HashSet stores only objects;
Put method is used to add element in map;
Add method is used to add element is Set;
In hash map hashcode value is calculated using key object.
Here member object is used for calculating hashcode value which can
be same for two objects. So equal() method is used to check for
equality: if it returns false, that means two objects are different.
Got the info from here.
You can, and you can even further argue that why we need ArrayList because you can see an ArrayList as a map with an integer as index, then you can use an HashMap and use integer as key and then you don't really need List anymore.
There are specific purpose and semantic meaning for different data structure, for example, Set is a collection that will not allow duplicate. Map aimed for providing key-value lookup. If you only want a collection to store non-duplicated objects, why use a Map that is aimed for other purpose?

100% Accurate key,value HashMap

According to the webpage http://www.javamex.com/tutorials/collections/hash_codes_advanced.shtml
hash codes do not uniquely identify an object. They simply narrow down the choice of matching items, but it is expected that in normal use, there is a good chance that several objects will share the same hash code. When looking for a key in a map or set, the fields of the actual key object must therefore be compared to confirm a match."
First does this mean that keys used in a has map may point to more then one value as well? I assume that it does.
If this is the case. How can I create a "Always Accurate" hashmap or similar key,value object?
My key needs to be String and my value needs to be String as well.. I need around 4,000 to 10,000 key value pairs..
A standard hashmap will guarantee unique keys. A hashcode is not equivalent to a key. It is just a means of quickly reducing the set of possible values down to objects (strings in your case) that have a specific hashcode.
First, let it be noted: Java's HashMaps work. Assuming the hash function is implemented correctly, you'll always get the same value for the same key.
Now, in a hash map, the key's hash code determines the bucket in which the value will be placed (read about hash tables if you're not familiar with the term). The performance of the map depends on how well the hash codes are distributed, and how balanced is the number of values in every bucket. Since you're using String, rest assure. HashMap will be "Always Accurate".

Categories

Resources