在Java中,我可以声明一个HashMap常量吗?

时间:2017-05-11 03:51:29

标签: java hashmap constants

我正在编写一个简单的程序,将数字转换为代表该数字的单词(13 =>“13”)。

我意识到我可以用这样的常量String数组得到一些单词:

private static final String[] tensNames = {"", " ten", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety" };

...并使用索引访问它,但我想尝试使用这样的HashMap:

final HashMap<Integer, String> tensNumberConversion = new HashMap<Integer, String>();
    tensNumberConversion.put(2, "twenty");
    tensNumberConversion.put(3, "thirty");
    tensNumberConversion.put(4, "forty");
    tensNumberConversion.put(5, "fifty");
    tensNumberConversion.put(6, "sixty");
    tensNumberConversion.put(7, "seventy");
    tensNumberConversion.put(8, "eighty");
    tensNumberConversion.put(9, "ninety");

老师指示我制作这些常数。 HashMap可以是常量吗?作为一个新手,尚不完全清楚术语“常数”,“静态”和“最终”是如何相关的,以及究竟是什么使它成为一个常数。 (单独静止?最后一个人?静态决赛一起?)。

我尝试将其设为私有静态最终Hashmap,但IntelliJ给了我一个错误(修改符'私有'不允许在这里......同样用于'静态')。

但是,它确实从我的终端编译而没有错误。如果HashMap可以是常量,这是声明一个的正确方法吗?谢谢!

4 个答案:

答案 0 :(得分:11)

这里有两个方面:

  • 您有一个包含对地图的引用的变量。您只需将该变量声明为 final ;并且,您无法将变量更改为指向另一个引用。
  • 但这并不妨碍您更改引用指向的对象的状态。因此,即使您拥有最终Map 对象,您仍然可以在该Map上调用put / remove / ...方法。

所以,为了得到一个真正的“常数”地图,你可以做到这一点:

首先,您创建一个包含所有所需值的普通地图。

然后使用Collections.unmodifiableMap()创建一个无法再更改的地图。

要注意的一件事是:您必须确保没有泄漏对原始地图对象的引用,因为该不可变地图只是该初始地图的包装。例如,你可以用一个小帮手方法做到这一点。

如果你问:是否有办法以特殊的“文字形式”(如数组)写下地图声明 - 没有。那么,您可以更改该辅助方法以Object ...作为参数;然后你会经历这些参数,一个是数字,下一个是一个字符串,并使用它来填充地图。因此,您可以使用单个值序列调用该方法。但可能不值得努力...

快速更新:Java9添加了各种静态辅助方法,允许您以某种“文字”方式写下地图,例如,请参阅here

答案 1 :(得分:7)

只是一个BTW,在Java 9中有static methods in the Map interface来创建不可变的地图,其中有一些条目如下:

Map<String,String> m = Map.of("k1", "v1",
                              "K2", "v2");

或者如果需要超过10个条目:

import static java.util.Map.entry;
Map<String, String> m = Map.ofEntries(
    entry("k1", "v1"), entry("k2", "v2"), …);

答案 2 :(得分:1)

我不知何故在这里错过了直接初始化HashMap的最简单形式

private static final Map<Integer, String> tensNumberConversion_internal = new HashMap<Integer, String>()
{
    {
        put(2, "twenty");
        put(3, "thirty");
        put(4, "forty");
        put(5, "fifty");
        put(6, "sixty");
        put(7, "seventy");
        put(8, "eighty");
        put(9, "ninety");
    };
};

并且为了使其不可更改,您已经从the accepted answer获得了Collections.unmodifiableMap

public static final Map<Integer, String> tensNumberConversion = Collections.unmodifiableMap(tensNumberConversion_internal);

必须按此顺序创建它们;)

答案 3 :(得分:0)

您可以使用继承从HashMap继承新类,然后重写HashMap.put()方法以显示一些适当的失败消息,而不是使用堆肥来实现常量HashMap ...

class MyMap extends java.util.HashMap{
@Override
public V put (K key, V value){
System.out.println("Operation Not Supported");
return null;
}
}

请注意,这不是唯一的方法,而是可能的众多方法之一