i have to calculate the average of a Infinite Sequence using Stream API
Input:
Stream<Double> s = a,b,c,d ...
int interval = 3
Expected Result:
Stream<Double> result = avg(a,b,c), avg(d,e,f), ....
the result can be also an Iterator, or any other type as long as it mantains the structure of an infinite list
of course what i written is pseudo code and doesnt run
The meaning is the same: For example, a 1 is equivalent to f (1). A simple example of an infinite sequence is 1, 4, 9, 16, 25, …. The elements here (a.k.a. the range) are called the terms of the sequence. Note that you can’t just write down a list of numbers and call it a “sequence”. It has to be a function.
An infinite series (also called an infinite sum) is a series that keeps on going until infinity. For example, 1 + 1 + … or 1 + 2 + 3 +…. In notation, it’s written as:
Given a set of time intervals in any order, merge all overlapping intervals into one and output the result which should have only mutually exclusive intervals. Let the intervals be represented as pairs of integers for simplicity.
5) The Fibonacci sequence 1, 1, 2, 3, 5, 8, … diverges. 6) The sequence 2, − 1, 1 2, − 1 4, 1 8, − 1 16, … is an example of a geometric sequence (see below; here, a = 2 and r = − 1 2 ).
There is a @Beta
API termed mapWithIndex
within Guava that could help here with certain assumption:
static Stream<Double> stepAverage(Stream<Double> stream, int step) {
return Streams.mapWithIndex(stream, (from, index) -> Map.entry(index, from))
.collect(Collectors.groupingBy(e -> (e.getKey() / step), TreeMap::new,
Collectors.averagingDouble(Map.Entry::getValue)))
.values().stream();
}
The assumption that it brings in is detailed in the documentation clearly(emphasized by me):
The resulting stream is efficiently splittable if and only if stream was efficiently splittable and its underlying spliterator reported
Spliterator.SUBSIZED
. This is generally the case if the underlying stream comes from a data structure supporting efficient indexed random access, typically an array or list.
This should work fine using vanilla Java
I'm using Stream#mapMulti
and a Set
external to the Stream
to aggregate the doubles
As you see, I also used DoubleSummaryStatistics
to count the average.
I could have use the traditional looping and summing then dividing but I found this way more explicit
Update:
I changed the Collection
used from Set
to List
as a Set
could cause unexpected behaviour
int step = 3;
List<Double> list = new ArrayList<>();
Stream<Double> averagesStream =
infiniteStream.mapMulti(((Double aDouble, Consumer<Double> doubleConsumer) -> {
list.add(aDouble);
if (list.size() == step) {
DoubleSummaryStatistics doubleSummaryStatistics = new DoubleSummaryStatistics();
list.forEach(doubleSummaryStatistics::accept);
list.clear();
doubleConsumer.accept(doubleSummaryStatistics.getAverage());
}
}));
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