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
的 Java apidoc 中所述(强调我的):
不幸的是,Java API 中没有等效的方便方法来创建不可修改的地图
、Map.of
和Map.ofEntries
静态工厂方法 提供一种创建不可修改地图的便捷方法。地图 这些方法创建的实例具有以下特征:Map.copyOf
- ...
- 映射的迭代顺序未指定并且可能会发生变化。
...
LinkedHashMap
。如果您想要一致的迭代顺序,则需要手动创建
LinkedHashMap
并填充它(并且 - 如果需要 - 使用
Collections.unmodifiableMap
包装它)。考虑创建您自己的便捷方法,该方法与
Map.of
等效,但具有一致的迭代顺序(或查找已提供此功能的现有库)。
Map<String, String> mapPreservingInsertionOrder = io.vavr.collection.LinkedHashMap.of("key1", "val1", "key2", "val2").toJavaMap();
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 的优点在于,键值对作为条目对提供,而不仅仅是通过参数索引作为丢失对。
TreeMap
这样的排序映射与
Map.of
结合使用
new TreeMap<>(Map.of("key1", "value1", "key0", "value0", "key3", "value3"))
这应该始终返回一个一致的映射,其中键已排序。注意:如果您需要它不可修改,则需要用类似的东西包装它
Collections.unmodifiableMap(<<<TreeMap Here>>>)