In Mysql we can query a table having clause " WHERE name LIKE '%someName%' ", can we have the same functionality with HashMap in java,if so how can we achieve this more efficiently in a less time by not iterating over each element?
-
3just loop with some regex, or create your own map impl – epoch Apr 17 '14 at 09:32
-
Is "name" the key or the value in your map? Would you like to return a list of keys or values? – Joffrey Apr 17 '14 at 09:34
-
"name" is a key in a map – achuth Apr 17 '14 at 09:36
-
1How efficient do you want it to be? You can do a brute force search of HashMap, or you can use a NavigableMap efficiently, but the code is far more complicated. i.e. if a brute force search isn't obvious to you, don't attempt using a NavigableMap. – Peter Lawrey Apr 17 '14 at 09:37
-
I need to search for key in a large number of keys more frequently – achuth Apr 17 '14 at 09:43
5 Answers
If you're using Java SE 8 and the new Streams API: there is a filter method which basically is what you are looking for, I think.
e.g. something like (untested!):
myMap.entrySet().stream().filter(entry -> entry.getKey().contains("someName")).map(entry -> entry.getValue()).collect(Collectors.toList());

- 37,247
- 13
- 80
- 152
-
Thank you @Puce! I just needed the key part, so `myMap.entrySet().stream().filter(entry -> entry.getKey().contains("someName")).collect(Collectors.toList());` was enough – hestellezg Apr 17 '19 at 21:27
You can iterate on all your keys and check if they match a regexp. This might not be the most efficient way of doing it, but it's the first thing I thought of. Here is what it would look like:
Pattern p = Pattern.compile("*someName*"); // the regexp you want to match
List<String> matchingKeys = new ArrayList<>();
for (String key : map.keySet()) {
if(p.matcher(key).matches()) {
matchingKeys.add(key);
}
}
// matchingKeys now contains the keys that match the regexp
Note: map
is supposed to be declared earlier like this:
HashMap<String, SomeValueClass> map = new HashMap<>();

- 32,348
- 6
- 68
- 100
-
This will upto my need functionality wise, but i am thinking about large set of key values which has to be iterated large number of times – achuth Apr 17 '14 at 09:59
-
@achuth Then why not use a real database? How much memory your program will need anyway if the number of keys is that large? – Joffrey Apr 17 '14 at 09:59
-
Actually i get all keys from a column in a table from database, of size 62Kb – achuth Apr 17 '14 at 10:03
-
@achuth Then why don't you use the `LIKE` SQL keyword when you get the info? I think it will be more efficient than loading everything in memory and iterate on everything many times in a row. – Joffrey Apr 17 '14 at 10:05
-
All the key are stored in JSON format in a single row of a single coumn – achuth Apr 17 '14 at 10:07
-
Hash map is faster in getting a value than iterating over a list or array by comparing each element, if there is no way in doing this i would directly use a array rather than a HashMap – achuth Apr 17 '14 at 10:29
-
@achuth Storing JSON in a database does not seem a good idea to me, why would you do such a thing? You might want to re-design your DB tables to fit the JSON fields. Then, you can load your stuff in a HashMap (if it fits in your memory) for indivual value accesses, and do SQL queries for large regexp accesses. – Joffrey Apr 17 '14 at 11:04
-
@achuth Here is some wise advice on whether to store JSON or not in the DB: http://stackoverflow.com/a/15367769/1540818 – Joffrey Apr 17 '14 at 11:14
Remove all values which doesn't contain key part:
yourMap.keySet().removeIf(key -> !key.contains(keyPart));
Or regex:
yourMap.keySet().removeIf(key -> !key.matches(".*keyPart.*"));

- 8,220
- 10
- 69
- 114
There may be a way to achieve this functionality in Java, but HashMap
will not do it.

- 71,677
- 44
- 195
- 329
If you want to get all the values in a map that are associated to a given key you are doing a reverse lookup.
You would need to iterate over every key / value pair in the map, searching for the given value and storing it into a collection. Something like this:
List<KeyType> keys = new ArrayList<>();
for (Map.Entry<KeyType, ValueType> e : myMap)
if(e.getValue().equals(valueWeAreSearchingFor)) keys.add(e.getKey());

- 2,301
- 23
- 29
-
What happens when searching a map having some 1000's of key's frequently? – achuth Apr 17 '14 at 09:39
-
This might not meet the OP's needs, because he wanted to match a pattern, not an exact value. – Joffrey Apr 17 '14 at 09:47
-
@achuth Well, you have to iterate over the entire map, so it's going to be *slow*. Consider using something like a [BidiMap](http://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/BidiMap.html) – robertoia Apr 17 '14 at 09:48
-
@Joffrey True, I didn't get that part of the question. Your answer is better then, upvoting. – robertoia Apr 17 '14 at 09:49