Duplicates in LinkedHashMap - java

In my code I am using a set of interleaved LinkedHashMaps inside each other as below. The code is fine and gives me the result I want except it automatically removes the duplicates. I couldnt find out how I can use TreeMap or Set in order to keep the duplicates.
LinkedHashMap<String, LinkedHashMap<Integer, LinkedHashMap<String, Vector<String>>>>
dataAll =new LinkedHashMap<String, LinkedHashMap<Integer, LinkedHashMap<String,
Vector<String>>>>();

LinkedHashMap is still a Map data structure. It maps a unique key to a value. If you assign two different values to a key the second value will simply replace the first value assigned to that key.
Also imagine why do you need a Map of duplicated key? The sole purpose of Map is to provide a one to one relationship between key/value pair. It does not handle one to many relationship.
If you have to map a key with a list of values, use something like:
LinkedHashMap<String, List<..>>
This allows you to have one key maps to a list of values.

Related

Meaning of List<HashMap<String, String>> nearbyPlacesList

I would like if someone could explain me what is the meaning of this in java
List<HashMap<String, String>> nearbyPlacesList
That means that you have a List containing instances of HashMaps that takes String data as both keys and values.
Oh, and the variable is called nearbyPlacesList.
It's a List which contains HashMap elements with a key of String type and a value of String type.
It is a List consisting of possibly multiple HashMap's where the key-value are Strings.
e.g.
nearbyPlacesList.get(0); // returns first HashMap in the List
nearbyPlacesList.get(0).get("park"); // returns value of the first Map which has the key park
and so on.
A HashMap contains key-value pairs of different kinds (in your case String).
Let's take an example right here. A store. In a store there can be different clothes.
HashMap<String, String> tShirts;
HashMap<String, String> jeans;
where the key-value pair could be for example "Price" and "100€", and they can all be stored in the following list containing different clothes:
List<HashMap<String, String>> clothes;
clothes.add(tShirts);
clothes.add(jeans);
The first piece of information that we see is a list, so we know it's a list. Then we see it is a hashmap (take a look here at the java docs if you are not familiar https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html)
So it's a list of hashmaps, with two strings as the key value pair.
HashMap<String,String>
It uses to store your data as a key and value pair.
When There is more than one HashMap you want to store. you can store all hashmaps into a single list like this.
List<HashMap<String,String>>

Java Map get key from value

below is my code...
Map<Integer, String> MyType = sessionInfo.getType();
//{2=somename}
I am trying to get key from value...without running any loops....is it possible?
MyType.get("somename") // should output 2`
It's not easy to get key from value in Hashtable or HashMap, as compared to getting value from key, because Hash Map or Hashtable doesn't enforce one to one mapping between key and value inside Map in Java. infact Map allows same value to be mapped against multiple keys inside HashMap, Hashtable or any other Map implementation.
String key= null;
String value="somename";
for(Map.Entry entry: MyType.entrySet()){
if(value.equals(entry.getValue())){
key = entry.getKey();
break; //breaking because its one to one map
}
}
I would encourage running a loop for simplicity. It most likely will not slow down your program a noticeable amount.
However, if you must not run a loop, Google's Guava library has a BiDirectional Map Collection called BiMap that can be (found here). The map works both ways and is guaranteed to be synchronized at all times. I also am assuming that you have unique values in your map. If you do not, duplicate values will not have a specific key to link to.
BiMap<String, Integer> biMapInversed = biMap.inverse(); // how to get inverted map
Again, I wouldn't encourage this unless absolutely necessary. Looping through will work perfectly fine in most cases.
Taken from this SO answer
If you choose to use the Commons Collections library instead of
the standard Java Collections API, you can achieve this with ease.
The BidiMap interface in the Collections library is a
bi-directional map, allowing you to map a key to a value (like normal
maps), and also to map a value to a key, thus allowing you to perform
lookups in both directions. Obtaining a key for a value is supported
by the getKey() method.
There is a caveat though, bidi maps cannot have multiple values mapped
to keys, and hence unless your data set has 1:1 mappings between keys
and values, you cannot use bidimaps.
This is not possible. You need to consider the value may be duplicated in map.
Ex, How do you deal with {2=somename} and {5=somename}
You still need to use a for loop to check value and get key and decide to break or go on when value is matched.
If you're sure that your values are unique you can iterate over the entries of your old map .
Map<String, Character> myNewHashMap = new HashMap<>();
for(Map.Entry<Character, String> entry : myHashMap.entrySet()){
myNewHashMap.put(entry.getValue(), entry.getKey());
}
Alternatively, you can use a Bi-Directional map like Guava provides and use the inverse() method :
BiMap<Character, String> myBiMap = HashBiMap.create();
myBiMap.put('a', "test one");
myBiMap.put('b', "test two");
BiMap<String, Character> myBiMapInversed = myBiMap.inverse();

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.

Java LinkedHashMap replace key

Is there any way to replace a key using put() in a LinkedHashMap without losing the order that the key was originally inserted in?
You do not lose the order when putting a different value for the same key.
Example
Map<String, String> map = new LinkedHashMap<String, String>();
map.put("foo", "bar");
map.put("blah", "baz");
System.out.println(map);
map.put("foo", "foo");
System.out.println(map);
Output
{foo=bar, blah=baz}
{foo=foo, blah=baz}
Edit
"Replacing" a key for a given value would imply removing the key value pair, then putting the new key with the stored value.
As such, there is no direct way to do this with a LinkedHashMap, probably not even by inheriting and changing the behavior of remove and put.
If you used the LinkedHashMap, I don't think there is built-in method to achieve your goal. You may want to pick another (or design your own) data-structure.
If you have to do it on a linkedhashmap, you can create a new LinkedHashMap, iterate the old one and put into the new one, when your target entry comes, create a new entry with different key, put the new entry into the map.

Java: Setting key of a hashmap explicitly and keeping reference to it

public static HashMap<ArrayList<Integer>, String> map = new HashMap<ArrayList<Integer>, String>();
public static ArrayList<ArrayList<Integer>> keys = new ArrayList<>(map.keySet());
Then in main
map.put(key, "c");
(assume key is a valid ArrayList). But keys still has size 0 after that.
How can I make the relationship of keys stronger so that it will be actually tied to the HashMap and contain all its keys.
The copy constructor of ArrayList copies all the keys in the map to the ArrayList but if you change the map after that point it will not be reflected.
I can think of 3 options:
write your own map implementation that embeds an ArrayList and keeps it up to date
update the ArrayList manually everytime you update the map
don't use an ArrayList at all (keySet() is there when you need to access the keys so I'm not sure why you would need one)
You can't.
Map.keySet() returns the Map's current key set, which you then load into your list. Changes to the map after that have no effect on the contents of the list.
Most people would just re-get the key set if needed. Why don't you just do that?

Categories