2017-02-17 10 views
6

(ラムダ式なし)古いJavaコードがあります:この古典的なJavaコードをJava Stream APIコードにどのように書き換えることができますか?

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; 
} 

私はのJava 8ストリーム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... 

問題:isCheckerBlocked()(最後にfilter()オペレーションを使用)は、VectorDirectionタイプ(変数d)の変数をとります。しかし、map()関数を呼び出すと、この変数へのアクセスが失われます。 map()関数を呼び出すと、d変数へのアクセスをどのように保存できますか?

ありがとうございました。

+2

新しいタイプにマップしたら、 'direction'にアクセスすることはできません。おそらく、 'VectorDirection'と' Checker'をカプセル化する新しいオブジェクトを作成し、そのタイプに 'direction'をマップすることができます。 – user7

+3

別の可能性:マッピングステップで、cとdの両方がスコープ内にある場合、isCheckerBlockedの場合はnullにマップすることができます –

+2

そのように書き直す理由があるかどうかわかりません。私はそれがコードをより読みやすくし、魅力的で、演技的にする方法を見ていない – Calculator

答えて

5

このようなラムダのスコープは共有できません。他の言語ではタプルを使うことができるので、結果だけを返すのではなく、結果としてという引数を返します。

javaでは、必要なデータのペアをホストするカスタムクラスを作成したり、データのペアをホストするタプルを作成したりすることができます。あなたがmap(tuple(d,f(d))))その後、あなたの次の機能がfilter(t->p(t._1,t._2))になりますことができ、その後、あなたがmap(t->t._1)でしょうかあなたができるあなたができるもmap(Tuple::get_1)

タプルにゲッターを追加する場合はそのように、このimport static so.alpha.Tuple.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); 
    } 
} 

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 
関連する問題