有没有这样初始化Java HashMap的方法?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
正确的语法是什么?我没有发现任何与此相关的信息。这可能吗?我正在寻找最短/最快的方法来将一些“最终/静态”值放在地图中,这些值永远不会改变,并且在创建地图时预先知道。
有没有这样初始化Java HashMap的方法?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
正确的语法是什么?我没有发现任何与此相关的信息。这可能吗?我正在寻找最短/最快的方法来将一些“最终/静态”值放在地图中,这些值永远不会改变,并且在创建地图时预先知道。
当前回答
如果只需要放置一个键值对,可以使用Collections.singletonMap(key,value);
其他回答
所有版本
如果您恰好需要一个条目:Collections.singletonMap(“key”,“value”)。
对于Java版本9或更高版本:
是的,这现在是可能的。在Java 9中,添加了两种简化地图创建的工厂方法:
// this works for up to 10 elements:
Map<String, String> test1 = Map.of(
"a", "b",
"c", "d"
);
// this works for any number of elements:
import static java.util.Map.entry;
Map<String, String> test2 = Map.ofEntries(
entry("a", "b"),
entry("c", "d")
);
在上面的示例中,test和test2都是相同的,只是表示Map的方式不同。Map.of方法最多为映射中的十个元素定义,而Map.ofEntries方法没有这样的限制。
注意,在这种情况下,生成的映射将是一个不可变的映射。如果希望映射是可变的,可以再次复制它,例如使用mutableMap=newHashMap<>(map.of(“a”,“b”));。还要注意,在这种情况下,键和值不能为空。
(另见JEP 269和Javadoc)
对于Java版本8之前的版本:
否,您必须手动添加所有元素。您可以在匿名子类中使用初始值设定项,使语法稍短:
Map<String, String> myMap = new HashMap<String, String>() {{
put("a", "b");
put("c", "d");
}};
然而,在某些情况下,匿名子类可能会引入不需要的行为。这包括例如:
它生成了一个额外的类,增加了内存消耗、磁盘空间消耗和启动时间在非静态方法的情况下:它保存对调用创建方法的对象的引用。这意味着当创建的映射对象仍然被引用时,不能对外部类的对象进行垃圾收集,从而阻塞了额外的内存
使用函数进行初始化也将使您能够在初始值设定项中生成映射,但避免了严重的副作用:
Map<String, String> myMap = createMap();
private static Map<String, String> createMap() {
Map<String,String> myMap = new HashMap<String,String>();
myMap.put("a", "b");
myMap.put("c", "d");
return myMap;
}
JAVA 8
在普通的java8中,您还可以使用Streams/Collectors来完成这项工作。
Map<String, String> myMap = Stream.of(
new SimpleEntry<>("key1", "value1"),
new SimpleEntry<>("key2", "value2"),
new SimpleEntry<>("key3", "value3"))
.collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));
这具有不创建匿名类的优点。
请注意,进口产品包括:
import static java.util.stream.Collectors.toMap;
import java.util.AbstractMap.SimpleEntry;
当然,正如在其他答案中所指出的,在java9之后,您有更简单的方法来实现同样的目的。
我找到了baeldung的一篇很棒的文章,其中列出了在不同Java版本中实现这一点的几种方法。
有几个有趣的方法很方便
对于任何Java版本
public static Map<String, String> articleMapOne;
static {
articleMapOne = new HashMap<>();
articleMapOne.put("ar01", "Intro to Map");
articleMapOne.put("ar02", "Some article");
}
对于使用流的Java 8
Map<String, String> map = Stream.of(new String[][] {
{ "Hello", "World" },
{ "John", "Doe" },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
我们使用一个简单的实用程序类以流畅的方式初始化Maps:
Map<String, String> map = MapInit
.init("key1", "value1")
.put("key2", "value2")
.put("key3", "value3")
.getMap();
实用程序类不受键和值的类型、条目的数量以及生成的Map的类型的限制。
实用程序类如下所示:
public class MapInit<K, V, T extends Map<K, V>> {
private final T map;
private MapInit(final T map) {
this.map = map;
}
public T getMap() {
return this.map;
}
public static <K, V> MapInit<K, V, HashMap<K, V>> init(final K key, final V value) {
return init(HashMap::new, key, value);
}
public static <K, V, T extends Map<K, V>> MapInit<K, V, T> init(final Supplier<T> mapSupplier, final K key, final V value) {
return new MapInit<>(mapSupplier.get()) //
.put(key, value);
}
public MapInit<K, V, T> put(final K key, final V value) {
this.map.put(key, value);
return this;
}
}
您可以通过两种简单的方式轻松地创建自己的Map.of(仅在Java9及更高版本中可用)方法
使用设定数量的参数
实例
public <K,V> Map<K,V> mapOf(K k1, V v1, K k2, V v2 /* perhaps more parameters */) {
return new HashMap<K, V>() {{
put(k1, v1);
put(k2, v2);
// etc...
}};
}
使用列表制作
您也可以使用列表来实现这一点,而不是为某一组参数创建许多方法。
实例
public <K, V> Map<K, V> mapOf(List<K> keys, List<V> values) {
if(keys.size() != values.size()) {
throw new IndexOutOfBoundsException("amount of keys and values is not equal");
}
return new HashMap<K, V>() {{
IntStream.range(0, keys.size()).forEach(index -> put(keys.get(index), values.get(index)));
}};
}
笔记不建议将其用于所有对象,因为每次使用时都会生成一个匿名类。