How can I rewrite this classic Java code to Java Stream API code?

There is old Java code (without lambda expressions):

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

I am trying to rewrite this code in the Java 8 Stream API style :

 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... 

PROBLEM: The isCheckerBlocked() function (which uses filter() in the last operation) accepts a variable of type VectorDirection (variable d ). But after calling the map() function, I lose access to this variable. How can I save access to the variable d after calling the map() function?

Thank you for attention.

+6
source share
1 answer

You cannot share lambda areas. In other languages, you can use tuples, so instead of returning only the result, you return the result and the argument.

In java, you can create your own class to accommodate a pair of required data or create a Tuple to host a pair of data.

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

import static so.alpha.Tuple.tuple; importing a static tuple function like import static so.alpha.Tuple.tuple; , you can map(tuple(d,f(d)))) , then your next function will be filter(t->p(t._1,t._2)) , and then you will map(t->t._1) or if you add getters to the tuple, you can also map(Tuple::get_1)

So you can continue your d until the next step.

  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 
+5
source

Source: https://habr.com/ru/post/1015070/


All Articles