简体   繁体   中英

Java - How to find a value from a hashmap that is the closest to a particular number?

Hi I have a HashMap<String, Double> and also a function which returns a double value known as answer . I want to check which value in the HashMap is the closest to the answer and then grab that value's key and print it.

HashMap<String, Double> output = new HashMap<String, Double>();


contents
("A", 0)
("B", 0.25)
("C", 0.5)
("D", 0.75)
("E", 1)

Suppose the answer to one of my functions was 0.42, how can I check which value it is closest to and then grab the key to that value. I cant switch around the key and value of the HashMap (as a previous function assigns the values equally to each letter), otherwise it would be better to go through each key and get the value.

If your values are unique, you can use a TreeMap , which implements NavigableMap , which has the nice ceilingKey and floorKey methods:

    NavigableMap<Double, String> map = new TreeMap<>();
    map.put(0d, "A");
    map.put(0.25, "B");
    map.put(0.5, "C");
    map.put(0.75, "D");
    map.put(1d, "E");

    double value = 0.42;
    double above = map.ceilingKey(value);
    double below = map.floorKey(value);

    System.out.println(value - below > above - value ? above : below); //prints 0.5

Note: both methods can return null if value is less (resp. greater) than the smallest / largest key.

With a HashMap , you have to go through each entry.

However, if performance is important and you're going to be finding several entries this way, you could create another collection: a list or an array of the entries in the hash map, sorted by value. You could then do a binary search to find the entry with the nearest value more efficiently, and return the key. Of course that doesn't help if you're only going to do this once per map...

The concept of 'closest' is not really meaningful for Hashed data structures. The primary goal of efficient hashing algorithms is collision avoidance, which is directly contrary to closeness. Either you have a collision, or not.

If you were asking this for an ordered key data structure (eg. TreeMap ), the answer would be different.

HashMap isn't the best structure to do this. You can get output.keySet() and check each value, for example:

for(String key:output.keySet()){
   Double temp=Math.abs(output.get(key)-answer);
   if(temp<min){
     min=temp;
     nearest=key;
   }
}

but it's not the best way. you are forced to use a hashmap? By the way, this isn't a problem if you have always five answer to check...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM