在本教程中,我们将学习在Java 中初始化_HashMap的各种方法 。
我们将使用Java 8和Java 9。
我们可以使用静态代码块初始化 HashMap :
public static Map<String, String> articleMapOne;
static {
articleMapOne = new HashMap<>();
articleMapOne.put("ar01", "Intro to Map");
articleMapOne.put("ar02", "Some article");
}
这种初始化的优点是映射是可变的,但仅适用于静态映射。可以根据需要添加和删除条目。
让我们继续进行测试:
@Test
public void givenStaticMap_whenUpdated_thenCorrect() {
MapInitializer.articleMapOne.put(
"NewArticle1", "Convert array to List");
assertEquals(
MapInitializer.articleMapOne.get("NewArticle1"),
"Convert array to List");
}
我们还可以使用双括号语法初始化地图:
Map<String, String> doubleBraceMap = new HashMap<String, String>() {{
put("key1", "value1");
put("key2", "value2");
}};
请注意,我们必须避免使用这种初始化技术,因为它在每次使用时都会创建一个匿名的额外类,并且还包含对封闭对象的隐藏引用,这可能会导致内存泄漏问题。
如果我们需要创建具有单个条目的单例,不可变地图, Collections.singletonMap() 会非常有用:
public static Map<String, String> createSingletonMap() {
return Collections.singletonMap("username1", "password1");
}
请注意,这里的地图是不可变的,如果我们尝试添加更多条目,它将抛出 java.lang.UnsupportedOperationException。
我们还可以使用Collections.emptyMap()创建一个不变的空地图 :
Map<String, String> emptyMap = Collections.emptyMap();
在本节中,让我们研究使用Java 8 Stream API初始化地图的方法 。
让我们使用二维String数组的Stream并将它们收集到地图中:
Map<String, String> map = Stream.of(new String[][] {
{ "Hello", "World" },
{ "John", "Doe" },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));
请注意这里的键和值的数据类型地图是一样的。
为了使它更通用,让我们使用Objects 数组 并执行相同的操作:
Map<String, Integer> map = Stream.of(new Object[][] {
{ "data1", 1 },
{ "data2", 2 },
}).collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1]));
在这里,我们创建键的映射为String,值创建为Integer。
在这里,我们将使用Map.Entry的实例 。 这是我们具有不同键和值类型的另一种方法。
首先,让我们使用 Entry 接口的SimpleEntry 实现 :
Map<String, Integer> map = Stream.of(
new AbstractMap.SimpleEntry<>("idea", 1),
new AbstractMap.SimpleEntry<>("mobile", 2))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
现在,让我们使用SimpleImmutableEntry 实现创建地图 :
Map<String, Integer> map = Stream.of(
new AbstractMap.SimpleImmutableEntry<>("idea", 1),
new AbstractMap.SimpleImmutableEntry<>("mobile", 2))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
在某些用例中,我们需要初始化一个不变的地图。这可以通过包装来完成Collectors.toMap()内Collectors.collectingAndThen() :
Map<String, String> map = Stream.of(new String[][] {
{ "Hello", "World" },
{ "John", "Doe" },
}).collect(Collectors.collectingAndThen(
Collectors.toMap(data -> data[0], data -> data[1]),
Collections::<String, String> unmodifiableMap));
请注意,我们应避免使用Streams进行此类初始化 , 因为这可能会导致巨大的性能开销,并且会创建大量垃圾对象来初始化地图。
Java 9在Map界面中附带了各种工厂方法 ,从而简化了不可变地图的创建和初始化。
让我们继续研究这些工厂方法。
此工厂方法不带参数,单个参数和变量参数:
Map<String, String> emptyMap = Map.of();
Map<String, String> singletonMap = Map.of("key1", "value");
Map<String, String> map = Map.of("key1","value1", "key2", "value2");
请注意,此方法最多仅支持10个键值对。
它与Map.of() 类似, 但对键值对的数量没有限制:
Map<String, String> map = Map.ofEntries(
new AbstractMap.SimpleEntry<String, String>("name", "John"),
new AbstractMap.SimpleEntry<String, String>("city", "budapest"),
new AbstractMap.SimpleEntry<String, String>("zip", "000000"),
new AbstractMap.SimpleEntry<String, String>("home", "1231231231")
);
请注意,工厂方法会生成不可变的映射,因此任何突变都将导致 UnsupportedOperationException。
而且,它们不允许空键和重复键。
现在,如果在初始化后需要可变的或正在增长的地图,则可以创建Map接口的任何实现, 并将这些不可变的地图传递给构造函数:
Map<String, String> map = new HashMap<String, String> (
Map.of("key1","value1", "key2", "value2"));
Map<String, String> map2 = new HashMap<String, String> (
Map.ofEntries(
new AbstractMap.SimpleEntry<String, String>("name", "John"),
new AbstractMap.SimpleEntry<String, String>("city", "budapest")));
现在,当我们研究了使用核心Java的方式时,让我们继续使用Guava库初始化地图:
Map<String, String> articles
= ImmutableMap.of("Title", "My New Article", "Title2", "Second Article");
这将创建一个不变的地图,并创建一个可变的地图:
Map<String, String> articles
= Maps.newHashMap(ImmutableMap.of("Title", "My New Article", "Title2", "Second Article"));
[ImmutableMap.of()] 方法 还具有重载版本,最多可以包含5对键值参数。这是带有两个参数对的示例:
ImmutableMap.of("key1", "value1", "key2", "value2");
查过5个key value时
Map<String, String> test = ImmutableMap.<String, String>builder()
.put("k1", "v1")
.put("k2", "v2")
...
.build();
原文: https://rumenz.com/rumenbiji/java-directly-initialize-hashmap.html