带有映射和多个集合的Java 8流
我正在尝试使用java8流编写这些行:带有映射和多个集合的Java 8流,java,foreach,hashmap,java-8,java-stream,Java,Foreach,Hashmap,Java 8,Java Stream,我正在尝试使用java8流编写这些行: for (Town town : getAllTowns(routes)) { if (originTown.equals(town)) continue; for (Route route : routes) { if (route.hasOrigin(originTown) && route.hasDestine(town)) {
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>
但是它在forEach调用中,因此我不能将它返回到我的变量
distance
,因为它只为内部调用生成映射。我不明白。任何输入都会非常有用。谢谢 您可以使用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));
Collection towns=getAllTowns(路线);
地图距离=towns.stream()
.filter(城镇->!originTown.equals(城镇))
.map(城镇->路线.stream()
.filter(route->route.hasOrigin(originTown)和&route.hasDestine(town))
.findFirst())
.filter(可选::isPresent)
.collect(toMap(route->route.get().getDestine(),route->route.get().getDistance());
城镇。溪流()
.filter(城镇->!距离.containsKey(城镇))
.forEach(城镇->距离.put(城镇,最大距离));
(请注意,town
在collect()
中不再可用,但您可以利用这样一个事实,即只有当每条路线的目的地城镇是town
时,才能添加该路线)
还要注意,
toMap()
不接受重复的键。如果可以有多条路线到达任何城镇(我认为可能有),则应使用groupingBy()
。我认为您有两种选择来解决此问题。您可以事先创建生成的映射
,然后使用嵌套的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)));
嘿,所以,
toMap()
很好,因为城镇是通过它的名字来识别的,我真的不想要重复的钥匙。它工作得很好。谢谢还有一件事是:有什么好方法可以包含distance.put(town,maxDistance)代码>适用于不满足第二个过滤器要求的所有城镇。因为过滤后,我再也不能使用城镇对象了。谢谢!如果您希望所有条目都在地图中,那么首先为什么要过滤它们?(我可能不明白您想要实现什么;请澄清。)在第二个for
循环中,有一个if语句,用于检查来源和目的地。如果不满意,则输入该城镇的distance
地图maxDistance
。在routes流上使用过滤器
,可以很好地处理原始和目的地匹配的情况。但是我想知道如果它没有匹配项,我将如何在流中执行“else”
操作。@felipe.forbeck:Gah,我没有看到那一行。那会更棘手;我认为最明确的解决办法可能是分两步进行;看看我更新的答案。太棒了!成功了。只需将其用于collect
调用:.collect(Collectors.toMap(route->route.isPresent()?route.get().getDestineTown():null,route->route.isPresent()?route.get().getDistance():0))代码>
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));
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)));
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()));