【问题标题】:How to use double brace initialization for Map of Map如何对 Map 的 Map 使用双括号初始化
【发布时间】:2019-08-02 18:19:42
【问题描述】:

我确实知道双括号初始化有其隐藏的成本,仍然有可能的方法来初始化Map<String,Map<String,String>>()

我尝试了什么:

Map<String, Map<String, String>> defaultSourceCode = new HashMap<String, Map<String, String>>(){
            {"a",new HashMap<String, String>(){{"c","d"}}}
        };

我知道这是一种不好的做法,但至于实验我正在尝试。

参考和动机: Arrays.asList also for maps?

【问题讨论】:

标签: java algorithm dictionary java-8 jvm


【解决方案1】:

几乎一切都很好,你只需要在双括号中使用方法调用:

Map<String, Map<String, String>> defaultSourceCode = new HashMap<String, Map<String, String>>(){
    {put("a",new HashMap<String, String>(){{put("c","d");}});}
};

但是this answer 描述了为什么你不应该这样做。

【讨论】:

  • 搞笑,Eclipse 想让我为这些类定义一个serialVersionUID
  • 这是一个非常有名的反模式!请不要。
  • @Eugene 你说得对,我附上了更多信息。
  • @LutzHorn 很好,这很好地暗示了与这种反模式相关的问题。这是创建 Serializable 类的子类,序列化此类映射将创建对该匿名类的持久引用。当然,添加serialVersionUID 并不能解决问题(除此之外你无论如何也不能这样做)。例如,周围类中的微小变化,比如再次对不同的地图使用这个反模式,可能会导致类文件重新编号,这会使持久性地图无效。更不用说对外部对象和任何捕获的变量的意外引用......
【解决方案2】:

您可以使用 java9 中的 Map.of() 返回不可变映射:

Map<String, Map<String, String>> map = Map.of("a", Map.of("c", "d"));

Map.ofEntries

Map<String, Map<String, String>> map1 = Map.ofEntries(
        Map.entry("a", Map.of("c", "d"))
);

【讨论】:

  • 喜欢它并 +1 ,但我正在寻找双括号初始化。虽然一如既往地感谢:)
  • @CommonMan 是的,ofEntries 解决了这个问题
  • 在许多情况下,20 个参数的列表足以让人混淆哪些是键,哪些是值。限制是有充分理由的。 ofEntries 接受几乎无限的项目,并明确哪些是键,哪些是值。
  • @OleV.V.好吧,限制的充分理由是您不能声明支持不同键和值类型的可变参数方法,因此,只能声明具有显式参数列表的重载方法。这可能与您的想法一致,即太多的论点无论如何都会令人困惑,但主要原因纯粹是技术性的。
  • @Holger 在一个本地库中,我看到了一个接受Object... 并返回地图的方法。您可以传递奇数个参数并返回异常,或者传递完全错误的类型。如果意志坚强(不用说我的意志不坚强),技术限制是可以克服的。
猜你喜欢
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 2012-02-22
  • 2012-08-28
  • 2023-03-04
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
相关资源
最近更新 更多