[英]Java Streams: filtering with 2 objects
我的问题是,我有一系列连接两个地方的道路,我想在没有直接连接的情况下找到从 A 到 B 的所有连接,因此行程将从 A 到 X(甚至到 Y)到 B。但是,当我已经知道没有直接连接时,我现在不知道如何过滤,因为我认为我需要 1 个以上的对象。
routes = allroutes
.stream()
.filter(p -> p.getStart() == start)
.filter(p,x -> p.getEnd() == x.getStart())
.filter(x -> x.getEnd() == end)
和 filter(p,x....) 是不起作用的东西,但我不知道如何以不同的方式解决它。 当然,所有流、列表等之前都已正确初始化。
由于您在此处同时需要列表中的两个值,因此我不确定使用流实现此目的的方法。 (其他人可能会发表评论。)但是,因为我发现这个问题很有趣,所以我很快就在一个简单的 Java 类上进行了尝试。 我使用了一个简单的for..each
循环而不是 Java 流。
public class RouteFinder{
public static void main( String[] args ){
List<Route> allroutes = new ArrayList<>();
populateData( allroutes );
findIndirectBetween( allroutes, "A", "B" ).forEach( System.out::println );
}
private static List<Route> findIndirectBetween( List<Route> allroutes, String start, String end ){
List<Route> selected = new ArrayList<>();
if( start.equals( end ) ) return selected;
for( Route route : allroutes ) {
List<String> rStops = route.getStops();
if( !rStops.contains( start ) || !rStops.contains( end ) ) continue;
int startIndex = rStops.indexOf( start );
int endIndex = rStops.indexOf( end );
if( startIndex != endIndex + 1 && startIndex != endIndex -1 ) selected.add( route );
}
return selected;
}
private static void populateData( List<Route> routes ) {
routes.add( Route.of( "1", "A", "H", "C", "B" ) );
routes.add( Route.of( "2", "A", "B" ) );
routes.add( Route.of( "3", "C", "K", "L", "Z" ) );
routes.add( Route.of( "4", "C", "L", "Z" ) );
routes.add( Route.of( "5", "C", "B", "Z", "A" ) );
}
private static class Route{
private String routeNumber;
private List<String> stops = new ArrayList<>();
public Route( String routeNumber, List<String> stops) {
super();
this.routeNumber = routeNumber;
this.stops = stops;
}
public static Route of( String number, String... stops ) {
List<String> ss = new ArrayList<>();
if( stops != null ) for( String s : stops ) ss.add( s );
return new Route( number, ss );
}
public String getStart() {
if( this.stops != null && this.stops.size() > 0 ) return this.stops.get( 0 );
return "";
}
public String getEnd() {
if( this.stops != null && this.stops.size() > 0 ) return this.stops.get( this.stops.size() - 1 );
return "";
}
public List<String> getStops(){
return this.stops;
}
public String getRouteNumber(){
return routeNumber;
}
@Override
public String toString(){
return "routeNumber=" + routeNumber + ", stops=" + stops;
}
}
}
再想一想,我认为有一种方法可以使用流来做到这一点。
private static List<Route> findIndirectBetweenUsingStreams( List<Route> allroutes, String start, String end ){
return allroutes.stream()
.filter( r -> r.getStops().contains( start ) ) //Retain routes which have "start"ing point
.filter( r -> r.getStops().contains( end ) ) //Retain routes which have "end" point
.collect( ArrayList::new, ( newRouteList, r ) -> {
List<String> rStops = r.getStops();
int startIndex = rStops.indexOf( start );
int endIndex = rStops.indexOf( end );
if( startIndex != endIndex + 1 && startIndex != endIndex -1 ) newRouteList.add( r );
},
( newRouteList, r ) -> {} );
}
这段代码使用了模型Route
和我上面粘贴的类中的基本代码。 可以调用此方法而不是findIndirectBetween()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.