I'm struggling with a little bit of code, and I just cannot figure out what the correct syntax would be. Here is an example of the problem:
for (Integer key : map1.keySet()) {
for (Integer value : map2.values()) {
if (value == key) {
// ++ the corresponding value of the looping map1 key.
// tried statements like map1.values()++
// but this is an invalid operation.
}
}
}
I am trying to loop map1 keys through map2 values and if within this process a map1 key matches a map2 value, I want to add one to the value of the corresponding map1 key.
Should be a simple problem but Eclipse keeps telling me that I have the syntax wrong, can anyone suggest what statement I may need to iterate the values?
Here is how you can do it with a very small modification to your code:
for (Map.Entry<Integer,Integer> entry : map1.entrySet()) {
for (Integer value : map2.values()) {
if (value.equals(entry.getKey())) {
entry.setValue(entry.getValue()+1);
}
}
}
EDIT : Since map2 could contain the same value more than once, the other solution that uses a hash set to speed things up will not work as expected.
How you init yours maps? Like Map<Integer, Integer> map1=new LinkedHashMap<Integer, Integer>(); or Map map1=new LinkedHashMap(); If the second way the key will be Object not Integer. And in all cases compare two Integer using == bad practise. Use equals
I'm not sure why Eclipse report a syntax error, but in any case this loop does not make much sense, consider changing it to:
for (Integer value : map2.values())
if (map1.containsKey(value))
// bla bla
it will run in O(n) rather than the former O(n*m)
when n is the size of map2 and m is the size of map1 (as notified by #dasblinkenlight)
You can use containsKey method like this:
for (Integer value : map2.values()){
if (map1.containsKey(value))
map1.put(key, value);
...
}
Related
I have this code for Guava Multimap:
String key = "first-key";
Multimap<String, String> map = ArrayListMultimap.create();
map.put(key, "firstValue");
map.put(key, "secondValue");
map.put(key, "thirdValue");
map.putAll("sec-key", Sets.newHashSet("am", "are", "is"));
for (String name : map.keySet()) {
System.out.println("key: " + name);
}
I want to query this structure for values.
For example: How I can send value are and get the result is?
Both are and is are values mapped to the key sec-key. There's no straightforward way of looking up a value by a different value using just a multimap. The mutlimap is meant to map keys to values. Not values to values.
You could of course do something like this, but this is very inefficient - this code requires us to iterate over the entire map:
for (Entry<String, String> entry : map.entries()){
if (entry.getValue().equals("are")) {
System.out.println(map.get(entry.getKey())); //will print the values mapped to the same key as `are`.
break;
}
}
A better solution would be to use a second map, one in which are will be the key, and is will be the value (or one of the values in case of a Mutlimap). If you make sure to keep both mutlimaps in sync, you'll be able to lookup quickly in both directions.
For example: How I can send value are and get the result is?
"are" is not a key mapped to a value "is". You can only get a value by passing a key to a map.
I need to merge two maps in the first one by the following rules:
I need to remove all of the keys from map1 which are not present in the map2.
I need to update all keys in the map1 with the appropriate values which are present in map2 under these keys.
This is my current code:
Set<String> keysToRemove = new HashSet<>();
map1.forEach((k, v) -> {
if (!map2.containsKey(k)) {
keysToRemove.add(k);
} else {
map1.put(k, map2.get(k));
}
});
for (String k : keysToRemove) {
map1.remove(k);
}
I'm not sure my code is optimal and can be improved. Could you please show the way how to implement this task more effectively?
You can achieve it in two lines
This solution is based on the comment (which gave an impression as the OP wanted map1 to be an exact copy of map2)
[...]I'm trying to keep the same referense on the original map1 and do not substitute it with the new map.[sic]
//Retains only those keys that are in map2
map1.keySet().retainAll(map2.keySet());
//(Possibly) Overwrite value for each key in map2 into map1
map2.forEach(map1::put);
I don't believe it would help you improve the performance though.
EDIT:
As suggested by Jacob G.# you can have map1.putAll(map2) for the last line
EDIT2:
If we consider the OP (and not the comments), if there are any keys in map2 that is not there in map1, it should not end up in map1 and hence the last statement becomes
map1.forEach((key, value) -> map1.put(key, map2.get(key)));
I think you can remove the second loop by using Iterator
Iterator<Map.Entry<K,V>> iter = map1.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<K,V> entry = iter.next();
if(not map2 contain k){
iter.remove();
} else {
entry.put new data
}
}
The key here is, you can't update the map while loop over Map.entrySet(), it will raise ConcurrentModificationException, but you can do it with Iterator.
Another approach could be filtering only with the keys available in map2, and finally using map to replace existing values with the ones on map2. Something similar to this might do the trick:
map1.entrySet().stream().
filter(e -> map2.containsKey(e.getKey())).
map(e -> map2.get(e.getKey()))
I have the following maps :
Map <String,String> m; // contains part details
Map <String,String> n; // contains part details
Map <String,String> o; // the new map that contains both m and n.
I want copy the values from m into o first.
I then want to loop though n and compare keys against o. If key from n, does not exist in o then put key/value it to o.
I tried the below, but the the the second step is not working (values are not copying)
for (Map.Entry<String, String> entry : m.entrySet())
{
String key = entry.getKey();
String value =entry.getValue();
o.put(key, value);
}
for (Map.Entry<String, String> entry : n.entrySet())
{
String key = entry.getKey();
String value =entry.getValue();
for (Map.Entry<String, String> entry1 : o.entrySet())
{
String key1 = entry.getKey();
if(key1 != key)
{
o.put(key,value);
}
}
}
Consider using Map#containsKey(). You can also iterate over a keyset, not over the entryset.
for (String key: n.keySet())
{
if (!o.containsKey(key))
o.put(key,n.get(key));
}
This should work.
I think the problem was you were using direct comparing of Strings, which is not sufficient in your case (almost never), use String#compareTo() method instead.
Why you don't use ready methods? You do not have to write all manually ;).
1) Method putAll() copies all values from one map to the second.
http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#putAll(java.util.Map)
2) Method containsKey() and only one loop.
You don't have to loop through o.
Just use o.containsKey() method
In second inner for loop "String key1 = entry.getKey();" it should be "String key1 = entry1.getKey();"
mistaken between entry and entry1
o.putAll(m); // put all m into o
n.keySet().removeAll(o.keySet()); // Remove all duplicates from n
o.putAll(n); // Now add all filtered n to o
I am trying to print the key value(s) in a hash table when the value is found or exists. This code does not seem to work.
Map<String,Integer> map = new HashMap<String, Integer>();
for(int j=0;j<al.size();j++){
Integer count = map.get(al.get(j));
map.put(al.get(j), count==null?1:count+1); //auto boxing and count
}
int max = Collections.max(map.values());
if( map.containsValue(max))
{
System.out.println(map.keySet());
}
Firstly, the values could occur multiple times - I assume you want to print all matching keys?
Secondly, hashtables basically aren't designed for lookup by value - so you have to iterate all the entries:
// Adjust types accordingly
for (Map.Entry<String, String> entry : map.entrySet()) {
if (entry.getValue().equals(targetValue)) {
System.out.println(entry.getKey());
}
}
You should change the equality check if it's possible that some of the values are null.
I want to go through every items in a dictionary in java. to clarify what I want to do, this is the C# code
Dictionary<string, Label> LableList = new Dictionary<string, Label>();
foreach (KeyValuePair<string, Label> z in LabelList);
I don't know how to do this is java, for example I did this
for(Object z: dic)
but it says it's not iterable. Please advise......
I'm assuming you have a Map<String, Label> which is the Java built-in dictionary structure. Java doesn't let you iterate directly over a Map (i.e. it doesn't implement Iterable) because it would be ambiguous what you're actually iterating over.
It's just a matter of choosing to iterate through the keys, values or entries (both).
e.g.
Map<String, Label> map = new HashMap<String, Label>();
//...
for ( String key : map.keySet() ) {
}
for ( Label value : map.values() ) {
}
for ( Map.Entry<String, Label> entry : map.entrySet() ) {
String key = entry.getKey();
Label value = entry.getValue();
}
Your C# code seems to be the same as iterating over the entries (the last example).
java.util.Map is the Dictionary equvivalent and below is an example on how you can iterate through each entry
for(Map.Entry<K, V> e : map.entrySet())
{
System.out.println(e.getKey()+": "+e.getValue());
}
Your best bet is to use this:
for (String key : LableList.keys()) {
Label value = LableList.get(key);
// do what you wish with key and value here
}
In Java however, a better bet is to not use Dictionary as you would in .NET but to use one of the Map subclasses, e.g. HashMap. You can iterate through one of these like this:
for (Entry<String, Label> e : myMap.entrySet()) {
// Do what you wish with e.getKey() and e.getValue()
}
You are also advised against using Dictionary in the official javadoc.
I was trying to add the contents of one HashMap (a) into another HashMap (b).
I found it simple to iterate through HashMap a this way:
a.forEach((k, v) -> b.put(k, v));
You can manipulate my example to do what ever you want on the other side of "->".
Note that this is a Lambda expression, and that you would have to use Java 1.8 (Java 8) or later for this to work. :-)