I have a List
of Item
fetched from a database.
I do 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 out something so I could delete this 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 wonder if there is a more elegant solution which doesn't need to create the intermediate list.
The java.io package provides a set of abstract classes that define and partially implement filter streams. A filter stream filters data as it's being read from or written to the stream. The filter streams are FilterInputStream or FilterOutputStream , FilterInputStream , and FilterOutputStream. .
Java stream provides a method filter() to filter stream elements on the basis of given predicate. Suppose you want to get only even elements of your list then you can do this easily with the help of filter method. This method takes predicate as an argument and returns a stream of consisting of resulted elements.
Java 8 Stream interface introduces filter() method which can be used to filter out some elements from object collection based on a particular condition. This condition should be specified as a predicate which the filter() method accepts as an argument.
You have to consume the stream to find out if it's empty. That's the point of Stream's semantics (laziness). To check that the stream is not empty you have to attempt to consume at least one element. At that point the stream has lost its "virginity" and cannot be consumed again from the start.
A possible solution would be to partition the Stream with the predicate and sum the values. Partitioning is done with partitioningBy(predicate, downstream)
. In this case, the predicate would be your filtering function and the downstream collector would be summingLong
to sum the values.
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);
}
The map will contain the sum where the predicate is true
(resp. false
) with the true
key (resp. false
).
This way, if something has been filtered, sumWithTrueCondition
will be strictly greater than 0. Furthermore, you can get the total sum by adding sumWithTrueCondition
and sumWithFalseCondition
.
Yes, you can do something like this.
Map<Boolean, List<Item>> partitions =
list.stream.collect(Collectors.partitioningBy(i -> i.condition()));
Where partitions.get(true)
will get you the good ones and partitions.get(false)
will get you the ones to be deleted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With