An elegant way to find out if a Java 8 stream filter filters

I have Listfrom Item, extracted from a database.

I am doing something like:

List<Item> list;
list.stream()
    .filter( i -> i.condition() )
    .mapToLong( Item::asLong )
    .sum()
    ;

Now I want to know if the filter has filtered something so that I can remove it from my database where it is no longer needed.

I could do:

List<Item> list2 = list.stream()
    .filter( i -> i.condition() )
    .collect( Collectors.toList() )
    ;

int theSizeIWant = list2.size();

list2.stream().mapToLong( Item::asLong )
     .sum()
     ;

but I am wondering if there is a more elegant solution that does not need to create an intermediate list.

+4
source share
4 answers

, . partitioningBy(predicate, downstream). , summingLong, .

public static void main(String[] args) {
    List<Item> list = new ArrayList<>();
    Map<Boolean, Long> map = 
        list.stream()
            .collect(Collectors.partitioningBy(
                Item::condition, 
                Collectors.summingLong(Item::asLong)
            ));
    long sumWithTrueCondition = map.get(true);
    long sumWithFalseCondition = map.get(false);
}

, true ( false) true ( false).

, - , sumWithTrueCondition 0. , , sumWithTrueCondition sumWithFalseCondition.

+4

, - .

Map<Boolean, List<Item>> partitions =
    list.stream.collect(Collectors.partitioningBy(i -> i.condition()));

partitions.get(true) , partitions.get(false) , .

+3

:

List<String> strings = Arrays.asList("1", "2", "3", "12", "4", "5");
List<String> badOnes = new ArrayList<>();

strings.stream()
       .filter(s -> {
         boolean returnValue = !s.contains("1");
         if (!returnValue) {
           badOnes.add(s);
         }
         return returnValue;
       })
       .forEach(s -> System.out.println(s));

System.out.println(badOnes);
0

This makes the interim list easier, but still requires a second calculation. If something does not pass the condition, it will not go downstream and will not be counted.

int count = 0;

count must be an instance variable, and then you can do this:

List<Item> list;
list.stream()
    .filter( i -> i.condition() )
    .mapToLong( (item) -> { count++; return item.asLong(); } )
    .sum();

boolean isFiltered = list.size() > count;
0
source

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


All Articles