Skip to content

Commit

Permalink
Add DoubleStream scan operators
Browse files Browse the repository at this point in the history
  • Loading branch information
aNNiMON committed Feb 21, 2017
1 parent 8f9bde9 commit 21689c8
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 0 deletions.
87 changes: 87 additions & 0 deletions stream/src/main/java/com/annimon/stream/DoubleStream.java
Expand Up @@ -695,6 +695,93 @@ public double nextDouble() {
});
}

/**
* Returns a {@code DoubleStream} produced by iterative application of a accumulation function
* to reduction value and next element of the current stream.
* Produces a {@code DoubleStream} consisting of {@code value1}, {@code acc(value1, value2)},
* {@code acc(acc(value1, value2), value3)}, etc.
*
* <p>This is an intermediate operation.
*
* <p>Example:
* <pre>
* accumulator: (a, b) -&gt; a + b
* stream: [1, 2, 3, 4, 5]
* result: [1, 3, 6, 10, 15]
* </pre>
*
* @param accumulator the accumulation function
* @return the new stream
* @throws NullPointerException if {@code accumulator} is null
* @since 1.1.6
*/
public DoubleStream scan(final DoubleBinaryOperator accumulator) {
Objects.requireNonNull(accumulator);
return new DoubleStream(new PrimitiveExtIterator.OfDouble() {

private double value;

@Override
protected void nextIteration() {
hasNext = iterator.hasNext();
if (hasNext) {
value = iterator.next();
if (isInit) {
next = accumulator.applyAsDouble(value, next);
} else {
next = value;
}
}
}
});
}

/**
* Returns a {@code DoubleStream} produced by iterative application of a accumulation function
* to an initial element {@code identity} and next element of the current stream.
* Produces a {@code DoubleStream} consisting of {@code identity}, {@code acc(identity, value1)},
* {@code acc(acc(identity, value1), value2)}, etc.
*
* <p>This is an intermediate operation.
*
* <p>Example:
* <pre>
* identity: 0
* accumulator: (a, b) -&gt; a + b
* stream: [1, 2, 3, 4, 5]
* result: [0, 1, 3, 6, 10, 15]
* </pre>
*
* @param identity the initial value
* @param accumulator the accumulation function
* @return the new stream
* @throws NullPointerException if {@code accumulator} is null
* @since 1.1.6
*/
public DoubleStream scan(final double identity, final DoubleBinaryOperator accumulator) {
Objects.requireNonNull(accumulator);
return new DoubleStream(new PrimitiveExtIterator.OfDouble() {

private double value;

@Override
protected void nextIteration() {
if (!isInit) {
// Return identity
hasNext = true;
next = value = identity;
return;
}
hasNext = iterator.hasNext();
if (hasNext) {
final double current = iterator.next();
next = accumulator.applyAsDouble(value, current);
value = next;
}
}
});
}

/**
* Takes elements while the predicate returns {@code true}.
*
Expand Down
64 changes: 64 additions & 0 deletions stream/src/test/java/com/annimon/stream/DoubleStreamTest.java
Expand Up @@ -125,6 +125,7 @@ public void testStreamIterateNull() {
}

@Test
@SuppressWarnings("unchecked")
public void testStreamIterateWithPredicate() {
DoublePredicate condition = new DoublePredicate() {
@Override
Expand Down Expand Up @@ -373,6 +374,69 @@ public void accept(double value) {
}).count(), is(2L));
}

@Test
@SuppressWarnings("unchecked")
public void testScan() {
DoubleStream stream;
stream = DoubleStream.of(1.1, 2.2, 3.3)
.scan(new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double left, double right) {
return left + right;
}
});
assertThat(stream, elements(array(
closeTo(1.1, 0.00001),
closeTo(3.3, 0.00001),
closeTo(6.6, 0.00001)
)));
}

@Test
public void testScanOnEmptyStream() {
DoubleStream stream;
stream = DoubleStream.empty()
.scan(new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double left, double right) {
return left + right;
}
});
assertThat(stream, isEmpty());
}

@Test
@SuppressWarnings("unchecked")
public void testScanWithIdentity() {
DoubleStream stream;
stream = DoubleStream.of(2.2, 3.3, 1.1)
.scan(1.1, new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double left, double right) {
return left + right;
}
});
assertThat(stream, elements(array(
closeTo(1.1, 0.00001),
closeTo(3.3, 0.00001),
closeTo(6.6, 0.00001),
closeTo(7.7, 0.00001)
)));
}

@Test
public void testScanWithIdentityOnEmptyStream() {
DoubleStream stream;
stream = DoubleStream.empty()
.scan(10.09, new DoubleBinaryOperator() {
@Override
public double applyAsDouble(double left, double right) {
return left + right;
}
});
assertThat(stream, elements(arrayContaining(10.09)));
}

@Test
public void testTakeWhile() {
DoubleStream stream;
Expand Down

0 comments on commit 21689c8

Please sign in to comment.