第一:你可能想要:
Map<String, Double> mapObj = HashMap<>();
mapObj.put("a1", 3.58654);
mapObj.put("a2", 4.1567);
mapObj.put("a3", 4.2546);
mapObj.put("a4", 4.1567); // Repeated value
然后你想要一个具有最接近值的反向查找。
为此,最好将所有条目按值排序。这不能是 Set,因为一个值多次出现。
List<Map.Entry<String, Double>> entries = new ArrayList<>(mapObj.entrySet());
Comparator<Map.Entry<String, Double>> cmp = (lhs, rhs) ->
Double.compare(lhs.getValue(), rhs.getValue());
Collections.sort(entries, cmp);
我知道 Java 中没有结合此的数据结构。虽然可能有。为了不丢失信息,我使用 Map.Entry 键值对。这需要一个比较器的值。简而言之,我在这里借鉴了 Java 8 语法。
现在搜索:
Map.Entry<String, Double> nearest(double value) {
int index = Collections.binarySearch(entries, cmp);
if (index < 0) { // Not found
index = -index + 1; // The insertion position
Map.Entry<String, Double> before = index != 0 ? entries.get(i - 1) : null;
Map.Entry<String, Double> after = index < entries.size() ?
entries.get(i) : null;
if (before == null && after == null) {
return null;
} else if (before == null) {
return after;
} else if (after == null) {
return before;
}
return value - before.getValue() < after.getValue() - value ? before : after;
}
return entries.get(index);
}
要在 delta 中查找值的子列表,需要使用索引。
现在每次搜索都花费 ²log N,这是可以接受的。