Matching a value of HashMap to values in a HashSet - java

I am trying to match the values of the key in the contextMap to a set of string. I know there is a clear match but despite that I get an empty map in my output. Is it correct to use the contains() method in this case?
The context map contents look like:
[Rhode Island ]=[leftWords: [fellow], rightWords: [solution,
provider]]
And the roleContexts set looks like :
[recent performance, has earned , holdings in , senior vice president
of, solution provider , pharmaceuticals, has launched ]
Here the word solution provider should be a match, thus the key Rhode Island should by put in the output map with he corresponding role (Location in this case).
for(Entry<Set<String>, Set<Words>> entry : contextMap.entrySet()) {
for (String key : entry.getKey()){
for (Words value : entry.getValue()) {
for(SemanticRole role : roleContextsMap.keySet())
{
Set<String> roleContexts = roleContextsMap.get(role);
if(roleContexts.contains(value.getLeftWords().toString().replaceAll("\\[|\\]","").replaceAll(","," ").toLowerCase())
|| roleContexts.contains(value.getRightWords().toString().toString().replaceAll("\\[|\\]","").replaceAll(","," ").toLowerCase()))
{
Set<String> roleStrings = roleStringsMap.containsKey(role)
? roleStringsMap.get(role) : new HashSet<String>();
roleStrings.add(key);
roleStringsMap.put(role, roleStrings);
}
}

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.

Unsure how this piece of code is doing what it does… .getDescribe()

I'm relatively new to Apex and Java.
Could someone possibly explain this snippet of code?
Map<String, SObjectField> m = Opportunity.SObjectType.getDescribe().fields.getMap();
for (String name : m.keySet()) {
DescribeFieldResult r = m.get(name).getDescribe();
System.debug(r);
}
I know it's getting the Describe information for each field on the Opportunity object, but could someone explain, line by line, how it's doing it?
Cheers!
This is about as basic as it gets when you need to enumerate a map:
Line 1 gets the map, and stores it in variable m
Line 2 iterates over the keys of the map m, using name variable for the value of the key in this iteration
Line 3 gets the item from the map m using name for the key, and calls getDescribe
Line 4 passes the result to System.debug
Line 5 closes the loop
However, this is not the best way of iterating the values, though: a simpler approach would be as follows:
Map<String, SObjectField> m = Opportunity.SObjectType.getDescribe().fields.getMap();
for (SObjectField val : m.values()) {
System.debug(val.getDescribe());
}
For completeness, if you would like to iterate both keys and values, iterate entrySet, like this:
Map<String, SObjectField> m = Opportunity.SObjectType.getDescribe().fields.getMap();
for (Map.Entry<String,SObjectField> e : m.entrySet()) {
// e.getKey() produces the key
// e.getValue() produces its associated value
}
Iterating keys and then retrieving the values in a separate call to get is inefficient.

Compare two lists & print elements which are repeating in second list

I have searched but couldn't find specific to what I was looking for.
I have a duplicate list got from Main List.
E.G.:
duplicateSet { D16A, D2243A, D2235A}
xConnectors { D16A, xxx, xxxx, xxxx, D16A, xxxx , D2243A ,xxxx, D2243A, xxxx, D2235A, xxxx, xxxx, D2235A}
I wrote this code
Set duplicateConnectors = new HashSet();
for(String s : duplicateSet)
{
for(IXConnector xCon : xConnectors)
{
if(s.equals(xCon.getAttribute("Name")))
{
duplicateConnectors.add(xCon);
vReporter.report(getDefaultSeverity(), "Connector {0} is duplicate", xCon);
}
}
}
The o/p I get is
Connector D16A is duplicate
Connector D16A is duplicate
Connector D2243A is duplicate
Connector D2243A is duplicate
But I need the above o/p in one single line.
Connectors D16A and D16A are duplicates.
Connectors D2243A and D2243A are duplicates.
Your current code runs in quadratic time i.e. O(n^2) and that is not a very scalable solution, because as your input will grow your running time will grow quadratically.
You should utilize a Hash Set to your advantage here, a hash set is a set that does not allow duplicates and items are hashed into an indexed array hence you receive constant time performance for insertion and contains. You now have one loop to check whether a connector name is found in the hashset earlier, if it is then it is a duplicate, this check is also constant time. So your whole algorithm becomes linear.
Set<String> dupes = new HashSet<String>();
for(String s : duplicateSet)
dupes.add(s);
for(IXConnector xCon : xConnectors)
{
String name = xCon.getAttribute("Name");
if(dupes.contains(name))
vReporter.report(getDefaultSeverity(), "Connectors {0} and {0} are duplicates.", xCon);
}
If you want to print the message only once, you can change the HashSet to a HashMap and use a boolean as a value to represent whether or not you have printed a message yet.
Map<String, Boolean> dupes = new HashMap<String, Boolean>();
for(String s : duplicateSet)
dupes.put(s, false);
for(IXConnector xCon : xConnectors)
{
String name = xCon.getAttribute("Name");
if(dupes.containsKey(name) && dupes.get(name) == false)
{
vReporter.report(getDefaultSeverity(), "Connectors {0} and {0} are duplicates.", xCon);
dupes.put(name, true);
}
}

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"));
}

How to Iterate Through Multiple Maps

So essentially, I have two hashmaps, one containing the following values:
rId33=image23
rId32=image22
rId37=image2
And the other containing this data:
{image2.jpeg=C:\Documents and Settings\image2.jpeg, image22.jpeg=C:\Documents and Settings\image22.jpeg, image23.jpeg=C:\Documents and Settings\image23.jpeg}
I basically want to be able to iterate through the first map, find a match of the key's, if a match is found, get the associated value, then look in the second map, find a match in the keys, then pull out the associated value (meaning the file path).
I was thinking of doing something like this for example (the follow is simplified)...
String val2 = "rId33";
for (String rID: map.keySet())
{
if (rID.contains(val2))
{
//enter code here
}
}
I was looking at the methods available for something like .getValue or something, but I'm not entirely sure how to do that. Any help would be appreciated. Thanks in advance for any replies.
Edited Code with Help From Bozho
else if ("v:imagedata".equals(qName) && headingCount > 0)
{
val2 = attributes.getValue("r:id");
String rID = imageMap.get(val2);
String path = imageLocation.get(rID + ".jpeg");
for (String rels: imageMap.keySet())
{
if (rels.contains(val2))
{
inImage = true;
image docImage = new image();
imageCount++;
docImage.setRelID(val2);
docImage.setPath(path);
addImage(docImage);
}
}
From what I see you don't need to iterate. Just:
String value1 = map1.get(key1);
if (value1 != null) {
String path = map2.get(value1 + ".jpeg");
}
If you don't always know whether it's value1 + ".jpeg", but you just know that the key starts with the first value, then you can iterate the 2nd map with:
for (Map.Entry<String, String> entry : map2.entrySet()) {
String key2 = entry.getKey();
String value2 = entry.getValue();
if (key.startsWith(value1)) {
return value2;
}
}
But note that the first code snippet is O(1) (both operations take constant time), while the 2nd is O(n)
And to answer the question as it is formulated in the title:
Get the iterators of both maps, and use it1.next() and it2.next() within a while loop. If any of the maps doesn't have more elements (it.hasNext()) - break.
That seems very inefficient. The entire point of a hash map is to do fast lookups. Do you really need to use that contains call on rID? In other words, can you change your hash map so that it directly contains the verbatim strings you want to search for and not just strings that contain the strings you want to search for as substrings? If yes, you could then use the answer given already. If not and if you must work with these data structures for whatever reason, the way to do what you're trying to do is something like:
String val2 = "rId33";
String path;
for (String rID: map.keySet())
{
if (rID.contains(val2))
{
path = secondMap.get(map.get(rID)+".jpeg");
break;
}
}
if (path == null)
{
//value not found
}

Categories