I am a bit confused. i was reading the map interface. It has to use entrySet() method for collection view to use iterator. entrySet() return a Set that contains the elements of map. Again, each of this Set element is a Map.Entry object. how is that possible? as Set contains only one field, whereas Map.Entry is a key value pair?
A map is basically a set of key => value mappings. In addition, the keys are unique and the values don't have to be. A key-value pair is encapsulated within a Map.Entry object. When you iterate over the entries of a map (= the set of key-value pairs), for each entry you can get the key with entry.getKey() and the value with entry.getValue().
In addition to the set of entries, a map also provides the set of keys, and the collection of values. For example, in a Map<String, Date>, you have the set of key-value pairs as Set<Map.Entry<String, Date>>, the set of keys as Set<String> and the collection of values as Collection<Date>.
A concrete example of iterating over entries:
Map<String, Date> map = new HashMap<String, Date>();
map.put("now", new Date());
map.put("now+", new Date());
for (Map.Entry<String, Date> entry : map.entrySet()) {
String key = entry.getKey();
Date value = entry.getValue();
System.out.println(String.format("%s => %s", key, value));
}
Another way to iterate is by keys:
for (String key : map.keySet()) {
Date value = map.get(key);
System.out.println(String.format("%s => %s", key, value));
}
But this is less efficient because for each key you have to perform a lookup to get the value, in contrast with using entries with direct access to values.
Set elements are objects, Map.Entry instance is also an object. All correct.
Consider the following: You can create your own Cat class with whichever properties you like. E.g.:
public class Cat {
private String name;
private String type;
private boolean isGrumpy;
// etc...
}
As long as you implement equals(Object) and hashCode(), instances of this class can be put in a Set, right?
So why should Map.Entry be different? Just think of it as a class with two members - key and value.
Related
I have a HashMap:
resources = new HashMap<Pair, Resource>();
That I have instantiated...
resources.put(new Pair(x,y), new Resource());
Pair is a custom Pair class that I have created that has overridden .equals and .hashMap to avoid duplicate keys.
I want to iterate over resources so I can identify the unique instances I have created. More specifically, I need to identify the unique (x,y) pairs.
I have found solutions for iterating over HashMaps, but I'm a little confused on how to adapt this (shown below) to work with a key that is a Pair.
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
Thanks!
First of all, I think you mean you have overridden equals() and hashCode() methods in Pair class right?
How do you define unique Pair? I hope your definition of uniqueness is not based on equals() because if it is the case then all the key of HashMap is unique
It's no different. Map and Map.Entry are generic, so you specify parametrized types when you construct the map.
Map<Pair, String> keyToValue = new HashMap<>();
// put stuff in it
for (Map.Entry<Pair, String> entry: keyToValue.entrySet()) {
Pair pair = entry.getKey();
String value = entry.getValue();
// do stuff
}
In fact, your Pair class should probably be generified itself -- Pair<T,U>.
As for getting the unique pairs, you could just do Set<Pair> uniquePairs = keyToValue.keySet() or, if you didn't need the corresponding values at all, you could just use a HashSet -- Set<Pair> uniquePairs = new HashSet<>(). They will be as unique as your implementations of Pair.hash and Pair.equals define them to be.
I am using Map as follows
Map<String, String> propMap = new LinkedHashMap<String, String>();
and I saw that there is two methods that I can use keySet() (to get the list of keys)
and values to get the list of values but my question is how to relate between them
for example for key1 the value is 2.
I thought to use get value like follows
Map<String, String> propMap2 = propterm.getPropMap();
Set<String> keySet = propMap2.keySet();
But how I relate it to his respective value ?
You can use propMap.entrySet() method which returns a Map.Entry of key, value, if you want to use every pair of key and value: -
for (Map.Entry<String, String> entry: propMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
Or, if you want to know how to do this with propMap.keySet(), you can iterate over the Set<Key> you obtain, and for each key, use propMap.get(key), to get the value of a particular key: -
Set<String> keySet = propMap2.keySet();
for (String key: keySet) {
System.out.println(propMap.get(key));
}
From an answer from this post: -
With the later approach, if you are regularly accessing the key-value pair, then for each key, the map.get() method is called, which - in the case of a HashMap - requires that the hashCode() and equals() methods of the key object be evaluated in order to find the associated value*. In the first case (entrySet), that extra work is eliminated.
If .NET has a SortedDictionary object ... what is this in Java, please? I also need to be able to retrieve an Enumeration (of elements), in the Java code .. so I can just iterate over all the keys.
I'm thinking it's a TreeMap ? But I don't think that has an Enumeration that is exposed?
Any ideas?
TreeMap would be the right choice. As for the Collection of all the keys (or values), any Map exposes keySet() and values().
EDIT (to answer your question with code tags). Assuming you have a Map<String, Object>:
for (String key : map.keySet()) {
System.out.println(key); // prints the key
System.out.println( map.get(key) ); // prints the value
}
You can also use entrySet() instead of keySet() or values() in order to iterate through the key->value pairs.
TreeMap is probably the closest thing you're going to find.
You can iterate over the keys by calling TreeMap.keySet(); and iterating over the Set that is returned:
// assume a TreeMap<String, String> called treeMap
for(String key : treeMap.keySet())
{
string value = treeMap[key];
}
It would be the equivalent of:
// assume a SortedDictionary called sortedDictionary
foreach(var key in sortedDictionary.Keys)
{
var value = sortedDictionary[key];
}
You could also try the following:
// assume TreeMap<String, String> called treeMap
for (Map.Entry<String, String> entry : treeMap.entrySet())
{
String key = entry.getKey();
String value = entry.getValue();
}
Which is the equivalent to the following .NET code:
// assume SortedDictionary<string, string> called sortedDictionary
foreach(KeyValuePair<string, string> kvp in sortedDictionary)
{
var key = kvp.Key;
var value = kvp.Value;
}
What you need is entrySet() method of SortedMap (TreeMap).
I'm using Guava's ArrayListMultimap<K,V> collection to map Integers to Strings. The class provides a method called containsValue(Object value) which checks if the Multimap contains the specified value for any key. Once I determine that is true, what's the best way to retrieve said key?
ArrayListMultimap<String, Integer> myMap = ArrayListMultimap.create();
if (myMap.containsValue(new Integer(1))
{
// retrieve the key?
}
Instead of using containsValue you could iterate over myMap.entries() which returns a collection of all key-value pairs. The iterator generated by the returned collection traverses the values for one key, followed by the values of a second key, and so on:
Integer toFind = new Integer(1);
for (Map.Entry<String, Integer> entry: myMap.entries()) {
if (toFind.equals(entry.getValue())) {
// entry.getKey() is the first match
}
}
// handle not found case
If you look at the implementation of containsValue it just iterates over the map's values so the performance of doing this with map.entries() instead of map.values() should be about the same.
public boolean containsValue(#Nullable Object value) {
for (Collection<V> collection : map.values()) {
if (collection.contains(value)) {
return true;
}
}
return false;
}
In the general case of course there isn't necessarily a unique key for a given value so unless you know that in your map each value only occurs against a single key you would need to specify the behaviour e.g. if you wanted the first key or last key.
I have a method that goes through the possible states in a board and stores them in a HashMap
void up(String str){
int a = str.indexOf("0");
if(a>2){
String s = str.substring(0,a-3)+"0"+str.substring(a-2,a)+str.charAt(a-3)+str.substring(a+1);
add(s,map.get(str)+1);
if(s.equals("123456780")) {
System.out.println("The solution is on the level "+map.get(s)+" of the tree");
//If I get here, I need to know the keys on the map
// How can I store them and Iterate through them using
// map.keySet()?
}
}
}
I'm interested in the group of keys. What should I do to print them all?
HashSet t = map.keySet() is being rejected by the compiler as well as
LinkedHashSet t = map.keySet()
Use:
Set<MyGenericType> keySet = map.keySet();
Always try to specify the Interface type for collections returned by these methods. This way regardless of the actual implementation class of the Set returned by these methods (in your case map.keySet()) you would be ok. This way if the next release the jdk guys use a different implementation for the returned Set your code will still work.
map.keySet() returns a View on the Keys of the map. Making changes to this view results in changing the underlying map though those changes are limited. See the javadoc for Map:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.html#keySet%28%29
Map<String, String> someStrings = new HashMap<String, String>();
for(Map.Entry<String, String> entry : someStrings.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}
This is how I like to iterate through Maps. If you specifically want just the keySet(), that answer is elsewhere on this page.
for ( String key : map.keySet() ) {
System.out.println( key );
}
Set t = map.ketSet()
The API does not specify what type of Set is returned.
You should try to declare variables as the interface rather than a particular implementation.
Just
Set t = map.keySet();
Unless you're using an older JDK, I think its a little cleaner to use generics when using the Collections classes.
So thats
Set<MyType> s = map.keySet();
And then if you just iterate through them, then you can use any kind of loop you'd like. But if you're going to be modifying the map based on this keySet, you you have to use the keySet's iterator.
All that's guaranteed from keySet() is something that implements the interface Set. And that could possibly be some undocumented class like SecretHashSetKeys$foo, so just program to the interface Set.
I ran into this trying to get a view on a TreeSet, the return type ended up being TreeSet$3 on close examination.
Map<String, Object> map = new HashMap<>();
map.put("name","jaemin");
map.put("gender", "male");
map.put("age", 30);
Set<String> set = map.keySet();
System.out.println("this is map : " + map);
System.out.println("this is set : " + set);
It puts the key values in the map into the set.
From Javadocs HashMap has several methods that can be used to manipulate and extract data from a hasmap.
public Set<K> keySet()
Returns a Set view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.
Specified by:
keySet in interface Map
Overrides:
keySet in class AbstractMap
Returns:
a set view of the keys contained in this map
so if you have a map myMap of any datatype , such that the map defined as map<T> , if you iterate it as follows:
for (T key : myMap.keySet() ) {
System.out.println(key); // which represent the value of datatype T
}
e.g if the map was defined as Map<Integer,Boolean>
Then for the above example we will have:
for (Integer key : myMap.keySet()){
System.out.println(key) // the key printed out will be of type Integer
}