Returning a list of wildcard matches from a HashMap in java

11,034

Solution 1

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

Solution 2

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());
    }
}
Share:
11,034
Sarah
Author by

Sarah

Updated on July 20, 2022

Comments

  • Sarah
    Sarah almost 2 years

    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.

  • Sarah
    Sarah over 12 years
    Thank you, Xavi. For a list of 200 do you think there will be any performance benefit to using a TreeSet?
  • Jim
    Jim over 12 years
    Creating a compareTo(string) method in the WildCardString class would break the contract of the compareTo method because: wildCardString.compareTo(string) may not be the opposite sign or string.compareTo(wildCardString). Additionally it's recommended that compareTo is consistent with equals.
  • Bohemian
    Bohemian over 12 years
    @Guillaume no he specifically did NOT say that. Specifically, he said: 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 ?. I answered the question by confirming the OR part.
  • Guillaume
    Guillaume over 12 years
    Bohemian, you sophist :-) I agree with your answer anyway. I don't see why he doesn't want to iterate.