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. :-)
Related
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 want to loop through all entries of AbstractMap.SimpleEntry type and Map type using the same function. Is there a way to do it?
You cannot iterate through what you are asking. I am guessing you mean the following:
for(Map.Entry<K, V> entry : AbstractMap.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
}
This example will not run; you'll need to alter it to your concrete implementations of the Abstract classes and Key/Value definitions.
Oracle Java Docs
Another Example
Is there a way to clear all of the values, while retaining the keys?
My HashMap is <String,String>, so should I just loop through and replace each value with a null? Is there a better way to do it?
You can use Map#replaceAll if you are using Java 8+ :
map.replaceAll((k, v) -> null);
If not, looping over the Entrys will probably be the simplest way. From the link above the default implementation of Map#replaceAll is equivalent to:
for (Map.Entry<K, V> entry : map.entrySet())
entry.setValue(function.apply(entry.getKey(), entry.getValue()));
Where function is the parameter, so you could do this:
for (Map.Entry<K, V> entry : map.entrySet()) {
entry.setValue(null);
}
I would keep it simple and collect the headers in a list or set then create a new HashMap at each line by looping over the list instead of trying to recycle the same map.
for(String key : map.keySet()) {
map.put(key, null);
}
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'm sure this comes up often enough for it to be addressed somewhere, but I wasn't sure how to search for it any further.
I want to modify the values from map that's key is not in set B. What is the best method? Here's what I had in mind:
Map<X,Y> map = ...
Set<X> B = ...
for(Map.Entry<X, Y> entry : map.entrySet() ) {
if( ! B.contains(entry.getKey()) {
entry.setValue( someMethod(entry.getValue);
}
}
What you have currently should work fine. As an alternative, you could try something like this:
Map<X,Y> newMap = new HashMap<X,Y>(map);
newMap.keySet().removeAll(B); // remove keys in the set B
for (Map.Entry<X, Y> entry : newMap.entrySet()) {
entry.setValue(someMethod(entry.getValue());
}
map.putAll(newMap);
Although I have to say, if I was doing this, I'd take your current approach.