由于您在此处同时需要列表中的两个值,因此我不确定使用流实现此目的的方法。 (其他人可能会发表评论。)但是,因为我发现这个问题很有趣,所以我很快在一个简单的 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()。