如何使用默认值初始化HashMap?

6
我正在实现此处提供的A*搜索算法:https://en.wikipedia.org/wiki/A*_search_algorithm

这行代码表示我们需要使用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);

我在想为什么会这样,以及它对我的实现有什么影响(如果有的话)。
3个回答

4
在Java中没有一种初始化带有默认值的Map的方法,你的第二个版本不会创建一个默认值为无穷大的Map,而是会尝试创建一个最大可能的Map。(实际上并非如此,但它会尝试创建最大的Map)。
相反,修改算法:每次执行 map.get(key) 时,检查值是否为null,如果是,则用无穷大替换它。

2
Map.getOrDefault 对此非常有用。 - VGR

1

不必为所有可能的键(这可能是低效的)显式地放置Double.POSITIVE_INFINITY,您可以使用putIfAbsent

无论何处都可以使用以下内容:

value = map.get(key);

你可以将它更改为:


value = map.putIfAbsent(key,Double.POSITIVE_INFINITY);

这将表现得好像不在Map中的任何键的值(或当前值为null的任何键)的值为Double.POSITIVE_INFINITY。它将在Map中为任何这样的键放置值Double.POSITIVE_INFINITY。
这将节省您检查map.get(key)是否返回null的需要。

1
我同意@Louis的看法,最佳解决方案是检查get调用的结果是否为null
然而,也有可能创建HashMap的子类,并重写get方法,如果super.get(key)返回null,则返回默认值。但要注意异常情况;例如:
- 遍历映射将只给出“真正存在”的条目。 - 如果有一个实际的条目具有null值(因为您调用了put(key, null)),则在为条目键调用get时不会得到null。但是该条目将在迭代中显示...其值为null
因此,从OO设计的角度来看,更好的方法(扩展HashMap)是创建一个特定于应用程序的类,仅公开Map功能的子集。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接