如何从现有地图<string double =“”> </string>获取给定double值的最接近值的键

时间:2014-11-19 13:46:34

标签: java hashmap treemap bimap

因为我需要获得双值I&#39;的关键值。 m使用BiMap

BiMap<String,Double>mapObj = HashBiMap.create();
mapObj.put("a1",3.58654);
mapObj.put("a2",4.1567);
mapObj.put("a3",4.2546);

对于像4.0156这样的特定值,我必须得到键值a2 ..即if,

Double value=4.0156; 
mapObj.inverse().get(value)=a2 

我尝试了很多方法,但它总是为空,因为没有完全匹配。请任何人帮助我...如果我选择了错误的方式,请更正它,因为我是Java新手。

4 个答案:

答案 0 :(得分:1)

首先:你可能想要:

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

要查找增量内的值的子列表,需要使用索引。

现在每次搜索都需要花费N,这是可以接受的。

答案 1 :(得分:0)

通过像这样的条目集迭代应该可以解决问题。

String nearestKey = null;
Double nearestValue = null;
for(Entry<String,Double> e : map.entrySet()){
    //if e.getValue() is nearer than prev nearestValue
    // nearestKey = e.getKey();
    // nearestValue = e.getValue();
}

您只需编写一个函数来确定密钥是否比上一个更近并更新变量。

答案 2 :(得分:0)

您必须遍历所有键值对,并选择一个值最接近您要查找的值的键值对。

public String searchClosest(Map<String,Double> map, double value)
{
    double minDistance = Double.MAX_VALUE;
    String bestString = null;

    for (Map.Entry<String,Double> entry : map.entrySet()) {
        double distance = Math.abs(entry.getValue() - value);
        if (distance < minDistance) {
            minDistance = distance;
            bestString = entry.getKey();
        }
    }

    return bestString;
}

答案 3 :(得分:0)

转换为已排序的键和值的有序映射,应用以下方法。

 private static Double getClosest(TreeMap<Double, String> mySet, Double d) {
        if (mySet.ceilingKey(d) != null && mySet.floorKey(d) != null){
            if( Math.abs(d - mySet.ceilingKey(d)) < Math.abs(d - mySet.floorKey(d)) )
                return mySet.ceilingKey(d);
            else
                return mySet.floorKey(d);
        }
        else if (mySet.ceilingKey(d) == null && mySet.floorKey(d) != null) {
            return mySet.floorKey(d);
        } else if (mySet.ceilingKey(d) != null && mySet.floorKey(d) == null) {
            return mySet.ceilingKey(d);
        } else
            return null;
    }