简体   繁体   中英

Lambda expressions in Java using predicate object in filter

This is simple code selecting a random subset of integers from a list of integers using lambda expressions. What the function is doing is, iterate through the list and for each element a random boolean value is called. Based on that element is selected or discarded.

public static List<Integer> getRandomSubsetUsingLambda(List<Integer> list) {
    List<Integer> randomSubset = new ArrayList<>();
    Random random = new Random();
    Predicate<Object> flipCoin = o -> {
        return random.nextBoolean();
    };

    randomSubset = list.stream().filter(flipCoin).collect(Collectors.toList());
    return randomSubset;
}

My understanding is that filter, based on ta boolean value selects the integers. But I didn't understand how is that happening. Does it mean that whenever flipCoin is called a boolean value is returned?

filter() will call to flipCoin passing as parameter the iterated value from the stream. Then flipCoin will generate a random boolean (ignoring the value of its parameter) and if false the iterated value from the stream will be discarded.

ie for each element in the stream a random boolean is generated and used to decide (randomly) if the element is accepted or discarded.

Let's pick a practical example with a List containing three elements [1, 2, 3]

1

list.stream()
    .filter(flipCoin) // random.nextBoolean() returns true so 1 goes through
    .collect(Collectors.toList()); // 1 is waiting to be added to the list

2

list.stream()
    .filter(flipCoin) // random.nextBoolean() returns false and 2 is blocked
    .collect(Collectors.toList()); 

3

list.stream()
    .filter(flipCoin) // random.nextBoolean() returns true 
    .collect(Collectors.toList()); // 3 is the last element of your stream so the list is created

The new List contains [1, 3]

Basically, everytime filter(flipCoin) is invoked, the following block code is executed for each element going through it (here Integer s)

public boolean test(Object o) {
    return random.nextBoolean();
}

Basically, your stream is the equivalent of the following code block

List<Integer> newList = new ArrayList<>();
for (Integer i : list) {
    boolean shouldBeAddedToNewList = random.nextBoolean();
    if (shouldBeAddedToNewList) {
        newList.add(i);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM