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

How to preserve order of insertion in Map.of factory?

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

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

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

顺便说一下,来自 the JEP itself

Static factory methods on concrete collection classes (e.g., ArrayList, HashSet) have been removed from this proposal ...

There is another wrinkle, which is that static methods on classes are inherited by subclasses. Suppose a static factory method HashMap.of() were to be added. Since LinkedHashMap is a subclass of HashMap, it would be possible for application code to call LinkedHashMap.of(). This would end up calling HashMap.of(), not at all what one would expect!

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

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

An immutable, hash-based Map with reliable user-specified iteration order...

Map 的 Java apidoc 中所述(强调我的):

Unmodifiable Maps

The Map.of, Map.ofEntries, and Map.copyOf static factory methods provide a convenient way to create unmodifiable maps. The Map instances created by these methods have the following characteristics:

  • ...
  • The iteration order of mappings is unspecified and is subject to change.
  • ...

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

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

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

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