获取具有一系列数字作为值的散列映射的键

时间:2015-07-16 22:51:14

标签: java

我有一个HashMap<Integer, Float>条目:

 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

假设我想要Float 0.465的键(这不是现有值)。 0.465介于0.4470.487之间,因此我希望获得密钥10

我想到的第一个想法就是使用15 if / else if语句或switch语句。但在我看来,这不会非常优雅和实用。

还有其他办法吗?

3 个答案:

答案 0 :(得分:4)

Map不是合适的数据结构。改为使用TreeSet

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

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

这将表现得非常好:TreeSet在O(log n)时间内找到插入点(如二进制搜索),返回的列表只是视图(未创建新列表) ,所以整个操作都是轻量级的。

另请注意,不需要以任何特定顺序添加元素 - TreeSet在内部维护其顺序,因此搜索速度很快。

这是一些测试代码:

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));

输出:

10

答案 1 :(得分:1)

假设data是您的初始地图且值是唯一的,您可以这样做:

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());

答案 2 :(得分:1)

如果值始终排序,只需使用公共数组:

double[] values = {0.127, ..., 0.652};

然后,调用Arrays.binarySearch()方法,该方法返回立即大于给定值的值的索引。

请注意,此方法支持重复值,返回的索引为0-based