Hash Multi-Map Issues - java

I have two questions on Java HashMap:
1) Is it possible in any implementation of Java HashMap to get corresponding Key from the value ? I am using HashMultiMap (key -) Multiple values).
2) Is it possible in any implementation of Java HashMap to get Key position in the HashMap ? If so, then If I add new key, is it possible that the key position is changed ? I am using HashMultiMap (key -) Multiple values).
If both of them answer is NOT, how is it possible to implement manually (any idea ?) ?

1) Yes, but not in an efficient way, and there are no methods in interface Map to do this with one method call. You'd have to iterate over the entries of the map until you find one with the value you're looking for; then you have the key of the corresponding entry. There are implementation such as Google Guava's BiMap that do let you do reverse lookups efficiently.
2) No, because a map is not an ordered collection: keys do not have a defined position in a map. If you need this, you could use for example LinkedHashMap, which keeps key-value pairs in the order they are inserted in the map.

Related

Hashmaps contain the same key

I have a
Stack<MyThread> rts;
each Thread contains a HashMap with a Custom Object Key.
HashMap<CustomObject> myMap = rts.pop().mapOfThread;
and I have the HashMap of these CustomObjectKeys
MyThread.CustomObjectMap
I need the fastest way to check if any of the HashMaps in the Threads in the Stack contains the same key as my CustomObject HashMap.
So, if I understand correctly, you have a number of disjoint HashMaps that may share keys, and you want to see if any keys are the same across any or all?
If so, I don't really see a solution other than iterating through the keySet() and checking each HashMap to see if the key is present, probably via containsKey().

Why key in HashMap can't be duplicated

I know how hash map works. We can't use duplicate keys in Hashmap. I want to know the logic behind this used by Sun people. How it has been coded that we can't store duplicate key in HashMap.
It's part of the contract of the Map interface:
An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.
What should Map.get(key) return if a key has multiple values?
An HashMap is a data structure where is possible to save couples of key values. This data structure implements Map.
From javadoc:
A map cannot contain duplicate keys; each key can map to at most one value.
It is possible to retrieve directly a value using its key, so is not possible to have more values associated to the same key.
Instead is possible to have multiple keys pointing to the same value.
If you need a different data structure where multiple values are associated to the same key you can use libraries like Guava that has the concept of Multimap
Note: Using standard Map is possible to create a Map<MyKey, List> where you associate a list to a key. So you can also add multiple values to that key storing them in the associated list.

creating Trigrams using LinkedHashMap java

I am trying to create a trigram model using LinkedHashMap>
where Entry is the entry of last inputed bigram (whose structure is:
LinkedHashMap
Now the problem is, being a map it does not store multiple keys (overwrites the existing key-value pair with new key-value pair for existing key).
I am not sure whether a multimap will be useful for this or not? If so, how?
Every collections that implements Map interface keeps it's keys in Set implementation. Set can not keep multiple values.
Multimap is just a Map<Key, Collection<Value>>. It allows to keep multiple values under one key.
Read more about Maps.

Hash Map with LinkedList in java

Is there a built in implementation in java for hash map whose values are linked lists?
like, if I put:
map.put(1, "A");
map.put(1, "B");
then it automatically add A and B to the linked list. When I retrieve from the map, as:
map.get(1)
I get back a list containing both of them?
Java does not have it but you can use MultiMap from Google Guava.
A collection similar to a Map, but which may associate multiple values with a single key. If you call put(K, V) twice, with the same key but different values, the multimap contains mappings from the key to both values.
The methods get(K), keySet(), keys(), values(), entries(), and asMap() return collections that are views of the multimap
This article Multimaps - Google Guava gives you complete idea about how to use it and also how to do it with HashMap using List as value.
Second put will overwrite first put. You will get B as response.
As per javadoc
If the map previously contained a mapping for the key, the old value is replaced
If you want to keep both entries, you need to use thrid party library google guava MultiMap
Nope, just build your own.
First you take a HashMap, if the key does not exist you put the linkedList in...
Simple...

Map with two-dimensional key in java

I want a map indexed by two keys (a map in which you put AND retrieve values using two keys) in Java. Just to be clear, I'm looking for the following behavior:
map.put(key1, key2, value);
map.get(key1, key2); // returns value
map.get(key2, key1); // returns null
map.get(key1, key1); // returns null
What's the best way to to it? More specifically, should I use:
Map<K1,Map<K2,V>>
Map<Pair<K1,K2>, V>
Other?
(where K1,K2,V are the types of first key, second key and value respectively)
You should use Map<Pair<K1,K2>, V>
It will only contain one map,
instead of N+1 maps
Key construction
will be obvious (creation of the
Pair)
Nobody will get confused as to
the meaning of the Map as its
programmer facing API won't have changed.
Dwell time in the data structure would be shorter, which is good if you find you need to synchronize it later.
If you're willing to bring in a new library (which I recommend), take a look at Table in Guava. This essentially does exactly what you're looking for, also possibly adding some functionality where you may want all of the entries that match one of your two keys.
interface Table<R,C,V>
A collection that associates an
ordered pair of keys, called a row key
and a column key, with a single value.
A table may be sparse, with only a
small fraction of row key / column key
pairs possessing a corresponding
value.
I'd recommend going for the second option
Map<Pair<K1,K2>,V>
The first one will generate more overload when retrieving data, and even more when inserting/removing data from the Map. Every time that you put a new Value V, you'll need to check if the Map for K1 exists, if not create it and put it inside the main Map, and then put the value with K2.
If you want to have an interface as you're exposing initially wrap your Map<Pair<K1,K2>,V> with your own "DoubleKeyMap".
(And don't forget to properly implement the methods hash and equals in the Pair class!!)
While I also am on board with what you proposed (a pair of values to use as the key), you could also consider making a wrapper which can hold/match both keys. This might get somewhat confusing since you would need to override the equals and hashCode methods and make that work, but it could be a straightforward way of indicating to the next person using your code that the key must be of a special type.
Searching a little bit, I found this post which may be of use to you. In particular, out of the Apache Commons Collection, MultiKeyMap. I've never used this before, but it looks like a decent solution and may be worth exploring.
I would opt for the Map<Pair<K1,K2>, V> solution, because:
it directly expresses what you want to do
is potentially faster because it uses fewer indirections
simplifies the client code (the code that uses the Map afterwards
Logically, you Pair (key1, key2) corresponds to something since it is the key of your map. Therefore you may consider writing your own class having K1 and K2 as parameters and overriding the hashCode() method (plus maybe other methods for more convenience).
This clearly appears to be a "clean" way to solve your problem.
I have used array for the key: like this
Map<Array[K1,K2], V>

Categories