Multi hashmap containsValue - java

I have a hashmap as follows
Map <String, List<String>> map = new HashMap <String, List<String>>();
After I did a map.put(), my map looks something like this:
Key - key1
Values - [value1]
Key - key2
Values - [value1, value2, value3]
Now I am reading a line from a file. File is like this:
Key:key2, Value:value1
I am storing the key1 and value1 in 2 elements called keyRead and valueRead. Inside the line reader, if I am using containsKey() and containsValue(), it is not working.
if(map.containsKey(keyRead){
S.O.P("Inside key match");
if(map.containsValue(valueRead){
S.O.P ("Inside value match");
}
}
The output is showing the inside key match but it is not showing the inside value match.
Can someone please tell me what I am missing here?

You need to do something like
if(map.containsKey(keyRead)) {
if(map.get(keyRead).contains(valueRead)) {
System.out.println("Inside value match");
}
}

Your values are lists, not strings. If you need to check if the string is contained by the list, you need to get the list first, then invoke the contains method of that list, passing the string as argument.

i think you have to loop through the values in the list like this, btw i have not tested the code -
if(map.containsKey(keyRead){
S.O.P("Inside key match");
forEach(List l: map.get(keyRead)) {
forEach(String s : l) {
if(s.equals(valueRead)) {
S.O.P ("Inside value match");
}
}
}
}

As has been pointed out, you cannot do a containsValue using an instance where the value is a List. Try using Guava's Multimap. This implements a Map where a key maps to multiple values.
Multimap has a containsEntry(key, value) that works exactly as you desire in that it matches the key and that the list associated with the key contains the value.

Related

How Can I search a Integer in a TreeMap<String, List<Integer>>? [duplicate]

I'm checking to see if a key in my HashMap exists, if it does, I also want to check to see if any other keys have a value with the same name as that of the original key I checked for or not.
For example I have this.
System.out.println("What course do you want to search?");
String searchcourse = input.nextLine();
boolean coursefound = false;
if(hashmap.containsKey(searchcourse) == true){
coursefound = true;
}
This checks to see if the key exists in my hashmap, but now I need to check every single key's values for a specific value, in this case the string searchcourse.
Usually I would use a basic for loop to iterate through something like this, but it doesn't work with HashMaps. My values are also stored in a String ArrayList, if that helps.
You will want to look at each entry in the HashMap. This loop should check the contents of the ArrayList for your searchcourse and print out the key that contained the value.
for (Map.Entry<String,ArrayList> entries : hashmap.entrySet()) {
if (entries.getValue().contains(searchcourse)) {
System.out.println(entries.getKey() + " contains " + searchcourse);
}
}
Here are the relevant javadocs:
Map.Entry
HashMap entrySet method
ArrayList contains method
You can have a bi-directional map. E.g. you can have a Map<Value, Set<Key>> or MultiMap for the values to keys or you can use a bi-directional map which is planned to be added to Guava.
As I understand your question, the values in your Map are List<String>. That is, your Map is declares as Map<String, List<String>>. If so:
for (List<String> listOfStrings : myMap.values()) [
if (listOfStrings .contains(searchcourse) {
// do something
}
}
If the values are just Strings, i.e. the Map is a Map<String, String>, then #Matt has the simple answer.

Multimap how to return all values from a key

Multimaps can have multiple values how would I be able to return all the values from a key if it contains multiple values.
Multimap<String, String> wordcount = ArrayListMultimap.create();
wordcount.put("1", "Dog");
wordcount.put("1", "Dog2");
wordcount.put("1", "Dog3");
So you can see above I gave my Multimap key "1" the following values "Dog", "Dog2" & "Dog3" how would I be able to print out all the dogs?
Extra Questions
How would I be able to check if a key contains multiple values of the same string for that specific key? Also how would I be able to return the amount of "same" strings it contains. It should return 3 because I specified the value 3 times with the same value so it should return 3.
wordcount.put("1", "Dog");
wordcount.put("1", "Dog");
wordcount.put("1", "Dog");
You can just do wordcount.get("1") it will return a List containing Dog1, Dog2, Dog3
For your extra question: I think you have to do wordcount.get("1") to get the List object and iterate through the list object if you want to use an ArrayListMultimap instance.
Alternatively, you may want to checkout Multiset<String> that keeps track of number of occurrences of your input Strings. In this case you can use Map<String, Multiset<String>> instead of ArrayListMultimap instance to avoid iterating the returned list.
But Multiset<?> is a set so it does not iterate in the order you put the values.
The get method returns a list of values for a given key. You could just rely on the returned List's toString():
System.out.println(wordcount.get("1"));
Or just iterate over them and print each one separately:
for (String s : wordcount.get("1")) {
System.out.println(s);
}
Or join all the values in that list to a single string somehow, e.g., by using a Joiner:
System.out.println(Joiner.on(",").join(wordcount.get("1"))

Selective and Specific printing of hash Map key - value pairs

While writing test automation, i was required to leverage the api's provided by the developers and these api accepts HashMap as arguments. The test code involves calling several such api with hashmap as the parameter as shown below.
Map<String,String> testMap = new HashMap<String,String>();
setName()
{
testMap.put("firstName","James");
testMap.put("lastName","Bond");
String fullName=devApi1.submitMap(testMap);
testMap.put("realName",fullName);
}
setAddress()
{
testMap.put("city","London");
testMap.put("country","Britain");
testMap.put("studio","Hollywood");
testMap.put("firstName","");
testMap.put("person",myMap.get("realName"));
devApi2.submitMap(testMap);
}
However the requirement was to print the testMap in both setName and setAddress functions, but the map should print only those elements (key-value pairs) in alternate lines which are set in the respective function. I mean setName should print 2 elements in the Map which are set before submitMap api is invoked and similarly setAddress should print 5 elements which are set before submitMap is invoked.
setName Output must be:
The data used for firstName is James.
The data used for lastName is Bond
setAddress Output must be:
The data used for city is London.
The data used for country is Britain.
The data used for studio is Hollywood.
The data used for firstName is null.
The data used for person is James Bond
Any help, in order to acheive this?
I would probably write a helper function that would add items to the map and do the printing.
public static <K,V> void add(Map<K,V> map, K key, V value){
System.out.println(String.format("The data used for \"%s\" is \"%s\"", key, value));
map.put(key, value);
}
If you need to print different messages you could either use different helper functions or pass format string as an argument.
I would create a method which takes a comma separated list of keys as argument and print only them.
Something like:
public void printKeys(Map<String,String> map, String csKeys) {
for(String key: csKeys.split(",")){
if(map.conatinsKey(key)){
System.out.println("The data used for " + key + " is " + map.get(key) );
}
}
}
and you can invoke it like:
printKeys(testMap, "firstName,lastName");
printKeys(testMap, "city,country,studio");
You'd better create a copy of your testMap when you invoke the submitMap method, since you don't have a flag to indicate which key-value pairs should be printed.
You could do it like
Map<String, String> printObj = new HashMap<String, String>
setName()
{
testMap.put("firstName","James");
testMap.put("lastName","Bond");
String fullName=devApi1.submitMap(testMap);
printObj.addAll(testMap);
testMap.put("realName",fullName);
}
Then print the printObj instead of testMap.
From you comments on my earlier answer it seems you don't want the values put from one method to be displayed in the second one...
That can be done easily, just place:
testMap.clear();
in the beginning of every method.

Returning a list of wildcard matches from a HashMap in java

I have a Hashmap which may contain wildcards (*) in the String.
For instance,
HashMap<String, Student> students_;
can have John* as one key. I want to know if JohnSmith matches any elements in students_. There could be several matches for my string (John*, Jo*Smith, etc). Is there any way I can get a list of these matches from my HashMap?
Is there another object I could be using that does not require me to iterate through every element in my collection, or do I have to suck it up and use a List object?
FYI, my collection will have less than 200 elements in it, and ultimately I will want to find the pair that matches with the least amount of wildcards.
It's not possible to achieve with a hasmap, because of the hashing function. It would have to assign the hash of "John*" and the hash of "John Smith" et al. the same value.
You could make it with a TreeMap, if you write your own custom class WildcardString wrapping String, and implement compareTo in such a way that "John*".compareTo("John Smith") returns 0. You could do this with regular expressions like other answers have already pointed out.
Seeing that you want the list of widlcard matchings you could always remove entries as you find them, and iterate TreeMap.get()'s. Remember to put the keys back once finished with a name.
This is just a possible way to achieve it. With less than 200 elements you'll be fine iterating.
UPDATE: To impose order correctly on the TreeSet, you could differentiate the case of comparing two WildcardStrings (meaning it's a comparation between keys) and comparing a WildcardString to a String (comparing a key with a search value).
You can use regex to match, but you must first turn "John*" into the regex equivalent "John.*", although you can do that on-the-fly.
Here's some code that will work:
String name = "John Smith"; // For example
Map<String, Student> students_ = new HashMap<String, Sandbox.Student>();
for (Map.Entry<String, Student> entry : students_.entrySet()) {
// If the entry key is "John*", this code will match if name = "John Smith"
if (name.matches("^.*" + entry.getKey().replace("*", ".*") + ".*$")) {
// do something with the matching map entry
System.out.println("Student " + entry.getValue() + " matched " + entry.getKey());
}
}
You can just iterate your Map without converting it into a list, and use the String matches function, wih uses a regexp.
If you want to avoid the loop, you can use guava like this
#Test
public void hashsetContainsWithWildcards() throws Exception {
Set<String> students = new HashSet<String>();
students.add("John*");
students.add("Jo*Smith");
students.add("Bill");
Set<String> filteredStudents = Sets.filter(students, new Predicate<String>() {
public boolean apply(String string) {
return "JohnSmith".matches(string.replace("*", ".*"));
}
});
assertEquals(2, filteredStudents.size());
assertTrue(filteredStudents.contains("John*"));
assertTrue(filteredStudents.contains("Jo*Smith"));
}

What is inside an empty index of a Hashmap?

I have a hashmap that is 101 keys in size, but I know for sure about 6 of those have no data inside, and there may be more without data as well. What exactly is inside the empty indexes? Is it null? or is there a Hash(index).isEmpty() method that I can use to see if its empty?
I realize there is a isEmpty method inside hashmap, but I thought that only checked if the entire map was empty not just a single index.
I realize there is a isEmpty method
inside hashmap, but I thought that
only checked if the entire map was
empty not just a single index.
I think what you're looking for is the containsKey(Object) method. According to the documentation:
Returns true if this map contains a
mapping for the specified key. More
formally, returns true if and only if
this map contains a mapping for a key
k such that (key==null ? k==null :
key.equals(k)). (There can be at most
one such mapping.)
Parameters:
key - key whose presence in this map is to be tested
Returns:
true if this map contains a mapping for the specified key
Well, for the keys to arrive there with no data, you have to put them there.
If you did map.put(key, null) then yes the data for that key is null. You always have to give the second parameter to the method, you can't just map.put(key).
If you know for sure that a certain key should have no data you could try going into debug mode and putting a watch for myMap.get(myEmptyKey) and see what you get (in case that no data is an empty object or something else, you should be able to see that).
Edit: Some code would be useful to help you, but if I understand correctly you do something like this:
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
map.put("X", obj);
else if (matchesCriteriaY(obj)) {
map.put("Y", obj);
}
}
Well, if you do that and try to do map.get("X"), but you never actually put anything for that key (becaus no object matched criteria X), you will most definitely get back a null.
On the other hand, if you did something like
Map<String, List<Object>> map = new HashMap<String, List<Object>>();
map.add("X", new ArrayList<Object>());
map.add("Y", new ArrayList<Object>());
for (Object obj : list) {
if (matchesCriteriaX(obj)) {
List<Object> list = map.get("X");
list.add(obj);
else if (matchesCriteriaY(obj)) {
List<Object> list = map.get("Y");
list.add(obj);
}
}
then you could check if a category is empty by doing map.get("x").isEmpty() since List has that method (and it would be empty if no object matched the key criteria).
Judging from what you said, I'm suspecting something like this:
Map<SomeKey, List<SomeValue>> yourMap;
If this is the case, what you can do is
if( yourMap.contains(someKey) ){
List<SomeValue> someList = yourMap.get(someKey);
if(someList.size() == 0){
// it's empty, do something?
}
}

Categories