Map
是我们常用到的一个容器,我们会用 map 来保存一些后续需要查找的数据,
今天我们来看一下,在 Java 中如何使用一行代码来初始化 map。
一般我们初始化 map 是这样:
Map<String, Runnable> map = new HashMap<>();
map.put("a", new Runnable() {
@Override
void run() {
logger.info("running a");
}
});
map.put("b", new Runnable() {
@Override
void run() {
logger.info("running b");
}
});
这样一个 map 就初始化完成了,不过如果这个 map 是某个类的成员变量, 如果想要在定义时就执行初始化,那么我们可能会需要创建一个函数:
class A {
Map<String, Runnable> createMap() {
Map<String, Runnable> map = new HashMap<>();
map.put("a", new Runnable() {
@Override
void run() {
logger.info("running a");
}
});
map.put("b", new Runnable() {
@Override
void run() {
logger.info("running b");
}
});
return map;
}
Map<String, Runnable> map = createMap();
}
这么做似乎有点啰嗦,那么有没有一种办法一次性同时完成定义和初始化呢?
Arrays
我们可以利用 Arrays.asList
方法,先创建一个 List<Entry>
然后转成 Stream
,
接下来 collect
成 map,拆解步骤是这样:
import java.util.Arrays;
import java.util.AbstractMap.SimpleEntry;
List<SimpleEntry> list = Arrays.asList(
new SimpleEntry<>("a", new Runnable() {
@Override
void run() {
logger.info("running a");
}
}),
new SimpleEntry<>("b", new Runnable() {
@Override
void run() {
logger.info("running b");
}
})
);
Map<String, Runnable> map = list.stream().collect(Collectors.toMap(
d -> d.getKey(), d -> d.getValue()
));
合并为一步会变成这样:
Map<String, Runnable> map = Arrays.asList(
new SimpleEntry<>("a", new Runnable() {
@Override
void run() {
logger.info("running a");
}
}),
new SimpleEntry<>("b", new Runnable() {
@Override
void run() {
logger.info("running b");
}
})
).stream().collect(Collectors.toMap(
d -> d.getKey(), d -> d.getValue()
));
这样我们就完成了一步同时完成定义和初始化。
Stream
如果我们更熟悉 Stream
,这个方法还可以进一步简化,
我们可以完全把创建 List
的这个步骤去掉,直接从 Stream
开始:
import java.util.stream.Stream;
Map<String, Runnable> map = Stream.of(
new SimpleEntry<>("a", new Runnable() {
@Override
void run() {
logger.info("running a");
}
}),
new SimpleEntry<>("b", new Runnable() {
@Override
void run() {
logger.info("running b");
}
})
).collect(Collectors.toMap(
d -> d.getKey(), d -> d.getValue()
));
很多人都觉得 java 是一门比较啰嗦的语言,所以我会尽量去简化一些写法, 当然写法的问题有时候见仁见智,可能也会有读者觉得这样写会不太清晰, 调试起来也比较复杂,我是觉得清晰的话,熟悉 stream 其实还好, 调试的话确实有些不便,但是其实我们不太需要调试 map 的初始化过程, 当然肯定会有例外,这个写法最大的问题,我想可能是实际写的时候, 如果代码中有语法或是依赖问题,就很难去寻找到底是哪部分代码出了问题, 这时一般我会采用分离的方式把代码写出来,看看问题在哪里,然后再改回去。 总体而言,这个也还是目前我比较满意的初始化 map 的方法。