Java Stream API storing lambda expression as a variable

This name sounds silly even to me, but there must be at least a somewhat clever way to achieve this effect, and I don't know how else to explain it. I need to sort an array using a sorted in a threaded API. Here is my thread:

Arrays.stream(sequence.split(" ")) .mapToInt(Integer::parseInt) .boxed() .sorted((a, b) -> a.compareTo(b)) .forEach(a -> System.out.print(a + " ")); 

Now I have two different types: ascending and descending, and the sorting I need to use is indicated in user input. So I want to do something like a switch with two cases: upstream and downstream and a variable to hold the lambda expression, respectively:

 switch(command) { case "ascending": var = a.compareTo(b); case "descending": var = b.compareTo(a); } 

Then I sorted as follows:

  .sorted((a, b) -> var) 

I got an idea in the python course that I studied in. There it was available to store the object in a variable, thereby making the variable "executable". I understand that this lambda is not an object, but an expression, but I ask if there is any smart way to achieve this result, or I just need

 if(var) 

and two different threads for each sort order.

+3
java lambda java-8 java-stream
source share
3 answers

The question is not stupid at all. Answering this in a broader sense: unfortunately, there is no general solution for this. This is due to the type of output, which defines one specific type for the lambda expression based on the target type. (The output type section may be useful here, but does not cover all the details regarding lambdas.)

In particular, such a lambda as x -> y does not exist. Thus, there is no way to write

GenericLambdaType function = x -> y;

and then use function as a replacement for the actual lambda x -> y .

For example, when you have two functions, such as

 static void useF(Function<Integer, Boolean> f) { ... } static void useP(Predicate<Integer> p) { ... } 

you can call them both with the same lambda

 useF(x -> true); useP(x -> true); 

but there is no way to "store" the lambda x -> true in such a way that it can later be passed to both functions , you can only store it in a link with the type that you will need later:

 Function<Integer, Boolean> f = x -> true; Predicate<Integer> p = x -> true; useF(f); useP(p); 

In your particular case, Konstantin Yovkov’s answer already showed a solution: you should save it as a Comparator<Integer> (ignoring the fact, I need the first lambda in the first place ...)

+7
source share

You can switch between Comparator.reverseOrder() and Comparator.naturalOrder :

 Comparator<Integer> comparator = youWantToHaveItReversed ? Comparator.reverseOrder(): Comparator.naturalOrder(); Arrays.stream(sequence.split(" ")) .map(Integer::valueOf) .sorted(comparator) .forEach(a -> System.out.print(a + " ")); 
+7
source share

In Lambdas, you can use the function block (a,b) -> { if(anything) return 0; else return -1;} (a,b) -> { if(anything) return 0; else return -1;}

+1
source share

All Articles