masterofdisaster
masterofdisaster

Reputation: 1159

Streams in Java, can't figure this code out

I've found the following code snippet:

Function<Integer, Predicate<Integer>> smallerThan = x -> y -> y < x;
List<Integer> l = Arrays.asList(5, 6, 7, 23, 4, 5645,
    6, 1223, 44453, 60182, 2836, 23993, 1);

List<Integer> list2 = l.stream()
    .filter(smallerThan.apply(l.get(0)))
    .collect(Collectors.toList());

System.out.println(list2);

As output I receive:

[4, 1]

How does the smallerThan function in this example work, considering that we only pass one parameter smallerThan.apply(l.get(0))?

Upvotes: 15

Views: 1266

Answers (3)

Eugene
Eugene

Reputation: 120848

That is called "currying" and it was possible before Java 8 too via anonymous classes for example, but it was much more verbose. Ultimately, it's a Function that returns a Function and while not that spread in Java (yet), in other functional languages it is used quite heavily.

Upvotes: 13

Eran
Eran

Reputation: 393791

smallerThan is a Function that accepts a single Integer and returns a Predicate<Integer> (a Predicate<Integer> is a function that accepts a single Integer and returns a boolean).

smallerThan.apply(l.get(0)) returns a Predicate<Integer> that looks like this:

y -> y < l.get(0)

i.e. it returns true if the input passed to it is smaller than l.get(0).

When you pass that Predicate to filter, your Stream pipeline keeps only the elements smaller than l.get(0).

Your pipeline can be re-written as:

List<Integer> list2 = l.stream()
    .filter(y -> y < l.get(0))
    .collect(Collectors.toList());

Since l.get(0) is 5, your pipeline returns all the elements of the original list smaller than 5.

Upvotes: 19

Ousmane D.
Ousmane D.

Reputation: 56423

The function smallerThan accepts a number and returns a Predicate object, in which case we apply this predicate to every element of the stream.

So, l.get(0) will retrieve the first value of the list l which is (5), we then pass it to the smallerThan function and this function returns a predicate with the criteria y -> y < x; which reads as "given a number, return true if it is less than 5" hence output is [4, 1]

Upvotes: 8

Related Questions