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.
Related
I have a hashamp with only one key (and a value). Lets say I don't know the key or value of that one key. Is there a way to find it? This may sound dumb but since there is only ONE key, then would there be a way to get that key.
For a single key map just do the following:
Map<String,String> map = Map.of("A","B");
System.out.println(map.keySet().iterator().next());
prints
A
For a more populated map you can do the following:
You can get the keySet() of the map via map.keySet() and iterate thru that.
If you want to try and find a particular key associated with a value you can
get the entrySet() of the map and do something like this:
String targetVal = "some value";
for (Entry<String,String> e : map.entrySet()) {
if (e.getValue().equals(targetVal)) {
System.out.println(e.getKey());
// or
System.out.println(e);
// keep iterating since multiple keys can
// map to the same value.
}
}
You can get all of your keys with hash_map.keySet()
https://www.geeksforgeeks.org/hashmap-keyset-method-in-java/
Yes, you can use iterators, which enable you to iterate over any Collection (or Map's entrySet()):
public class Main {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("First", "Entry");
System.out.println(map.entrySet().iterator().next());
}
}
This prints: First=Entry, where First is the key and Entry is the value.
hashMapObj.entrySet().iterator().next();
is the answer to your question.
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);
...
}
I have a hash map type array list:
public static ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
It has some IDs and Names like this:
This is the code that is used to loop through:
for (HashMap<String, String> map : mylist)
for (Entry<String, String> entry : map.entrySet())
if(entry.getValue().contains(typedText)){
map1 = new HashMap<String, String>();
map1.put("id", entry.getKey());
map1.put("name", entry.getValue());
mylist1.add(map1);
}
Problem is that in this line:
for (Entry<String, String> entry : map.entrySet())
map.entrySet() shows correct ID and the Name like this:
But only Name is available with 'entry':
entry.getKey() always returns the text 'name' which is the key and entry.getValue() returns 'Katie Bailey' which is the value.
My question is why am I not getting the key with entry.getKey()? Why do I always get 'name' as the key with each iteration?
I suspect you're getting confused by the debugger's visualization of the map. When it's showing this:
{id=2990511, name=Katie Bailey}
that's showing that your map has two entries - one with a key of id and a value of "2990511", and one with a key of name and a value of "Katie Bailey".
You're then looping over all those entries, and if the value matches you're adding two entries into a second map: one entry with the key id and a value which is the key of the entry you're looking at, and a second entry with the key name and a value which is the value of the entry you're looking at. You're not using the whole of the original map - you're just using that single entry.
So if you match on the entry of name=Katie Bailey you end up with a new map containing two entries:
{id=name, name=Katie Bailey}
It's not really clear what you were expecting, but the results you've shown make perfect sense with your code.
I suspect you actually want something like:
for (HashMap<String, String> map : mylist) {
String name = map.get("name");
if (name.contains(typedText)) {
// Create a copy of the whole map
mylist1.add(new HashMap<String, String>(map));
}
}
If you've got fixed keys though, you should at least consider creating a type to encapsulate the data - e.g. a Person class with getName() and getId() methods.
The issue is map only takes unique values for the key, therefore, if a key exists in the map, it cannot be re-inserted in the map, that results in you getting the first matching value.
For that matter you have to provide different keys to be substituted. Using a string such as "id" or "name" for the key means that key does not change, and so does the value.
Refer to Java HashMap API
If I extract an element from a hash map through the method get(<key>) and update the extracted element, will these updates persist in the map? Or do I have to re-insert the element back to the hash map?
If you change fields of the object you got out, like this...
Thing thing = map.get(key);
thing.setOtherThing(yetAnotherThing);
then that'll update the value in the map.
On the other hand, if you modify the reference that you obtained by getting a value out of the map...
Thing thing = map.get(key);
thing = doSomethingWith(thing);
then you need to put it back into the map.
If you modify the object obtained by the Map.get(K) method, the object does not need to be re-inserted. However, if you change a key in a way that the hashCode() function is affected, then you need to remove the map entry before modifying the key and then you can put back your value using your new key.
Consider the following map corruption case:
Map<List<String>, String> map = new HashMap<List<String>, String>();
List<String> key1 = new ArrayList<String>();
key1.add("key1");
map.put(key1, "value1");
System.out.println(map.get(key1)); //prints "value1"
key1.add("buzz2");
System.out.println(map.get(key1)); //prints "null"
List<String> k = map.keySet().iterator().next();
System.out.println(map.get(k)); //prints "null"
Morale of the story: for maps, always use immutable keys like String or int.
I want to get all the values associated with a key in Map.
For e.g,
Map tempMap = new HashMap();
tempMap.put("1","X");
tempMap.put("2","Y");
tempMap.put("3","Z");
tempMap.put("1","ABC");
tempMap.put("2","RR");
tempMap.put("1","RT");
How to retrieve all the values associated with key 1 ?
the thing you must understand is that in a Map, the key is unique.
that means that after
tempMap.put("1","X");
"1" is mapped to "X"
and after
tempMap.put("1","ABC");
"1" is mapped to "ABC" and the previous value ("X") is lost
From the HashMap javadoc:
public V put(K key, V value)
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.
What you can do is this:
Map<String, List<String>> tempMap = new HashMap<String, List<String>>();
tempMap.put("1", new LinkedList<String>());
tempMap.get("1").add("X");
tempMap.get("1").add("Y");
tempMap.get("1").add("Z");
for(String value : tempMap.get("1")) {
//do something
}
This compartmentalizes values that correspond to the key "1" into their own list, which you can easily access. Just don't forget to initialize the list... else NullPointerExceptions will come to get you.
Yuval =8-)
can't
try using google collections's Multimap
I think you're missing something important:
Map tempMap = new HashMap();
tempMap.put("1","X");
tempMap.put("2","Y");
tempMap.put("3","Z");
tempMap.put("1","ABC"); // replaces "X"
tempMap.put("2","RR"); // replaces "Y"
tempMap.put("1","RT"); // replaces "ABC"
Also, you should use generics where possible, so your first line should be:
Map<String, String> tempMap = new HashMap<String, String>();
To do that you have to associate each key with a Set of values, with corresponding logic to create the set and enter/remove values from it instead of simple put() and get() on the Map.
Or you can use one of the readymade Multimap implementations such as the one in Apache commons.