我如何将这个经典的Java代码重写为Java Stream API代码?

V. *_*roz 6 java collections lambda java-8 java-stream

有一个旧的Java代码(没有lambda表达式):

public List<CheckerPosition> getAttackedCheckersForPoint(CheckerPosition from, boolean isSecondPlayerOwner, boolean isQueen, VectorDirection ignoredDirection){
    List<VectorDirection> allDirections = VectorDirection.generateAllDirections();
    List<CheckerPosition> result = new ArrayList<CheckerPosition>();

    for (VectorDirection direction : allDirections){
        if (!direction.equals(ignoredDirection)){
            Checker firstCheckerOnWay = findFirstCheckerOnWay(new CheckerBaseVector(from, direction), !isQueen);
            if ((firstCheckerOnWay != null) && (firstCheckerOnWay.isSecondPlayerOwner() != isSecondPlayerOwner) && isCheckerBlocked(firstCheckerOnWay.getPosition(), direction)){
                result.add(firstCheckerOnWay.getPosition());
            }
        }
    }
    return result;
 }
Run Code Online (Sandbox Code Playgroud)

我正在尝试将此代码重写为Java 8 Stream API样式:

allDirections.stream()
                .filter(d -> !d.equals(ignoredDirection))
                .map(d -> findFirstCheckerOnWay(new CheckerBaseVector(from, d), !isQueen)) // In this operation I map VectorDirection element (d) to Checker variable type.
                .filter(c -> (c != null) && (c.isSecondPlayerOwner() != isSecondPlayerOwner) && isCheckerBlocked(c.getPosition(), d)); // But in this operation I need to access d variable...
Run Code Online (Sandbox Code Playgroud)

问题:函数isCheckerBlocked()(在最后一个filter()操作中使用)采用VectorDirection类型(变量d)的变量.但在调用map()函数后,我无法访问此变量.如何d在调用map()函数后保存对变量的访问?

感谢您的关注.

min*_*nus 5

你无法分享这样的lambdas范围.在其他语言中,您可以使用元组,因此不返回结果,而是返回结果参数.

在java中,您可以创建一个自定义类来托管您需要的数据对,或者创建一个Tuple来托管这对数据.

public class Tuple<A,B> {
    public final A _1;
    public final B _2;
    public Tuple(A a, B b){
        _1 = a;
        _2 = b;
    }
    public static <A,B> Tuple<A,B> tuple(A a, B b){
        return new Tuple<>(a, b);
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样导入元组静态函数import static so.alpha.Tuple.tuple;你可以 map(tuple(d,f(d))))然后你的下一个函数filter(t->p(t._1,t._2))然后你将map(t->t._1)或者如果你添加getters到元组你也可以map(Tuple::get_1)

这样,你可以对你进行d下一步.

    Stream<String> s = Arrays.asList("sa","a","bab","vfdf").stream();

    Stream<Integer> result = s.map(d -> tuple(d.length(),d)) //String to Tuple<Integer,String>
        .filter(t->t._1 >= 2 && t._2.contains("a")) // Filter using both
        .map(Tuple::get_1); // Return just Integers
Run Code Online (Sandbox Code Playgroud)