user3924402
user3924402

Reputation: 13

Getting integer in HashMap without Iterating

If I have:

HashMap<String, Integer> hm = new HashMap<String, Integer>();

Am I able to get all Strings based off an integer without iterating through the whole HashMap? If this isn't possible, what is the best way to handle this?

Upvotes: 1

Views: 57

Answers (3)

Daniel Pryden
Daniel Pryden

Reputation: 60957

There is no way to do this with a HashMap other than iterating.

The data structure you want is typically called a bi-directional map, or BiMap -- this allows you to map both from keys to values (from String to Integer, in your case) but also back from values to keys (from Integer to String). This only works if your key-value mappings are unique, since your values are now also keys as well.

The Google Guava library has a BiMap interface and several implementations to choose from.

Edit: Given your comment:

I need to get all string associated with an int, ie, if I have "Pie", "1" - "Apple", "1" - "Fruit", 2, I need to be able to specify "1" and get Pie and Apple back

What you actually want is a Multimap<Integer, String>. Depending on the use case, Multimaps.invertFrom may also be useful.

Upvotes: 1

Makoto
Makoto

Reputation: 106400

No, you'd have to iterate over the contents of that map to get an integer for a string. The reason for that is that you have your key set to be the arbitrary string you want, and the value is the integer you're searching on.

If you had the integer, you could iterate over the entry set instead:

for(Map.Entry<String, Integer> entry : hm.entrySet()) {
    if(entry.value().equals(searchValue) {
        // logic
    }
}

But this kind of takes the idea of using a map for this and turns it on its head.

Think of it like a dictionary. Treat the word and the definition as a key and a value, respectively. If you know the word you want to look up, then you're provided the value relatively quickly - it's in alphabetic order.

But, how do you search the dictionary if all you know is the definition? You'd have to look at every definition until you came across the exact one you had, and then you could get the key from it.

The same thing is happening here. Instead of using an index to search your data structure, you're now going over every possible value inside of it to fetch a particular key.

For larger data sets, this is completely untenable.

I would recommend a BiMap from Google Guava, with a few caveats:

  • Both keys and values must be unique
  • Consider that this may be overkill for what you want to do; it may be simpler to reverse the key-value pairing and use the integer as your key instead.

Also, per your comments, you may even want to look into a Multimap instead. It allows you to provide one key for multiple, different values, which may fit the use case you're trying to go for.

Here's an example implementation:

    Multimap<Integer, String> dataSet = HashMultimap.create();

    dataSet.put(1, "foo");
    dataSet.put(1, "bar");
    dataSet.put(1, "baz");

    // prints [baz, bar, foo]
    System.out.println(dataSet.get(1));

Upvotes: 3

Hannes
Hannes

Reputation: 2073

You cannot get a subset of your keys, that "share" the same key value using a hashmap that way.

To get the data, you coud use HashMap<Integer, List<String>> as construction.

Upvotes: 0

Related Questions