HashMap selections = new HashMap<Integer, Float>();
How can i get the Integer key of the 3rd smaller value of Float in all HashMap?
Edit im using the HashMap for this
for (InflatedRunner runner : prices.getRunners()) {
for (InflatedMarketPrices.InflatedPrice price : runner.getLayPrices()) {
if (price.getDepth() == 1) {
selections.put(new Integer(runner.getSelectionId()), new Float(price.getPrice()));
}
}
}
i need the runner of the 3rd smaller price with depth 1
maybe i should implement this in another way?
You could do it with the google collections BiMap, assuming that the Floats are unique.
Are you sure you're using hashmaps right? They're used to quickly lookup a value given a key; it's highly unusual to sort the values and then try to find a corresponding key. If anything, you should be mapping the float to the int, so you could at least sort the float keys and get the integer value of the third smallest that way
Michael Mrozek nails it with his question if you're using
HashMap
right: this is highly atypical scenario forHashMap
. That said, you can do something like this:Set<Map.Entry<K,V>>
from theHashMap<K,V>.entrySet()
.addAll
toList<Map.Entry<K,V>>
Collections.sort
the list with a customComparator<Map.Entry<K,V>>
that sorts based onV
.Map.Entry<K,V>
only, then aO(N)
selection algorithm may suffice.//after edit
It looks like
selection
should really be aSortedMap<Float, InflatedRunner>
. You should look atjava.util.TreeMap
.Here's an example of how
TreeMap
can be used to get the 3rd lowest key:Also note how I take advantage of Java's auto-boxing/unboxing feature between
int
andInteger
. I noticed that you usednew Integer
andnew Float
in your original code; this is unnecessary.//another edit
It should be noted that if you have multiple
InflatedRunner
with the same price, only one will be kept. If this is a problem, and you want to keep all runners, then you can do one of a few things:TreeMap<Float,Set<InflatedRunner>>
MultiMap
from Google CollectionsList<RunnerPricePair>
(sorry, I'm not familiar with the domain to name it appropriately), whereRunnerPricePair implements
Comparable<RunnerPricePair>
that compares on prices. You can just add all the pairs to the list, then either:Collections.sort
the list and get the 3rd pairYou have to do it in steps:
Collection<V>
of values from the MapThink about how you want to handle ties.
If you regularly need to get the key of the nth item, consider:
You have to weigh up the inelegance and potential risk of bugs from needing to maintain two maps with the scalability benefit of having a structure that efficiently keeps the keys in order.
You may need to think about two keys mapping to the same float...
P.S. Forgot to mention: if this is an occasional function, and you just need to find the nth largest item of a large number of items, you could consider implementing a selection algorithm (effectively, you do a sort, but don't actually bother sorting subparts of the list that you realise you don't need to sort because their order makes no difference to the position of the item you're looking for).