Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obtain key of a hashmap with a range of numbers as value

Tags:

java

I have a HashMap<Integer, Float> with entries:

 1 -> 0.127
 2 -> 0.167
 3 -> 0.207
 4 -> 0.247
 5 -> 0.237
 6 -> 0.327
 7 -> 0.367
 8 -> 0.407
 9 -> 0.447
10 -> 0.487
11 -> 0.527
12 -> 0.567
13 -> 0.607
14 -> 0.647
15 -> 0.652

Let suppose that I want the key to the Float 0.465 (which is not an existing value). 0.465 is between 0.447 and 0.487, so I would like to get the key 10.

The first thought that came in my mind was achive this with 15 if/else if statements or with the switch statement. But in my view, this wouldn't be very elegant and practical.

Is there any other way to do this?

like image 911
zearthur99 Avatar asked Jul 16 '15 22:07

zearthur99


2 Answers

A Map is not the appropriate data structure. Use a TreeSet instead:

TreeSet<Float> numbers = new TreeSet<>();
// populate the set with your numbers, in any order, then

int index = numbers.headSet(n).size() + 1;

This will perform very well: TreeSet finds the insertion point in O(log n) time (like a binary search) and the list returned is just a view (a new list is not created), so the whole operation is lightweight.

Also note that the elements don't need to be added in any particular order - TreeSet internally maintains their order so searching is fast.


Here's some test code:

TreeSet<Float> numbers = new TreeSet<>(Arrays.asList(
    0.607F, 0.647F, 0.127F, 0.167F, 0.207F, 0.247F, 0.237F, 0.327F,
    0.367F, 0.407F, 0.447F, 0.487F, 0.527F, 0.567F, 0.652F));

Output:

10
like image 113
Bohemian Avatar answered Sep 18 '22 22:09

Bohemian


Assuming data is your initial map and values are unique, you could do:

java.util.NavigableMap<Double, Integer> reverseMap = new java.util.TreeMap<>();
for(java.util.Map.Entry<Double, Integer> entry : data.entrySet()) {
    reverseMap.put(entry.getValue(), entry.getKey());
}
System.out.println(reverseMap.ceilingEntry(0.465).getValue());
like image 26
khachik Avatar answered Sep 18 '22 22:09

khachik