Hash Map with LinkedList in java - 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...

Related

How to conditionally insert a Map into a list in Java if the list does not already include a map containing a key value pair

I have a list of HashMap objects in Java.
I would like to conditionally add more HashMap objects to this list if the list does not already contain a HashMap having the same key value pair as in the new HashMap.
Here is an example HashMap list. Note that in reality, there are more keys. Here, I am just including "contact_id" for simplicity.
[{contact_id=16247115}, {contact_id=16247116}, {contact_id=16247117}, {contact_id=16247118}, {contact_id=16247119}]
Adding {contact_id=16247117} to this list should not be allowed.
Adding {contact_id = 74857983}, should be allowed.
Ideally, I would like to be able to conditionally add several HashMaps into this list in one line of code. If I were not to perform the conditional check, I could just use the syntax listname.addAll(batchOfHashMaps). I'd like to do something similar, but precluding redundant HashMaps in the list.
What is the most efficient way to achieve this conditional insert in Java?
I reckon there must be a more efficient solution than evaluating each element in the list inside a for-loop.
If you are only wanting to look at one key-value pair of the maps as an identifier, then you could use a Map instead of a List to hold everything. For example,
Map<String, Map<String, String> mapOfMaps;
Then you could add one like:
mapOfMaps.putIfAbsent(mapToAdd.get("contact_id"), mapToAdd);
you could add multiple like:
batchOfHashMaps.forEach(m -> mapOfMaps.putIfAbsent(m.get("contact_id"), m));
To get a collection of your maps simply call values()
mapOfMaps.values();

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.

How do I get each of the entries from Guava MultiMap and their corresponding values associated with it?

I am reading from a huge csv file which contains duplicate entries. I was able to read the whole csv file into a Multimap. I am also able to obtain the keyset with duplicate values and write them to a file. I want to get the value associated with each of the keys and write it to a file but unable to do so. I cant seem to find any of the options that might help me. I tried using entries() method which according to the doc
Returns a view collection of all key-value pairs contained in this multimap, as Map.Entry instances
but I am unable to get anything from it.
I am using ArrayListMultiMap implementation of MultiMap. Reason for using ArrayList is that later I need to perform a search operation which is quicker in an ArrayList.
I have pstored the keyset as a MultiSet which is why I am able to get all the duplicate keys.
Value of each of the keys is an object which I want to be written to a file corresponding to that read key.
If you want each key and each value associated with that key, instead of each key-value pair, then you can do that with
for (Map.Entry<String, Collection<SomeClassObject>> entry : multimap.asMap().entrySet()) {
String key = entry.getKey();
Collection<SomeClassObject> valuesForKey = entry.getValue();
// do whatever
}
As you've discovered, there are two ways to think about Multimaps. One is as a Map<K, Collection<V>>, and the other is as a Map<K, V>, where the keys do not have to be unique. In the documentation, Google stresses that the latter approach is preferred, although if you do multimap.asMap().entries() (N.B. Not just multimap.entries()), as Louis suggested, you will have entries like the former version.
For your particular problem, I'm not sure why you can't do something like the following:
for (String key : multimap.keySet()) {
Collection<SomeClassObject> values = multimap.get(key);
//Do whatever with all the values for Key key...
}

A java datastructure which has constant access time and allows duplicates

A HashMap has constant access time but does not allow duplicates. An ArrayList allows duplicates but does not have constant access time.
Is there a data structure in java which allows constant access time and allows duplicates?
I know I could make my own HashMap which allows duplicates, but I want to use an already existing data structure.
Thank you in advance.
ArrayList#get and ArrayList#set are actually constant time, as well as a few other functions. Read the documentation, second paragraph of the class documentation:
The size, isEmpty, get, set, iterator, and listIterator operations run in constant time
Your next option would be a multimap. This is a map that stores items in a key/collection manner. The collection holds the values, so a single key map to multiple values. You can look into Apache Common's MultiMap to see if they have an implementation that works for you. Or you could always create your own, simply by defining a collection as the value:
Map<String, List<String>> multimap;
You could use a Bag from Eclipse Collections, a Multiset from Google Guava, or a Bag from Apache Commons Collections. A Bag is basically a Map<Key, Integer> which behaves like a Collection.
All three libraries have Multimaps as well. A Multimap is basically a Map<Key, Collection<V>>, where a call to put results in adding to the Collection<V> instead of replacing the value at that key. There are different types of Multimap (List, Set, Bag, etc.).
Note: I am a committer for Eclipse Collections

How to found in Java common part of many Maps?

I have many maps like Map(String, Object).
map1
map2
....
mapN
I need to receive map that contains only these key-value pairs where first parameter is equal in all maps.
Could it be done by using retainAll method?
Yes you can do it using retainAll
map1.keySet().retainAll(map2.keySet());
map1.keySet().retainAll(map3.keySet()); //etc
At last map1 will be intersection of all keys in your all maps so these keys are common now you can retrieve value easily
Yes. You get one of the Sets and use retainAll with all of the others, the remainder elements are common to all of the sets.
The missing step is getting all the keys of the maps as a Set, which is done by Map.keySet()
Note that the retainAll is marked as optional, so maybe the implementation of the Set returned by Map.keySet does not implement it. In that case, create a new Set instance that does support it passing the original set as parameter.

Categories