当然,你可以不使用流来完成它,这样可能会使代码更易读。
Map<Radio, Station> LOOK_UP = new HashMap<>();
List<Station> stations = ...
stations.forEach(station -> {
station.getRadios().forEach(radio -> {
LOOK_UP.put(radio, station);
});
});
这与普通循环并没有太大的区别:
for (Station station : stations) {
for (Radio radio : station.getRadios()) {
LOOK_UP.put(radio, station);
}
}
这里显然存在一个问题,即
LOOK_UP::put
总是会替换某个键的值,隐藏了您曾经有重复的事实。例如:
[StationA = {RadioA, RadioB}]
[StationB = {RadioB}]
当你搜索
RadioB
时,你应该得到什么结果?
如果你能有这样的场景,显而易见的是改变
LOOK-UP
的定义并使用
Map::merge
。
Map<Radio, List<Station>> LOOK_UP = new HashMap<>();
List<Station> stations = new ArrayList<>();
stations.forEach(station -> {
station.getRadios().forEach(radio -> {
LOOK_UP.merge(radio,
Collections.singletonList(station),
(left, right) -> {
List<Station> merged = new ArrayList<>(left);
merged.addAll(right);
return merged;
});
});
});
另一种可能性是在存在这些映射时抛出异常:
stations.forEach(station -> {
station.getRadios().forEach(radio -> {
LOOK_UP.merge(radio, station, (left, right) -> {
throw new RuntimeException("Duplicate Radio");
});
});
});
这个最后一段代码片段的问题在于,你无法真正记录导致非唯一性的
radio
。
left
和
right
都是
Stations
。如果你也想要记录它们,你需要使用一个不依赖于
Map::merge
内部的
合并器,就像
this answer中所示。
因此,你可以看到,所有这些都取决于你需要如何以及确切需要处理什么。
stationList.stream().forEach(station -> station.getRadioList().stream().forEach(rl -> radioToStationMap.put(rl, station)))
还不够好吗? - ZhenyaMcollect
方法将数据写入可变列表要比使用forEach
更好。 - RealSkeptic