Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
132 views
in Technique[技术] by (71.8m points)

java - how to get key of the most nearest value of a given double value from an existing map <String double>

Since I need to get the key values of double value I' m using BiMap.

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

For a particular value like 4.0156 I must get the key value a2.. that is if,

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

I tried many ways but its getting always null, since there is no exact match. please anyone help me... if I have chosen a wrong way please correct it because I'm new in Java.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First: you probably want to have:

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

And then you want a reverse lookup with nearest value.

For that it would be nice to have all entries sorted by value. This cannot be a Set because of a value occuring multiple times.

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

I know of no data structure in Java that combines this. Though there probably is. To not lose information I use the Map.Entry, key-value pair. That needs a Comparator on the values. For shortness, I have borrowed from Java 8 syntax here.

Now search:

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

To find a sub list of values inside a delta, one would need to use the index.

Now every search costs 2log N, which is acceptable.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...