我正在尝试使用java8流编写这些行:
for (Town town : getAllTowns(routes)) {
if (originTown.equals(town))
continue;
for (Route route : routes) {
if (route.hasOrigin(originTown) && route.hasDestine(town)) {
distances.put(town, route.getDistance());
break;
}
distances.put(town, maxDistance);
}
}
return distances; //Map<Town,Integer>
到目前为止我得到的结果是:
Map<Town, Integer> distances = getAllTowns(routes).stream()
.filter(town -> !originTown.equals(town))
.forEach(town -> routes.stream()
.filter(route -> route.hasOrigin(originTown) && route.hasDestine(town)
...)
return distances;
如何在内部过滤器之后收集并构建Map&lt;镇,整型&GT;其中整数是route.getDistance()? 我试着用:
.collect(Collectors.toMap(route -> route.getDestineTown(), route -> route.getDistance()))
但它在forEach调用中,然后我无法将其返回到我的变量distances
,因为它仅为内部调用生成映射。我不明白。任何输入都会非常有用。谢谢。
答案 0 :(得分:2)
您可以使用findFirst()
构建一个列表,其中包含针对每个城镇的第一条路线,该路线将该城镇作为目的地,然后在其上调用toMap()
。缺失城市的默认值可以单独处理。
Collection<Town> towns = getAllTowns(routes);
Map<Town, Integer> distances = towns.stream()
.filter(town -> !originTown.equals(town))
.map(town -> routes.stream()
.filter(route -> route.hasOrigin(originTown) && route.hasDestine(town))
.findFirst())
.filter(Optional::isPresent)
.collect(toMap(route -> route.get().getDestine(), route -> route.get().getDistance()));
towns.stream()
.filter(town -> !distances.containsKey(town))
.forEach(town -> distances.put(town, maxDistance));
(请注意town
中不再提供collect()
,但您可以利用每条路线仅在其目的地城镇为town
时才会添加的事实。)
另请注意,toMap()
不接受重复的密钥。如果可以有多条路线到任何城镇(我假设可能有),您应该使用groupingBy()
代替。
答案 1 :(得分:1)
我认为您有两种方法可以解决这个问题。您可以事先创建结果Map
并使用嵌套的foreach
s:
Map<Town, Integer> distances = new HashMap<>();
getAllTowns(routes).stream().filter(town -> !originTown.equals(town))
.forEach(town -> routes.stream().forEach(route -> distances.put(town,
route.hasOrigin(originTown) && route.hasDestine(town) ? route.getDistance() : maxDistance)));
另一个选项是collect
您的信息流为Map
,方法是创建一个中间Object
,它基本上是一对Town
和Integer
:< / p>
Map<Town, Integer> distances = getAllTowns(routes).stream().filter(town -> !originTown.equals(town))
.flatMap(town -> routes.stream()
.map(route -> new AbstractMap.SimpleEntry<Town, Integer>(town,
route.hasOrigin(originTown) && route.hasDestine(town) ? route.getDistance()
: maxDistance)))
.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));