Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 657
Sarah Avatar asked Sep 30 '11 12:09

Sarah


2 Answers

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).

like image 54
Xavi López Avatar answered Nov 15 '22 15:11

Xavi López


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());
    }
}
like image 41
Bohemian Avatar answered Nov 15 '22 14:11

Bohemian