Найти ближайший ответ в HashMap

Я хочу найти ключ в хэш-карте и найти ближайший к этому ключу!

    HashMap<Long, Object> map = new HashMap<Long , Object>();

так что в основном я хочу найти длинный, и если бы он не существовал на карте, найдите ближайший матч к этому длинному значению! Как я могу это сделать??

Thanx заранее

Ответ 1

Вы не можете сделать это с помощью HashMap без повторения всех его ключей. Я предполагаю, что это не то, что вам нужно, так что это способ сделать это с помощью TreeMap:

TreeMap<Long,Object> map = new TreeMap<Long,Object>();
Long key = 42;
Map.Entry<Long,Object> low = map.floorEntry(key);
Map.Entry<Long,Object> high = map.ceilingEntry(key);
Object res = null;
if (low != null && high != null) {
    res = Math.abs(key-low.getKey()) < Math.abs(key-high.getKey())
    ?   low.getValue()
    :   high.getValue();
} else if (low != null || high != null) {
    res = low != null ? low.getValue() : high.getValue();
}

Ответ 2

Использование NavigableMap, как TreeMap

long key = 
NavigableMap<Long, Object> map = new TreeMap<Long , Object>();

Long before = map.floorKey(key);
Long after = map.ceilingKey(key);
if (before == null) return after;
if (after == null) return before;
return (key - before < after - key 
       || after - key < 0) 
       && key - before > 0 ? before : after;

Ответ 3

Итерации по всем клавишам, чтобы найти ключ с наименьшей разницей с целевой клавишей.

Вот код, который делает это:

public static Long nearestKey(Map<Long, Object> map, Long target) {
    double minDiff = Double.MAX_VALUE;
    Long nearest = null;
    for (long key : map.keySet()) {
        double diff = Math.abs((double) target - (double) key);
        if (diff < minDiff) {
            nearest = key;
            minDiff = diff;
        }
    }
    return nearest;
}

Все, что отличает double, - это защита от опрокидывания, когда цель является большим отрицательным, а ключ карты - большой положительный

Ответ 4

Вместо этого вы можете использовать TreeMap:

public static void main(String... args) throws Exception {
    Map<Long, Object> map = new TreeMap<Long, Object>();
    map.put(2L, "2");
    map.put(5L, "5");
    map.put(8L, "8");
    map.put(3L, "3");

    System.out.println(findNearest(map, 2)); //prints 2
    System.out.println(findNearest(map, 4)); //prints 3
    System.out.println(findNearest(map, 7)); //prints 8
}

private static Object findNearest(Map<Long, Object> map, long value) {
    Map.Entry<Long, Object> previousEntry = null;
    for (Map.Entry<Long, Object> e : map.entrySet()) {
        if (e.getKey().compareTo(value) >= 0) {
            if (previousEntry == null) {
                return e.getValue();
            } else {
                if (e.getKey() - value >= value - previousEntry.getKey()) {
                    return previousEntry.getValue();
                } else {
                    return e.getValue();
                }
            }
        }
        previousEntry = e;
    }
    return previousEntry.getValue();
}

Ответ 5

Хэши (включая HashMap) не имеют порядка (реализуют "Comparable" ), они просто работают с реализациями equals() и hashCode().

Другими словами, это невозможно. Вы можете попробовать с упорядоченным списком или установить.

Ответ 6

Не? Это не то, как должна работать функция get. Я думаю, вы могли бы использовать TreeMap и использовать getHeadMap/getTailMap и использовать некоторую логику для поиска ближайшего соответствия. Но это, вероятно, потребует немного поиграть. В конце концов, что было бы самым близким?...