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.
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 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().
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>>>
I am trying to implement an iterator that will iterate through the HashMap and its duplicates. For example string.put("a", 1);
string.put("a", 2);
string.put("b", 3);
string.put("b", 4);
However with my iterator I only iterate twice, once for where the value is "a" and the other for "b". I'd like to make an iterator that will iterate 4 times throughout the whole Map.
EDIT: I kind of left out a lot of detail because I just wanted to see if this iterator was possible, but the code I'm writing is actually an abstraction of a map. For example, I have an add function which takes in parameter T. So for adding a string it would look like add("Hello"). By adding this string, it's key is "String" and its value is 1. If I call add("Hello") again it will bump up the value to 2. If I add it again, it will bump up its value to 3 and so on. I want to create an iterator that will iterate through all the stuff I have added.
Unfortunately, Java's Map interface doesn't allow for duplicate keys:
An object that maps keys to values. A
map cannot contain duplicate keys;
each key can map to at most one value.
Thus, when you try to put a key that already exists in the map, the new value replaces the old value; the reason your iterator iterates 2 times is because there are only 2 items.
If you want to keep duplicate keys (like "a" pointing to both 1 and 2), either you can have a Map of a List or Set, like
Map<String, List<Integer>> myMap;
Where the list or set that a key maps to contains all values, like myMap.get("a") would return a list that would look like [1,2].
Or use something like a MultiMap from either Google or Apache
For your problem, I believe you are saying that you want a special Map where:
The value for each key to be how many times the key was entered.
When you iterate over the map, you iterate over all the keys you added, for each time they were added.
You may want to look at how they implemented iterator() for HashMap, specifically looking at the internal private class HashIterator.
next() and hasNext() could maybe keep returning the key for as many times as specified by the value (i.e. if "Hello" maps to 2, your custom iterator() will return with next() "Hello" two times before moving onto the next key).
Map may not be an appropriate structure to use for what you're trying to do, but I wish you luck!
You can try using a Multimap from the guava library. java.util.HashMap allows to associate only one value with one key.
You can access an Iterator for your HashMap like this :
myHashMap.entrySet.iterator()
If you want to loop on all your objects, this is a faster way :
for(Object o : myHashMap.entrySet()) {
// do something with o
}
The problem in your case seems to come from the fact that a HashMap in java can't have identical keys, so your code add only two objects to the HashMap.
What is the best way to do the following(make sure that items from List are following the same order as those in ListTwo):
List
harry~20
marry~22
peter~40
jerry~33
janice~20
ListTwo
harry
marry
peter
janice
Now the result should look like this
ListThree
harry
marry
peter
janice
jerry
Step by step :
For each item in List :
compare first part of the item to item in ListTwo
if they are equal add it to ListThree
if item exist in List but not in ListTwo dont do anything yet save it
somewhere
continue from step 1
you are at the end of the List add the item(s) you skipped before in step
3
I know this much(actually I don't, I think I know), there are better ways to do this I'm sure
Why did I get downvote, did I miss something ?
It may be easier if you reverse the roles (store the keys in the ArrayList, in order) and the key-value mappings in a SortedMap, such as TreeMap, or ConcurrentSkipListMap. The comparator for the sorted map can use List.indexOf as the basis for element comparison.
With this arrangement, the map defines the key/value mapping, which is natural for the map, and the list maintains the desired order, which is quite natural for a List.
Alternatively, use a regular Map, and not a sorted map, and use iteration over the list, and fetching values from the map. E.g.
ArrayList keysList;
Map keyValues;
for(String key: keysList) {
String value = keyValues.get(key);
}
EDIT: Commons collections has SetUniqueList - a list that ensures uniqueness like a Set. It also has has various types of OrderedMap, in particular a ListOrderedMap that maintains the key/value mappings in the order of a list. For generics support, see commons collections with generics.
Use LinkedHashMap
You can call something like
map.put(one,value1);
and later call
map.get(one);
which will return value1
also a hash map does not accept duplicate key, so if you call
map.put(one,value2);
after this the original value is replaced.
you can use
map.containsKey(one)
to check whether one already exists as a key
If you are only comparing the keys of element then you can store them in LinkedHashSet and use the contains method of linkedHashset to check whether the element exists in constant time O(1).
LinkeHashMap also serves the purpose, however it requires extra space to store the value and this is not required we are only interested in keys.
Refer : http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html