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

新手上路,请多包涵

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

我意识到我可以用这样一个常量字符串数组得到一些单词:

 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 可以是常量吗?作为新手,并不完全清楚术语“常量”、“静态”和“最终”之间的关系,以及究竟什么是常量。 (单独静态?单独最终?一起静态最终?)。

我尝试将其设为 private static final Hashmap,但 IntelliJ 给了我一个错误(此处不允许修饰符“private”…与“static”相同)。

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

原文由 Hoonta 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 597
2 个回答

这里有两个方面:

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

因此,为了获得真正的“常量”地图,您需要这样做:

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

然后你使用 Collections.unmodifiableMap() 来创建一个不能再改变的地图。

需要注意的一件事是:您必须确保没有泄漏对原始地图对象的引用,因为不可变地图只是该初始地图的包装器。例如,您可以使用一些辅助方法来做到这一点。

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

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

原文由 GhostCat 发布,翻译遵循 CC BY-SA 4.0 许可协议

是的,它可以是一个常数。您应该声明您的 HashMap 实例如下:

 class <class name> {
    private static final HashMap<Integer, String> tensNumberConversion = new HashMap<>();

    static {
        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");
    }
}

然而,这只是一个常量参考。虽然您不能将 tensNumberConversion 重新分配给其他东西,但您仍然可以稍后在运行时更改地图的内容:

 tensNumberConversion = new HashMap<>(); // won't compile
tensNumberConversion.put(9, "one"); // succeeds

如果你也想要地图常量的内容,你应该将 HashMap 包装成一个不可修改的地图:

 class <class name> {
    private static final Map<Integer, String> tensNumberConversion = initMap();

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

原文由 ZhekaKozlov 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题