简体   繁体   English

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

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

Java 9 offers Map.of() feature to easily create a map with fixed values. Java 9 提供Map.of()功能来轻松创建具有固定值的地图。

Problem: I want to create a map that preserves order of insertion like LinkedHashMap .问题:我想创建一个保留插入顺序的地图,如LinkedHashMap Is that possible with that factory?那家工厂可以吗? At least map.of() does not preserv the order...至少map.of()不保留顺序...

There isn't a factory method like LinkedHashMap::of indeed, and a Map does not have an order per-se, so the only way I see it is to build a LinkedHashMap if you really needed one.确实没有像LinkedHashMap::of这样的工厂方法,而且Map本身没有订单,所以我看到的唯一方法是在你真的需要时构建一个LinkedHashMap

Btw from the JEP itself :顺便说一句,来自JEP 本身

Static factory methods on concrete collection classes (eg, ArrayList, HashSet) have been removed from this proposal ...具体集合类(例如,ArrayList、HashSet)上的静态工厂方法已从该提案中删除...

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.假设要添加一个静态工厂方法 HashMap.of()。 Since LinkedHashMap is a subclass of HashMap, it would be possible for application code to call LinkedHashMap.of().由于 LinkedHashMap 是 HashMap 的子类,因此应用程序代码可以调用 LinkedHashMap.of()。 This would end up calling HashMap.of(), not at all what one would expect!这最终会调用 HashMap.of(),这完全不是人们所期望的!

Point here is that static methods are inherited, but not overridable, thus if such a method would have been added to HashMap it could have not been overridden in LinkedHashMap .这里的重点是static方法是继承的,但不可覆盖,因此如果将这样的方法添加到HashMap中,它可能不会在LinkedHashMap中被覆盖。

If you can use guava , you could use ImmutableMap that is documented as:如果您可以使用guava ,您可以使用ImmutableMap记录为:

An immutable, hash-based Map with reliable user-specified iteration order...一个不可变的、基于哈希的 Map 具有可靠的用户指定的迭代顺序......

As documented on the Java apidoc of Map (emphasis mine):正如Map的 Java apidoc 中所记录的那样(强调我的):

Unmodifiable Maps不可修改的地图

The Map.of , Map.ofEntries , and Map.copyOf static factory methods provide a convenient way to create unmodifiable maps. Map.ofMap.ofEntriesMap.copyOf静态工厂方法提供了一种方便的方式来创建不可修改的地图。 The Map instances created by these methods have the following characteristics:这些方法创建的 Map 实例具有以下特点:

  • ... ...
  • The iteration order of mappings is unspecified and is subject to change.映射的迭代顺序未指定,可能会发生变化。
  • ... ...

Unfortunately, there is no equivalent convenience method in the Java API that creates a LinkedHashMap .不幸的是,Java API 中没有创建LinkedHashMap的等效便捷方法。 If you want a consistent iteration order, then you will need to manually create a LinkedHashMap and populate it (and - if needed - wrap it using Collections.unmodifiableMap ).如果您想要一个一致的迭代顺序,那么您将需要手动创建一个LinkedHashMap并填充它(并且 - 如果需要 - 使用Collections.unmodifiableMap包装它)。

Consider creating your own convenience method that does the equivalent of Map.of but with a consistent iteration order (or find an existing library that already provides this).考虑创建自己的便捷方法,该方法与Map.of等效,但具有一致的迭代顺序(或查找已经提供此功能的现有库)。

Because there seems to be no method that is doing what you want in the JDK you have to implement it by yourself or use a existing library.因为在 JDK 中似乎没有任何方法可以做你想做的事情,你必须自己实现它或使用现有的库。 Creating such helper method isn't that hard:创建这样的辅助方法并不难:

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;
}

And then you could use it like this:然后你可以像这样使用它:

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

This solution has the advantage over the Map.of in the JDK that the key value pairs are provided as entry pairs and not just as lose pairs by parameter index.该解决方案优于 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