code: public static DoubleStream shiftingWindowAveragingDouble(DoubleStream doubleStream, int rollingFactor) {
          Objects.requireNonNull(doubleStream);
  
          RollingOfDoubleSpliterator ofDoubleSpliterator = RollingOfDoubleSpliterator.of(doubleStream.spliterator(), rollingFactor);
          return StreamSupport.stream(ofDoubleSpliterator, doubleStream.isParallel())
                  .onClose(doubleStream::close)
                  .mapToDouble(subStream -> subStream.average().getAsDouble());
      }
docs: <p>Generates a stream that is computed from a provided double stream by first rolling it in the same
  way as the <code>roll()</code> method does. The average is then computed on each substream, to
  form the final double stream. No boxing / unboxing is conducted in the process.
  <p>The resulting stream has the same number of elements as the provided stream,
  minus the size of the window width, to preserve consistency of each collection. </p>
  <p>A <code>NullPointerException</code> will be thrown if the provided stream is null.</p>
  
  @param doubleStream  the processed stream
  @param rollingFactor the size of the window to apply the collector on
  @return a stream in which each value is the collection of the provided stream