2016-02-27 3 views
-1

Я реализация A * алгоритм поиска заданный здесь, https://en.wikipedia.org/wiki/A * _search_algorithmИнициализация HashMap со значениями по умолчанию?

Эта линия показывает, что мы должны initiliaze карты со значениями по умолчанию INFINITY,

gScore := map with default value of Infinity 

Так что я попробовал, что здесь,

Map<State, Double> gScore = new HashMap<State, Double>(Double.POSITIVE_INFINITY); 

Это не работает, однако следующее:

Map<State, Double> gScore = new HashMap<State, Double>((int) Double.POSITIVE_INFINITY); 

Мне интересно, почему и какое влияние (если таковое имеется) на мою реализацию.

ответ

1

Невозможно инициализировать карту со значением по умолчанию в Java, а вторая версия не будет создавать карту со значением бесконечности по умолчанию, но вместо этого попытается создать бесконечно большую карту. (Не совсем, но он попытается создать самую большую возможную карту.)

Вместо этого, отредактируйте алгоритм: в любое время вы делаете map.get(key), проверьте, имеет ли значение значение null и, если да, замените его на бесконечность.

+0

[Map.getOrDefault] (https: // docs.oracle.com/javase/8/docs/api/java/util/Map.html#getOrDefault-java.lang.Object-V-) полезен для этого. – VGR

1

Я согласен с @Louis, что решение лучше, чтобы проверить результат get вызова, чтобы увидеть, если это null.

Однако, это также возможно создать подкласс HashMap с переопределения для get метода, который возвращает значение по умолчанию, если super.get(key) возвращает null. Но остерегайтесь аномалий; например

  • Итерация карты даст вам только записи, которые «действительно там».

  • Если есть реальная запись со значением null (потому что вы назвали put(key, null)), вы не получите null при вызове get для ключа записей. Но но запись будет появляться на итерации ... со значением null.

Таким образом, из точки зрения дизайна OO, лучший подход (к расширению HashMap) было бы создать класс конкретного приложения, что только обнажает подмножество Map функциональности.

0

Если вы знаете, ключи заранее, с Java 8 вы можете сделать:

// this will have to get your State keys from somewhere 
Collection<State> keys = getStateKeys(); 

// this is your initial default value 
Double initialValue = Double.POSITIVE_INFINITY; 

// and initialise the map with default values 
Map<State, Double> gScore = keys.stream().collect(Collectors.toMap(Function.identity(), __ -> initialValue)); 

обобщенный метод Util, который может помочь:

public static <T, V> Map<V, T> newMapWithKeysAndInitialValue(Collection<V> keys, T initialValue) 
{ 
    return keys.stream().collect(Collectors.toMap(Function.identity(), __ -> initialValue)); 
} 
Смежные вопросы