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.
Related
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();
I am mapping a time table in the format of: Map<Route, List<Service>> read(String fileName)
Can I have multiple Lists on the same key? For example:
timeTable.put(route66,["32","55","33","12","15"]);
timeTable.put(route66,["66","5","33","43","77"]);
timeTable.put(route66,["12","56","33","67","35"]);
No, the contract for Map clearly states:
A map cannot contain duplicate keys; each key can map to at most one value.
In addition, your code isn't close to valid Java, as arrays aren't Lists, and those are strings, not whatever Service might be.
You might, however, be interested in Guava's Multimap, which is essentially a map from keys to a collection of values.
No you can't, Map keys are unique. In your case, the last value will override the others.
What you may want to do is have a map like Map<Route, List<String[]>>. It means that any entry you have will contain a list of String arrays
No you cannot. But you may keep for the same key a List of your lists:
Map<Route, List<List<Service>>>
Sets are essentially Maps from an existential point of view. There is nothing a Map can not do which a Set can, I assume. We have these overheads of defining key-value pairs in Maps which is not there in the Sets. But again the elements of a Set are just the keys of the underlying Map, right? So what is the point of having Sets around when Maps are able to do all the things required? I hope a Set takes the same amount of memory as a Map does?
What are key arguments in favor of existence of Sets?
For instance, in the case of Lists, we have ArrayList and LinkedList which have differences and we can choose between these two as per our requirements.
I would argue that a Map is actually a Set!
Map<Key,Value> can be implemented with Set<Entry<Key,Value>>
This is similar to the mathematical foundations of what sets, maps, and functions are.
Firstly, can we agree that a Map is a function from Key=>Value (or Domain=>Range). Each key corresponds with at most one value, so it is a partial function (or a complete function only upon those keys in the map). So a map is a function. (Scala even goes so far as to have Map implement the Function1 interface.)
Secondly, what is a function? A function is a set of tuples where each first element occurs only once in the set. The second element of the tuple is the value returned by the function.
So we have Map is a Function is a Set.
On a practical note, there are very good reasons for having Sets. They are very often the correct data structure to use from a conceptual point of view, even before you start worrying about performance. I'd use them over a List in most situations.
The primary difference between a Set and a Map is that a Map holds two object per Entry e.g. key and value and it may contain duplicate values but keys are always unique. But Set holds only keys and those are unique.
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...
I am having two Hashtables with <int,string> pair. Now they both have duplicate values in each of them, and I want to merge both the hashtables to give me distinct values. How can I do that!?
thanks
Edit #1 I am reading file contents from a directory. and storing those contents as tokens in two different hashtables. Now I need to merge them into a single hashtable which would give me distinct values of both the tables.
You can use the putAll method of Hashtable to merge two hashtables. The hashtable passed as an argument will overwrite duplicates in the original hashtable.
I didn't get how two hashtables can be merged and still have distinct values. If you want to remove duplicate items from one hashtable (and leave them in the second hashtable) just do as suggested in another answer, but without adding non-duplicate items to map2. After that you will have the first table unmodified and the second with entries which aren't in map1.
Another solution is to merge two hashtables using putAll and clear the second hashtable :)
I guess you mean duplicate keys, not duplicate values. Also, since Hashtable is a map implementation, I'll provide a generic map solution.
// assuming the maps are of type String / String
for(Map.Entry<String, String> entry : map1.entrySet()){
if(map2.containsKey(entry.getKey()){
map2.remove(entry.getKey());
}else{
map2.put(entry.getKey(), entry.getValue());
}
}
Now map2 is the merged version with all duplicates removed
But if you want a Map without duplicate values, that's pretty cumbersome to achieve. Maybe you should check out the BidiMap interface in apache commons / collections. It provides maps were both keys and values are unique.
Actually, here's a simple way to remove duplicate values:
Collection<String> values1 = map1.values();
Collection<String> values2 = map2.values();
Collection<String> values1Copy = new ArrayList<String>(values1);
Collection<String> values2Copy = new ArrayList<String>(values2);
while(values1.removeAll(values2Copy)){}
while(values2.removeAll(values1Copy)){}
Now all duplicate values are removed from both maps. (This is assuming you want to delete the dupes entirely. If you want to keep one copy, use the values1 and values2 collections in the while loops and don't take copies.)
The original question-asker asserted in the comments that he means value, not key. This makes the question incomplete. In order to have duplicate values in two different tables, the key generation algorithm must be different. If that's the case, the bit of information that is missing from the question is which key does he want to retain? The one from the first hashtable or the one from the second?
The solution presented above by S.P.Floyd-seanizer is correct but needs a tiny bit of logic added if he really, really mean values. this additional logic would tell the code which key to put the thing under in the merged version.
if the question-asker is having 'value' and 'key' confusion then his solution is spot on.