Reputation: 111
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?
Upvotes: 5
Views: 1251
Reputation: 424993
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
Upvotes: 4
Reputation: 34460
If values are always sorted, just use a common array:
double[] values = {0.127, ..., 0.652};
And then, call the Arrays.binarySearch()
method, which returns the index of the value that is immediately greater than the given value.
Please note that this approach supports duplicate values, and the index returned is 0-based
.
Upvotes: 1
Reputation: 28693
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());
Upvotes: 1