Java 如何筛选映射并返回值列表

Java 如何筛选映射并返回值列表,java,java-8,hashmap,Java,Java 8,Hashmap,我正在尝试创建一个函数,该函数过滤一个映射,其中包含一个字符串作为键,一个飞行对象列表作为值,并返回一个字符串列表。地图表示飞行路径,任务是找到从起点到目的地的最短路径。 航班类别有两个字段:起点和终点。因此,如果我发送到纽约的维也纳,我应该会得到一个包含flight1和flight2的列表。 该函数接受两个参数(字符串原点、字符串目标) 地图中的键表示一个城市,而值是航班到达的位置,如下所示: Map<String, List<Flight>> paths = new

我正在尝试创建一个函数,该函数过滤一个映射,其中包含一个字符串作为键,一个飞行对象列表作为值,并返回一个字符串列表。地图表示飞行路径,任务是找到从起点到目的地的最短路径。 航班类别有两个字段:起点和终点。因此,如果我发送到纽约的维也纳,我应该会得到一个包含flight1和flight2的列表。 该函数接受两个参数(字符串原点、字符串目标)

地图中的键表示一个城市,而值是航班到达的位置,如下所示:

Map<String, List<Flight>> paths = new HashMap<>();

List<Flight> flightsToBerlin = new ArrayList<>();
List<Flight> flightsToVienna = new ArrayList<>();

Flight flight1 = new Flight("Vienna", "Berlin");
Flight flight2 = new Flight("Berlin", "New York");

flightsToBerlin.add(flight1);
flightsToVienna.add(flight2);


paths.put("Vienna", flightsToVienna);
paths.put("Berlin", flightsToBerlin);
public List<Flight> findPath(String origin, String destination) {
    return (List<Flight>) this.paths.entrySet().stream()
            .filter(x -> x.getKey().equals(destination))..
}
Map path=newhashmap();
List flightsToBerlin=new ArrayList();
List flightstoviena=new ArrayList();
航班1=新航班(“维也纳”、“柏林”);
航班2=新航班(“柏林”、“纽约”);
flightsToBerlin.add(flight1);
flightsToVienna.add(flight2);
“维也纳”,飞往维也纳;
路径。放置(“柏林”,飞至柏林);
诀窍是要求它在一行中完成。这就是让我发疯的部分。我尝试过使用streams,但在过滤地图并找到目的地后,我有点困惑,比如:

Map<String, List<Flight>> paths = new HashMap<>();

List<Flight> flightsToBerlin = new ArrayList<>();
List<Flight> flightsToVienna = new ArrayList<>();

Flight flight1 = new Flight("Vienna", "Berlin");
Flight flight2 = new Flight("Berlin", "New York");

flightsToBerlin.add(flight1);
flightsToVienna.add(flight2);


paths.put("Vienna", flightsToVienna);
paths.put("Berlin", flightsToBerlin);
public List<Flight> findPath(String origin, String destination) {
    return (List<Flight>) this.paths.entrySet().stream()
            .filter(x -> x.getKey().equals(destination))..
}
公共列表findPath(字符串源、字符串目标){
返回(列出)this.path.entrySet().stream()
.filter(x->x.getKey().equals(destination))。。
}
如何从这里开始?

请尝试以下代码:

return (List<Flight>) paths.entrySet()
                    .stream()
                    .filter(x -> x.getKey().equals(destination))
                    .map(Map.Entry::getValue)
                    .flatMap(List::stream) 
                    .collect(Collectors.toList());
return(List)path.entrySet()
.stream()
.filter(x->x.getKey().equals(目标))
.map(map.Entry::getValue)
.flatMap(列表::流)
.collect(Collectors.toList());

您可以这样做:

return Stream.of(
        paths.values()
                .stream()
                .flatMap(Collection::stream)
                .collect(Collectors.groupingBy(Flight::getStartingLocation))
).flatMap(flights ->
        Stream.of(
                new HashMap<>(Map.of(origin, new Flight(origin, origin)))
        ).peek(back ->
                Stream.iterate(
                        List.of(origin),
                        list -> list.stream().flatMap(
                                now -> flights.getOrDefault(now, Collections.emptyList()).stream()
                                        .filter(flight -> back.putIfAbsent(flight.getDestination(), flight) == null)
                                        .map(Flight::getDestination)
                        ).collect(Collectors.toList())
                ).filter(list -> list.contains(destination)).findFirst()
        ).map(back ->
                Stream.iterate(
                        new Flight(destination, null),
                        now -> back.get(now.getStartingLocation())
                )
                        .skip(1)
                        .takeWhile(flight -> !flight.getDestination().equals(origin))
                        .collect(Collectors.toList())
        )
)
        .map(ArrayList::new)
        .peek(Collections::reverse)
        .findFirst().get();
public class Flight {

    private String origin;
    private String dest;

    public Flight(String origin, String dest) {
        this.origin = origin;
        this.dest = dest;
    }

    public String getOrigin() {
        return origin;
    }

    public String getDestination() {
        return dest;
    }

}
returnstream.of(
路径。值()
.stream()
.flatMap(集合::流)
.collect(收集器.groupingBy(航班::getStartingLocation))
).flatMap(航班->
溪流(
新HashMap(地图(原点,新航班(原点,原点)))
).peek(背面->
Stream.iterate(
(原产地)清单,
list->list.stream().flatMap(
现在->flights.getOrDefault(现在是Collections.emptyList()).stream()
.filter(flight->back.putIfAbsent(flight.getDestination(),flight)=null)
.map(航班::获取目的地)
).collect(收集器.toList())
).filter(list->list.contains(destination)).findFirst()
).map(返回->
Stream.iterate(
新航班(目的地,空),
now->back.get(now.getStartingLocation())
)
.skip(1)
.takeWhile(航班->!flight.getDestination().equals(原点))
.collect(收集器.toList())
)
)
.map(ArrayList::新建)
.peek(集合::反向)
.findFirst().get();

您的请求几乎是不可能的。然而,我却能想出一个基本上有效的单行线。它的主要限制是,它只能找到两个航班让你到达目的地。换言之:

Berlin   -> Vienna                       | WORKS 
New York -> Berlin   -> Vienna           | WORKS
Boston   -> New York -> Berlin -> Vienna | DOESN'T WORK

我通常会花时间解释我在回答中所做的事情以及原因,但这是一种对Java语言如此混乱、复杂、低效的厌恶,我怀疑我是否能够解释得足够好。以下是我解释发生了什么,但不是为什么发生的最好尝试:

  • 查找与给定始发地或目的地匹配的航班
  • 检查与给定出发地和目的地匹配的单程航班
  • 如果没有与给定起点和目的地匹配的航班,请比较与起点或目的地匹配的每个航班,查看是否有任何航班同时与给定参数对齐。例如:

             (A1)     (A2)
    findPath(Boston, Tokyo)
    
           (B1)       (B2)                      B1 aligns with A1
    Flight[Boston, Istanbul]                    C2 aligns with A2
                                                C1 aligns with B2
           (C1)      (C2)
    Flight[Istanbul, Tokyo]
    

  • 在实现代码之前,需要进行以下导入:

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Optional;
    import java.util.stream.Collectors;
    import java.util.stream.Stream; 
    
    我还假设您的
    航班
    舱看起来像这样:

    return Stream.of(
            paths.values()
                    .stream()
                    .flatMap(Collection::stream)
                    .collect(Collectors.groupingBy(Flight::getStartingLocation))
    ).flatMap(flights ->
            Stream.of(
                    new HashMap<>(Map.of(origin, new Flight(origin, origin)))
            ).peek(back ->
                    Stream.iterate(
                            List.of(origin),
                            list -> list.stream().flatMap(
                                    now -> flights.getOrDefault(now, Collections.emptyList()).stream()
                                            .filter(flight -> back.putIfAbsent(flight.getDestination(), flight) == null)
                                            .map(Flight::getDestination)
                            ).collect(Collectors.toList())
                    ).filter(list -> list.contains(destination)).findFirst()
            ).map(back ->
                    Stream.iterate(
                            new Flight(destination, null),
                            now -> back.get(now.getStartingLocation())
                    )
                            .skip(1)
                            .takeWhile(flight -> !flight.getDestination().equals(origin))
                            .collect(Collectors.toList())
            )
    )
            .map(ArrayList::new)
            .peek(Collections::reverse)
            .findFirst().get();
    
    public class Flight {
    
        private String origin;
        private String dest;
    
        public Flight(String origin, String dest) {
            this.origin = origin;
            this.dest = dest;
        }
    
        public String getOrigin() {
            return origin;
        }
    
        public String getDestination() {
            return dest;
        }
    
    }
    

    好的,这是你的一句台词:

    @SuppressWarnings("unchecked")
    public List<Flight> findPath(String origin, String destination) {
        return new ArrayList<Flight>((Collection<Flight>) this.paths.values().stream().map(l -> l.stream().filter(f -> f.getDestination().equalsIgnoreCase(destination)|| f.getOrigin().equalsIgnoreCase(origin)).collect(Collectors.toList())).map(t -> new Object[] { t.stream().filter(f -> f.getDestination().equalsIgnoreCase(destination)&& f.getOrigin().equalsIgnoreCase(origin)).findAny(), t }).map(t -> ((Optional<Flight>) t[0]).isPresent() ? ((Optional<Flight>) t[0]).get() : t[1]).reduce((t, u) -> t instanceof Flight ? new HashSet<Flight>(Arrays.asList((Flight) t)): t instanceof HashSet ? t: u instanceof Flight ? new HashSet<Flight>(Arrays.asList((Flight) u)): u instanceof HashSet ? u: Stream.concat(((List<Flight>) t).stream().filter(f1 -> (f1.getDestination().equalsIgnoreCase(destination)&& ((List<Flight>) u).stream().anyMatch(f2 -> f1.getOrigin().equalsIgnoreCase(f2.getDestination())))|| (f1.getOrigin().equalsIgnoreCase(origin)&& ((List<Flight>) u).stream().anyMatch(f2 -> f1.getDestination().equalsIgnoreCase(f2.getOrigin())))),((List<Flight>) u).stream().filter(f1 -> (f1.getDestination().equalsIgnoreCase(destination)&& ((List<Flight>) t).stream().anyMatch(f2 -> f1.getOrigin().equalsIgnoreCase(f2.getDestination())))|| (f1.getOrigin().equalsIgnoreCase(origin)&& ((List<Flight>) t).stream().anyMatch(f2 -> f1.getDestination().equalsIgnoreCase(f2.getOrigin()))))).collect(Collectors.toList())).get());
    }
    
    @SuppressWarnings(“未选中”)
    公共列表findPath(字符串源、字符串目标){
    返回新的ArrayList((集合)this.paths.values().stream().map(l->l.stream().filter(f->f.getDestination().equalsIgnoreCase(destination)| f.getOrigin().equalsIgnoreCase(origin)).collect(Collectors.toList()).map(t->新对象[]{t.stream().filter(f->f.getDestination().equalsIgnoreCase)和&f.GetOriginance()(origin)).findAny(),t}).map(t->((可选)t[0]).isPresent()?((可选)t[0]).get():t[1]).reduce((t,u)->飞行的t实例?新哈希集(Arrays.asList((Flight)t)):飞行的t实例?新哈希集(Arrays.asList((Flight)u)):哈希集的u实例?u:Stream.concat((List)t).Stream().过滤器(f1->)(f1.getDestination().equalsIgnoreCase(destination)和((List)u).stream().anyMatch(f2->f1.getOrigin().equalsIgnoreCase(f2.getDestination()))))| |(f1.getOrigin().equalsIgnoreCase(origin)和((List)u).stream().anyMatch(f2->->.getDestination().equalsIgnoreCase()(destination)和((List)t).stream().anyMatch(f2->f1.getOrigin().equalsIgnoreCase(f2.getDestination()))| |(f1.getOrigin().equalsIgnoreCase(origin)和((List)t).stream().anyMatch(f2->f1.getDestination().equalsIgnoreCase(f2.getOrigin())))).collect(collector.toList()).get());
    }
    
    如果没有这样的值,你怎么能找到最短路径?更新了问题,希望现在问题更清楚了。欢迎这么做!最短路径需要类似BFS的东西,使用队列和集合来避免循环。我不确定如何在一行中准确地完成这项工作……你是su吗