I have the following key-value system (HashMap) , where String would be a key like this "2014/12/06".
LinkedHashMap<String, Value>
So, I can retrieve an item knowing the key, but what I'm looking for is a method to retrieve a list of the value which key matches partialy, I mean, how could I retrieve all the values of 2014?.
I would like to avoid solutions like, test every item in the list, brute-force, or similar.
thanks.
-
If you regularly need to access the items in this way then you may wish to invest in a MapFilter.OldCurmudgeon– OldCurmudgeon2014年12月08日 10:46:39 +00:00Commented Dec 8, 2014 at 10:46
4 Answers 4
Apart from doing the brute-force solution of iterating over all the keys, I can think of two options :
Use a TreeMap, in which the keys are sorted, so you can find the first key that is>= "2014/01/01" (using
map.getCeilingEntry("2014/01/01")
) and go over all the keys from there.Use a hierarchy of Maps - i.e.
Map<String,Map<String,Value>>
. The key in the outer Map would be the year. The key in the inner map would be the full date.
-
hierarchy of Maps seems to be a really good solution, thanks.Octal– Octal2014年12月08日 10:53:33 +00:00Commented Dec 8, 2014 at 10:53
Not possible with LinkedHashMap only. If you can copy the keys to an ordered list you can perform a binary search on that and then do a LinkedHashMap.get(...) with the full key(s).
If you're only ever going to want to retrieve items using the first part of the key, then you want a TreeMap
rather than a LinkedHashMap
. A LinkedHashMap
is sorted according to insertion order, which is no use for this, but a TreeMap
is sorted according to natural ordering, or to a Comparator
that you supply. This means that you can find the first entry that starts with 2014
efficiently (in log time), and then iterate through until you get to the first one that doesn't match.
If you want to be able to match on any part of the key, then you need a totally different solution, way beyond a simple Map
. You'd need to look into full text searching and indexing. You could try something like Lucene.
You could refine a hash function for your values so that values with similar year would hash around similar prefixed hashes. That wouldn't be efficient (probably poor distribution of hashes) nor to the spirit of HashMaps. Use other map implementations such as TreeMaps that keep an order of your choice.
Explore related questions
See similar questions with these tags.