有没有这样初始化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"};
正确的语法是什么?我没有发现任何与此相关的信息。这可能吗?我正在寻找最短/最快的方法来将一些“最终/静态”值放在地图中,这些值永远不会改变,并且在创建地图时预先知道。
当前回答
没有直接的方法可以做到这一点——截至2021,Java没有Map文字(然而,我认为它们是为Java8提出的,但没有实现)。
有些人喜欢这样:
Map<String,String> test = new HashMap<String, String>(){{
put("test","test"); put("test","test");}};
这将创建HashMap的匿名子类,其实例初始值设定项将放置这些值。(顺便说一句,地图不能包含两个相同的值,第二个put将覆盖第一个。我将在下一个示例中使用不同的值。)
通常的方法是(对于局部变量):
Map<String,String> test = new HashMap<String, String>();
test.put("test","test");
test.put("test1","test2");
如果测试映射是实例变量,请将初始化放在构造函数或实例初始值设定项中:
Map<String,String> test = new HashMap<String, String>();
{
test.put("test","test");
test.put("test1","test2");
}
如果测试映射是类变量,请将初始化放在静态初始值设定项中:
static Map<String,String> test = new HashMap<String, String>();
static {
test.put("test","test");
test.put("test1","test2");
}
如果你希望你的映射永远不变,你应该在初始化后用Collections.unmodifiedMap(…)包装你的映射。你也可以在静态初始化器中这样做:
static Map<String,String> test;
{
Map<String,String> temp = new HashMap<String, String>();
temp.put("test","test");
temp.put("test1","test2");
test = Collections.unmodifiableMap(temp);
}
(我不确定你现在是否能让考试成为最终……试试看,然后在这里报告。)
从Java9开始,您还拥有Map.of(…)和Map.entries()语法,正如yankee的回答所解释的。
其他回答
使用Java 8或更低版本
您可以使用静态块用一些值初始化映射。例子:
public static Map<String,String> test = new HashMap<String, String>
static {
test.put("test","test");
test.put("test1","test");
}
使用Java 9或更高版本
在声明时,可以使用Map.of()方法用一些值初始化映射。例子:
public static Map<String,String> test = Map.of("test","test","test1","test");
我们可以使用具有SimpleEntry的AbstractMap类,该类允许创建不可变映射
Map<String, String> map5 = Stream.of(
new AbstractMap.SimpleEntry<>("Sakshi","java"),
new AbstractMap.SimpleEntry<>("fine","python")
).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(map5.get("Sakshi"));
map5.put("Shiva", "Javascript");
System.out.println(map5.get("Shiva"));// here we can add multiple entries.
如果它是一个实例变量,那么一个实例初始化块绝对是最好的方法,特别是如果你不能使用Map.of(),因为你需要一个不同类型的映射。
但是,如果你感觉很活泼,你可以使用Java 8供应商(不推荐)。
private final Map<String,Runnable> games = ((Supplier<Map<String,Runnable>>)() -> {
Map<String,Runnable> map = new LinkedHashMap<>();
map.put("solarus",this::playSolarus);
map.put("lichess",this::playLichess);
return map;
}).get();
或者制作自己的功能界面(我觉得不错):
@FunctionalInterface
public interface MapMaker<M> {
static <M extends Map<K,V>,K,V> M make(M map,MapMaker<M> maker) {
maker.build(map);
return map;
}
void build(M map);
}
// Can use LinkedHashMap!
private final Map<String,Runnable> games = MapMaker.make(
new LinkedHashMap<>(),(map) -> {
map.put("solarus",this::playSolarus);
map.put("lichess",this::playLichess);
});
另一种方法是使用纯Java 7类和varargs:使用以下方法创建一个类HashMapBuilder:
public static HashMap<String, String> build(String... data){
HashMap<String, String> result = new HashMap<String, String>();
if(data.length % 2 != 0)
throw new IllegalArgumentException("Odd number of arguments");
String key = null;
Integer step = -1;
for(String value : data){
step++;
switch(step % 2){
case 0:
if(value == null)
throw new IllegalArgumentException("Null key value");
key = value;
continue;
case 1:
result.put(key, value);
break;
}
}
return result;
}
使用如下方法:
HashMap<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");
如果您允许第三方库,您可以使用Guava的ImmutableMap来实现字面上的简洁:
Map<String, String> test = ImmutableMap.of("k1", "v1", "k2", "v2");
这最多适用于5个键/值对,否则您可以使用其生成器:
Map<String, String> test = ImmutableMap.<String, String>builder()
.put("k1", "v1")
.put("k2", "v2")
...
.build();
注意,Guava的ImmutableMap实现与Java的HashMap实现不同(最明显的是它是不可变的,不允许空键/值)有关更多信息,请参阅Guava关于其不可变集合类型的用户指南文章