Can consecutive streaming operations have side effects?

I am trying to pass a limited number of values ​​to a set, but I need to verify that they are new elements before applying the constraint. For instance:

Set<Integer> destination = ... 
Set<Integer> source = ...
source.stream()
        .filter(i -> !destination.contains(i))
        .limit(10)
        .forEach(destination::add);

But redundant checking contains()bothers me, because it add()can both add an item and let it know if it is new to the collection. So I thought about this:

source.stream()
        .filter(destination::add)
        .limit(10)
        .forEach(i -> {});    // no-op terminal operation to force evaluation

Ignoring the operation of a hacked terminal, there is a problem of using a filter operation with a side effect, which is usually not recommended. I can understand why it would be safe to use map()and filter()side effects of parallel streams. My question is: is this acceptable for a sequential thread, as in this case? If not, why not?

+4
2

, , API , .

destination 10 , . no-op forEach 10, .

, java , for while, .

, :

int maxSize = destination.size()+10;
source.stream().allMatch(x -> destination.size()<maxsize && (destination.add(x)||true));

allMatch , false.

+7

:

package be.objectsmith;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Playground {
    public static void main(String[] args) {
        copy(
            IntStream.range(1, 20).boxed().collect(Collectors.toSet()),
            new HashSet<>(Arrays.asList(2, 5)));
        copy(
            IntStream.range(1, 5).boxed().collect(Collectors.toSet()),
            new HashSet<>(Arrays.asList(2, 5)));
    }

    private static void copy(Set<Integer> source, Set<Integer> destination) {
        source
            .stream()
            .map(destination::add)
            .filter(resultOfAdding -> resultOfAdding)
            .limit(10)
            .collect(Collectors.toList());  // Need a terminal operation
        System.out.println("source = " + source);
        System.out.println("destination = " + destination);
    }

}

wil print:

source = [1, 2, 3, 4]
destination = [1, 2, 3, 4, 5]
source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
destination = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

, 10 . , , 10 .

-1

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


All Articles