繁体   English   中英

如何在 Map.of 工厂中保留插入顺序?

[英]How to preserve order of insertion in Map.of factory?

Java 9 提供Map.of()功能来轻松创建具有固定值的地图。

问题:我想创建一个保留插入顺序的地图,如LinkedHashMap 那家工厂可以吗? 至少map.of()不保留顺序...

确实没有像LinkedHashMap::of这样的工厂方法,而且Map本身没有订单,所以我看到的唯一方法是在你真的需要时构建一个LinkedHashMap

顺便说一句,来自JEP 本身

具体集合类(例如,ArrayList、HashSet)上的静态工厂方法已从该提案中删除...

还有一个问题,就是类上的静态方法是由子类继承的。 假设要添加一个静态工厂方法 HashMap.of()。 由于 LinkedHashMap 是 HashMap 的子类,因此应用程序代码可以调用 LinkedHashMap.of()。 这最终会调用 HashMap.of(),这完全不是人们所期望的!

这里的重点是static方法是继承的,但不可覆盖,因此如果将这样的方法添加到HashMap中,它可能不会在LinkedHashMap中被覆盖。

如果您可以使用guava ,您可以使用ImmutableMap记录为:

一个不可变的、基于哈希的 Map 具有可靠的用户指定的迭代顺序......

正如Map的 Java apidoc 中所记录的那样(强调我的):

不可修改的地图

Map.ofMap.ofEntriesMap.copyOf静态工厂方法提供了一种方便的方式来创建不可修改的地图。 这些方法创建的 Map 实例具有以下特点:

  • ...
  • 映射的迭代顺序未指定,可能会发生变化。
  • ...

不幸的是,Java API 中没有创建LinkedHashMap的等效便捷方法。 如果您想要一个一致的迭代顺序,那么您将需要手动创建一个LinkedHashMap并填充它(并且 - 如果需要 - 使用Collections.unmodifiableMap包装它)。

考虑创建自己的便捷方法,该方法与Map.of等效,但具有一致的迭代顺序(或查找已经提供此功能的现有库)。

因为在 JDK 中似乎没有任何方法可以做你想做的事情,你必须自己实现它或使用现有的库。 创建这样的辅助方法并不难:

public static <K, V> LinkedHashMap<K, V> of(Collection<Entry<? extends K, ? extends V>> entries) {
  final LinkedHashMap<K, V> map = new LinkedHashMap<>();
  entries.forEach(entry -> map.put(entry.getKey(), entry.getValue()));
  return map;
}

然后你可以像这样使用它:

of(List.of(Map.entry("Hello", "World"), Map.entry("Goodnight", "Moon")));

该解决方案优于 JDK 中的 Map.of,即键值对作为条目对提供,而不仅仅是通过参数索引作为丢失对提供。

您还可以通过以下方式使用 vavr.io:

Map<String, String> mapPreservingInsertionOrder = io.vavr.collection.LinkedHashMap.of("key1", "val1", "key2", "val2").toJavaMap();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM