diff --git a/README.md b/README.md
index 807d997..203814c 100644
--- a/README.md
+++ b/README.md
@@ -6,34 +6,55 @@ A library of useful [Stream Gatherers](https://openjdk.org/jeps/473) (custom int
TBD, once I start publishing snapshots to Maven Central.
+# Gatherers In This Library
+
+
+| Function | Purpose |
+|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `averageBigDecimals()` | Create a running or trailing average of `BigDecimal` values. See below for options.
See [specific advice on averaging](#averaging-bigdecimal-objects) |
+| `averageBigDecimalsBy(fn)` | Create a running avergage of `BigDecimal` values mapped out of some different object via `fn`.
See [specific advice on averaging](#averaging-bigdecimal-objects) |
+| `dedupeConsecutive()` | Remove conescutive duplicates from a stream |
+| `dedupeConsecutiveBy(fn)` | Remove consecutive duplicates from a stream as returned by `fn` |
+| `distinctBy(fn)` | Emit only distinct elements from the stream, as measured by `fn` |
+| `interleave(stream)` | Creates a stream of alternating objects from the input stream and the argument stream |
+| `last(n)` | Constrain the stream to the last `n` values |
+| `withIndex()` | Maps all elements of the stream as-is, along with their 0-based index. |
+| `zipWith(stream)` | Creates a stream of `Pair` objects whose values come from the input stream and argument stream |
+| `zipWithNext()` | Creates a stream of `List` objects via a sliding window of width 2 and stepping 1 | |
+
+
# Use Cases
-(Example, TODO clean this up)
+#### Running average of `Stream`
-**Running Average**
+For more options, please see the [specific advice on averaging](#averaging-bigdecimal-objects).
```java
Stream
- .of(new BigDecimal("1.0"), new BigDecimal("2.0"), new BigDecimal("10.0"))
+ .of("1.0", "2.0", "10.0")
+ .map(BigDecimal::new)
.gather(Gatherers4j.averageBigDecimals())
.toList();
// [1, 1.5, 4.3333333333333333]
```
-**Trailing Average**
+#### Moving average of `Stream`
+
+For more options, please see the [specific advice on averaging](#averaging-bigdecimal-objects)
```java
Stream
- .of(new BigDecimal("1.0"), new BigDecimal("2.0"), new BigDecimal("10.0"), new BigDecimal("20.0"), new BigDecimal("30.0"))
- .gather(Gatherers4j.averageBigDecimals().trailing(2))
+ .of("1.0", "2.0", "10.0", "20.0", "30.0")
+ .map(BigDecimal::new)
+ .gather(Gatherers4j.averageBigDecimals().simpleMovingAverage(2))
.toList();
// [1.5, 6, 15, 25]
```
-**Removing consecutive duplicate elements:**
+#### Remove consecutive duplicate elements
```java
Stream
@@ -44,7 +65,52 @@ Stream
// ["A", "B", "C", "D", "A", "B", "C"]
```
-**Limit the stream to the `last` _n_ elements:**
+#### Remove consecutive duplicate elements, where duplicate is measured by a function
+
+```java
+record Person(String firstName, String lastName) {}
+
+Stream
+ .of(
+ new Person("Todd", "Ginsberg"),
+ new Person("Emma", "Ginsberg"),
+ new Person("Todd", "Smith")
+ )
+ .gather(Gatherers4j.dedupeConsecutiveBy(Person::firstName))
+ .toList();
+
+// [Person("Todd", "Ginsberg"), Person("Todd", "Smith")]
+```
+
+#### Remove duplicate elements, where duplicate is measured by a function
+
+```java
+record Person(String firstName, String lastName) {}
+
+Stream
+ .of(
+ new Person("Todd", "Ginsberg"),
+ new Person("Emma", "Ginsberg"),
+ new Person("Todd", "Smith")
+ )
+ .gather(Gatherers4j.distinctBy(Person::firstName))
+ .toList();
+
+// [Person("Todd", "Ginsberg"), Person("Emma", "Ginsberg")]
+```
+
+#### Interleave streams of the same type into one stream
+
+```java
+final Stream left = Stream.of("A", "B", "C");
+final Stream right = Stream.of("D", "E", "F");
+
+left.gather(Gatherers4j.interleave(right)).toList();
+
+// ["A", "D", "B", "E", "C", "F"]
+```
+
+#### Limit the stream to the `last` _n_ elements
```java
Stream
@@ -55,8 +121,104 @@ Stream
// ["E", "F", "G"]
```
+#### Include index with original stream values
+
+```java
+Stream
+ .of("A", "B", "C")
+ .gather(Gatherers4j.withIndex())
+ .toList();
+
+// [IndexedValue(0, "A"), IndexedValue(1, "B"), IndexedValue(2, "C")]
+```
+
+#### Zip two streams of together into a `Stream`
+
+The left and right streams can be of different types.
+
+```java
+final Stream left = Stream.of("A", "B", "C");
+final Stream right = Stream.of(1, 2, 3);
+
+left.gather(Gatherers4j.zip(right)).toList();
+
+// [Pair("A", 1), Pair("B", 2), Pair("C", 3)]
+
+```
+
+#### Zip elements of a stream together
+
+This converts a `Stream` to a `Stream>`
+
+```java
+Stream
+ .of("A", "B", "C", "D", "E")
+ .gather(Gatherers4j.zipWitNext())
+ .toList();
+
+// [["A", "B"], ["B", "C"], ["C", "D"], ["D", "E"]]
+```
+
+## Averaging `BigDecimal` objects
+
+Functions on `AveragingBigDecimalGatherer` which modify the output.
+
+| Function | Purpose |
+|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `simpleMovingAverage(window)` | Instead of a cumulative average, calculate a moving average over a trailing `window` |
+| `includePartialValues` | When calculating a moving average, include partially calculated values when less than `window` number of values are availabe.
The default is to only include fully calculated averages. |
+| `treatNullAsZero()` | When an element in the `Stream` is `null` treat it as `BigDecimal.ZERO` instead of skipping it in the calculation. |
+| `treatNullAs(BigDecimal)` | When an element in the `Stream` is `null` treat it as the `BigDecimal` value given instead of skipping it in the calculation. |
+| `withMathContext(MathContext)` | Switch the `MathContext` for all calculations to the non-null `MathContext` given. The default is `MathContext.DECIMAL64`. |
+| `withRoundingMode(RoundingMode)` | Switch the `RoundingMode` for all calcullations to the non-null `RoundingMode` given. The default is `RoundingMode.HALF_UP`. |
+| `withOriginal()` | Include the original value (either a `BigDecimal` or some other object type if using `averageBigDecimalsBy()`) with the calculated average. |
+
+### Example of `averageBigDecimals()`
+
+This example creates a stream of `double`, converts each value to a `BigDecmial`, and takes a `simpleMovingAverage` over 10 trailing values.
+It will `includePartialValues` and sets the `RoundingMode` and `MathContext` to the values given. Additionally, nulls
+are treated as zeros, and the calculated average is returned along with the original value.
+
+```java
+someStreamOfBigDecimal()
+ .gather(Gatherers4j
+ .averageBigDecimals()
+ .simpleMovingAverage(10)
+ .includePartialValues()
+ .withRoundingMode(RoundingMode.HALF_EVEN)
+ .withMathContext(MathContext.DECIMAL32)
+ .treatNullAsZero()
+ .withOriginal()
+ )
+ .toList();
+
+// Example output:
+[
+ WithOriginal[original=0.8462487, calculated=0.8462487],
+ WithOriginal[original=0.8923297, calculated=0.8692890],
+ WithOriginal[original=0.2556937, calculated=0.6647573],
+ WithOriginal[original=0.2901778, calculated=0.5711125],
+ WithOriginal[original=0.4945578, calculated=0.5558016],
+ WithOriginal[original=0.3173066, calculated=0.5160525],
+ WithOriginal[original=0.6377766, calculated=0.5334417],
+ WithOriginal[original=0.1729199, calculated=0.4883765],
+ WithOriginal[original=0.7408201, calculated=0.5164258],
+ WithOriginal[original=0.7169926, calculated=0.5364825],
+ WithOriginal[original=0.5174489, calculated=0.5036025],
+ WithOriginal[original=0.5895662, calculated=0.4733262],
+ WithOriginal[original=0.4458275, calculated=0.4923396],
+ // etc...
+]
+```
+
+# Project Philosophy
+
+1. Consider adding a gatherer if it cannot be implemented with `map`, `filter`, or a collector without enclosing outside state.
+2. Resist the temptation to add functions that only exist to provide an alias. They seem fun/handy but add surface area to the API and must be maintained forever.
+3. All features should be documented and tested.
+
# Contributing
-Guidance forthcoming.
+Please feel free to file issues for change requests or bugs. If you would like to contribute new functionality, please contact me before starting work!
Copyright © 2024 by Todd Ginsberg
\ No newline at end of file
diff --git a/src/main/java/com/ginsberg/gatherers4j/AveragingBigDecimalGatherer.java b/src/main/java/com/ginsberg/gatherers4j/AveragingBigDecimalGatherer.java
index b5dfc25..dadc931 100644
--- a/src/main/java/com/ginsberg/gatherers4j/AveragingBigDecimalGatherer.java
+++ b/src/main/java/com/ginsberg/gatherers4j/AveragingBigDecimalGatherer.java
@@ -33,7 +33,7 @@ public class AveragingBigDecimalGatherer
private RoundingMode roundingMode = RoundingMode.HALF_UP;
private MathContext mathContext = MathContext.DECIMAL64;
private BigDecimal nullReplacement;
- private int trailingCount = 1;
+ private int windowSize = 1;
private boolean includePartialValues;
AveragingBigDecimalGatherer(final Function mappingFunction) {
@@ -43,7 +43,7 @@ public class AveragingBigDecimalGatherer
@Override
public Supplier initializer() {
- return trailingCount == 1 ? State::new : () -> new TrailingState(trailingCount);
+ return windowSize == 1 ? State::new : () -> new TrailingState(windowSize);
}
@Override
@@ -60,40 +60,73 @@ public Integrator integrat
};
}
- public AveragingBigDecimalGatherer trailing(int count) {
- if (count <= 0) {
- throw new IllegalArgumentException("Trailing count must be positive");
+ /**
+ * Construct a moving average, with a window of size window
.
+ *
+ * @param window The size of the window to average values over, must be a positive number.
+ */
+ public AveragingBigDecimalGatherer simpleMovingAverage(int window) {
+ if (window <= 0) {
+ throw new IllegalArgumentException("Moving window size must be positive");
}
- trailingCount = count;
+ windowSize = window;
return this;
}
- public AveragingBigDecimalGatherer includePartialTailingValues() {
+ /**
+ * When creating a moving average and the full size of the window has not yet been reached, the
+ * gatherer should emit averages for what it has.
+ * For example, if the trailing average is over 10 values, but the stream has only emitted two
+ * values, the gatherer should average the two values and emit the answer. The default is to not
+ * emit anything until the full size of the window has been seen.
+ */
+ public AveragingBigDecimalGatherer includePartialValues() {
includePartialValues = true;
return this;
}
+ /**
+ * When encountering a null
value in a stream, treat it as `BigDecimal.ZERO` instead.
+ */
public AveragingBigDecimalGatherer treatNullAsZero() {
return treatNullAs(BigDecimal.ZERO);
}
+ /**
+ * When encountering a null
value in a stream, treat it as the given `rule` value instead.
+ *
+ * @param rule The value to replace null with
+ */
public AveragingBigDecimalGatherer treatNullAs(final BigDecimal rule) {
this.nullReplacement = rule;
return this;
}
+ /**
+ * Replace the MathContext
used for all mathematical operations in this class.
+ *
+ * @param mathContext A non-null MathContext
+ */
public AveragingBigDecimalGatherer withMathContext(final MathContext mathContext) {
mustNotBeNull(mathContext, "MathContext must not be null");
this.mathContext = mathContext;
return this;
}
+ /**
+ * Replace the RoundingMode
used for all mathematical operations in this class.
+ *
+ * @param roundingMode A non-null RoundingMode
+ */
public AveragingBigDecimalGatherer withRoundingMode(final RoundingMode roundingMode) {
mustNotBeNull(roundingMode, "RoundingMode must not be null");
this.roundingMode = roundingMode;
return this;
}
+ /**
+ * Include the original input value from the stream in addition to the calculated average.
+ */
public WithOriginalGatherer withOriginal() {
return new WithOriginalGatherer<>(this);
}
diff --git a/src/main/java/com/ginsberg/gatherers4j/GathererUtils.java b/src/main/java/com/ginsberg/gatherers4j/GathererUtils.java
index 4c6f349..84b04cf 100644
--- a/src/main/java/com/ginsberg/gatherers4j/GathererUtils.java
+++ b/src/main/java/com/ginsberg/gatherers4j/GathererUtils.java
@@ -17,7 +17,7 @@
public class GathererUtils {
- public static boolean safeEquals(final Object left, final Object right) {
+ static boolean safeEquals(final Object left, final Object right) {
if (left == null && right == null) {
return true;
} else if (left == null || right == null) {
@@ -26,7 +26,7 @@ public static boolean safeEquals(final Object left, final Object right) {
return left.equals(right);
}
- public static void mustNotBeNull(final Object subject, final String message) {
+ static void mustNotBeNull(final Object subject, final String message) {
if (subject == null) {
throw new IllegalArgumentException(message);
}
diff --git a/src/main/java/com/ginsberg/gatherers4j/Gatherers4j.java b/src/main/java/com/ginsberg/gatherers4j/Gatherers4j.java
index e7fe61e..ab473e2 100644
--- a/src/main/java/com/ginsberg/gatherers4j/Gatherers4j.java
+++ b/src/main/java/com/ginsberg/gatherers4j/Gatherers4j.java
@@ -18,11 +18,12 @@
import java.math.BigDecimal;
import java.util.List;
-import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Gatherer;
import java.util.stream.Stream;
+import static com.ginsberg.gatherers4j.GathererUtils.mustNotBeNull;
+
public class Gatherers4j {
/**
@@ -61,23 +62,30 @@ public static AveragingBigDecimalGatherer averageBigDecimalsBy(
}
/**
+ * Remove consecutive duplicates from a stream where duplication is measured by the given function
.
+ *
* @param function A mapping function used to compare objects in the stream for equality.
*/
public static Gatherer dedupeConsecutiveBy(final Function function) {
- Objects.requireNonNull(function, "Mapping function cannot be null");
+ mustNotBeNull(function, "Mapping function cannot be null");
return new DedupeConsecutiveGatherer<>(function);
}
/**
- * Filter a stream to only distinct elements as described by the given function.
+ * Filter a stream to only distinct elements as described by the given function
.
*
- * @param function The mapping function
+ * @param function The non-null mapping function
*/
public static Gatherer distinctBy(final Function function) {
- Objects.requireNonNull(function, "Mapping function cannot be null"); // TODO: Where should this go?
+ mustNotBeNull(function, "Mapping function cannot be null");
return new DistinctGatherer<>(function);
}
+ /**
+ * Creates a stream of alternating objects from the input stream and the argument stream
+ *
+ * @param other A non-null stream to interleave
+ */
public static Gatherer interleave(final Stream other) {
return new InterleavingGatherer<>(other);
}
@@ -91,19 +99,25 @@ public static LastGatherer last(final int count) {
return new LastGatherer<>(count);
}
- public static Gatherer> mapWithIndex(final Function mappingFunction) {
- Objects.requireNonNull(mappingFunction, "Mapping function cannot be null");
- return new IndexingGatherer<>(mappingFunction);
- }
-
+ /**
+ * Maps all elements of the stream as-is, along with their 0-based index.
+ */
public static Gatherer> withIndex() {
- return new IndexingGatherer<>(Function.identity());
+ return new IndexingGatherer<>();
}
- public static Gatherer> zip(final Stream other) {
- return new ZipGatherer<>(other);
+ /**
+ * Creates a stream of `Pair` objects whose values come from the input stream and argument stream
+ *
+ * @param other A non-null stream to zip with
+ */
+ public static Gatherer> zipWith(final Stream other) {
+ return new ZipWithGatherer<>(other);
}
+ /**
+ * Creates a stream of `List` objects via a sliding window of width 2 and stepping 1
+ */
public static Gatherer> zipWithNext() {
return new ZipWithNextGatherer<>();
}
diff --git a/src/main/java/com/ginsberg/gatherers4j/IndexingGatherer.java b/src/main/java/com/ginsberg/gatherers4j/IndexingGatherer.java
index cc0a7ac..3b80260 100644
--- a/src/main/java/com/ginsberg/gatherers4j/IndexingGatherer.java
+++ b/src/main/java/com/ginsberg/gatherers4j/IndexingGatherer.java
@@ -16,17 +16,13 @@
package com.ginsberg.gatherers4j;
-import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Gatherer;
-public class IndexingGatherer
- implements Gatherer> {
+public class IndexingGatherer
+ implements Gatherer> {
- private final Function mappingFunction;
-
- IndexingGatherer(final Function function) {
- this.mappingFunction = function;
+ IndexingGatherer() {
}
@Override
@@ -35,9 +31,9 @@ public Supplier initializer() {
}
@Override
- public Integrator> integrator() {
+ public Integrator> integrator() {
return (state, element, downstream) -> downstream
- .push(new IndexedValue<>(state.index++, mappingFunction.apply(element)));
+ .push(new IndexedValue<>(state.index++, element));
}
public static class State {
diff --git a/src/main/java/com/ginsberg/gatherers4j/ZipGatherer.java b/src/main/java/com/ginsberg/gatherers4j/ZipWithGatherer.java
similarity index 89%
rename from src/main/java/com/ginsberg/gatherers4j/ZipGatherer.java
rename to src/main/java/com/ginsberg/gatherers4j/ZipWithGatherer.java
index c842a67..f0f4daf 100644
--- a/src/main/java/com/ginsberg/gatherers4j/ZipGatherer.java
+++ b/src/main/java/com/ginsberg/gatherers4j/ZipWithGatherer.java
@@ -21,10 +21,10 @@
import java.util.stream.Gatherer;
import java.util.stream.Stream;
-public class ZipGatherer implements Gatherer> {
+public class ZipWithGatherer implements Gatherer> {
private final Spliterator otherSpliterator;
- ZipGatherer(final Stream other) {
+ ZipWithGatherer(final Stream other) {
Objects.requireNonNull(other, "Other stream must not be null");
otherSpliterator = other.spliterator();
}
diff --git a/src/test/java/com/ginsberg/gatherers4j/AveragingBigDecimalGathererTest.java b/src/test/java/com/ginsberg/gatherers4j/AveragingBigDecimalGathererTest.java
index a4b08d9..803bee6 100644
--- a/src/test/java/com/ginsberg/gatherers4j/AveragingBigDecimalGathererTest.java
+++ b/src/test/java/com/ginsberg/gatherers4j/AveragingBigDecimalGathererTest.java
@@ -185,7 +185,7 @@ void treatNullAsNonZero() {
}
@Test
- void trailingAverageOfBigDecimals() {
+ void simpleMovingAverageAverageOfBigDecimals() {
// Arrange
final Stream input = Stream.of(
new BigDecimal("1.0"),
@@ -197,7 +197,7 @@ void trailingAverageOfBigDecimals() {
// Act
final List output = input
- .gather(Gatherers4j.averageBigDecimals().trailing(2))
+ .gather(Gatherers4j.averageBigDecimals().simpleMovingAverage(2))
.toList();
// Assert
@@ -212,7 +212,7 @@ void trailingAverageOfBigDecimals() {
}
@Test
- void trailingAverageOfBigDecimalsWithPartials() {
+ void simpleMovingAverageAverageOfBigDecimalsWithPartials() {
// Arrange
final Stream input = Stream.of(
new BigDecimal("1.0"),
@@ -224,7 +224,7 @@ void trailingAverageOfBigDecimalsWithPartials() {
// Act
final List output = input
- .gather(Gatherers4j.averageBigDecimals().trailing(2).includePartialTailingValues())
+ .gather(Gatherers4j.averageBigDecimals().simpleMovingAverage(2).includePartialValues())
.toList();
// Assert
@@ -355,16 +355,16 @@ void mathContextCannotBeNull() {
}
@Test
- void trailingInvalidRangeZero() {
+ void simpleMovingAverageInvalidRangeZero() {
assertThatThrownBy(() ->
- Stream.of(BigDecimal.ONE).gather(Gatherers4j.averageBigDecimals().trailing(0))
+ Stream.of(BigDecimal.ONE).gather(Gatherers4j.averageBigDecimals().simpleMovingAverage(0))
).isExactlyInstanceOf(IllegalArgumentException.class);
}
@Test
- void trailingInvalidRangeNegative() {
+ void simpleMovingAverageInvalidRangeNegative() {
assertThatThrownBy(() ->
- Stream.of(BigDecimal.ONE).gather(Gatherers4j.averageBigDecimals().trailing(-1))
+ Stream.of(BigDecimal.ONE).gather(Gatherers4j.averageBigDecimals().simpleMovingAverage(-1))
).isExactlyInstanceOf(IllegalArgumentException.class);
}
diff --git a/src/test/java/com/ginsberg/gatherers4j/DedupeConsecutiveGatherersTest.java b/src/test/java/com/ginsberg/gatherers4j/DedupeConsecutiveGatherersTest.java
index 8a52fc8..8ff5e57 100644
--- a/src/test/java/com/ginsberg/gatherers4j/DedupeConsecutiveGatherersTest.java
+++ b/src/test/java/com/ginsberg/gatherers4j/DedupeConsecutiveGatherersTest.java
@@ -21,6 +21,7 @@
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
class DedupeConsecutiveGatherersTest {
@@ -90,4 +91,15 @@ record TestConsecutive(int left, String right) {
new TestConsecutive(6, "C")
);
}
+
+
+ @Test
+ void dedupeConsecutiveByWithNullMappingFunction() {
+ // Arrange
+ final Stream input = Stream.of("A");
+
+ // Act/Assert
+ assertThatThrownBy(() -> input.gather(Gatherers4j.dedupeConsecutiveBy(null)).toList())
+ .isExactlyInstanceOf(IllegalArgumentException.class);
+ }
}
\ No newline at end of file
diff --git a/src/test/java/com/ginsberg/gatherers4j/DistinctGathererTest.java b/src/test/java/com/ginsberg/gatherers4j/DistinctGathererTest.java
index f0b83ef..0a7736a 100644
--- a/src/test/java/com/ginsberg/gatherers4j/DistinctGathererTest.java
+++ b/src/test/java/com/ginsberg/gatherers4j/DistinctGathererTest.java
@@ -22,6 +22,7 @@
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
class DistinctGathererTest {
@@ -52,4 +53,14 @@ void distinctByWithNull() {
// Assert
assertThat(output).containsExactly(null, "a");
}
+
+ @Test
+ void distinctByWithNullMappingFunction() {
+ // Arrange
+ final Stream input = Stream.of("A");
+
+ // Act/Assert
+ assertThatThrownBy(() -> input.gather(Gatherers4j.distinctBy(null)).toList())
+ .isExactlyInstanceOf(IllegalArgumentException.class);
+ }
}
\ No newline at end of file
diff --git a/src/test/java/com/ginsberg/gatherers4j/IndexingGathererTest.java b/src/test/java/com/ginsberg/gatherers4j/IndexingGathererTest.java
index 4f65649..fd87920 100644
--- a/src/test/java/com/ginsberg/gatherers4j/IndexingGathererTest.java
+++ b/src/test/java/com/ginsberg/gatherers4j/IndexingGathererTest.java
@@ -16,7 +16,6 @@
package com.ginsberg.gatherers4j;
-import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.util.List;
@@ -26,105 +25,42 @@
class IndexingGathererTest {
- @Nested
- class MapWithIndex {
- @Test
- void mapObjectWithIndex() {
- // Arrange
- final Stream input = Stream.of("A", "B", "C");
-
- // Act
- final List> output = input
- .gather(Gatherers4j.mapWithIndex(String::toLowerCase))
- .toList();
-
- // Assert
- assertThat(output)
- .containsExactly(
- new IndexedValue<>(0, "a"),
- new IndexedValue<>(1, "b"),
- new IndexedValue<>(2, "c")
- );
- }
-
- @Test
- void mapIntegerWithIndex() {
- // Arrange
- final Stream input = Stream.of(1, 2, 3);
-
- // Act
- final List> output = input
- .gather(Gatherers4j.mapWithIndex(it -> it * it))
- .toList();
-
- // Assert
- assertThat(output)
- .containsExactly(
- new IndexedValue<>(0, 1),
- new IndexedValue<>(1, 4),
- new IndexedValue<>(2, 9)
- );
- }
-
- @Test
- void mapIntegerToStringWithIndex() {
- // Arrange
- final Stream input = Stream.of(1, 2, 3);
-
- // Act
- final List> output = input
- .gather(Gatherers4j.mapWithIndex(it -> String.valueOf(it * it)))
- .toList();
-
- // Assert
- assertThat(output)
- .containsExactly(
- new IndexedValue<>(0, "1"),
- new IndexedValue<>(1, "4"),
- new IndexedValue<>(2, "9")
- );
- }
+ @Test
+ void objectWithIndex() {
+ // Arrange
+ final Stream input = Stream.of("A", "B", "C");
+
+ // Act
+ final List> output = input
+ .gather(Gatherers4j.withIndex())
+ .toList();
+
+ // Assert
+ assertThat(output)
+ .containsExactly(
+ new IndexedValue<>(0, "A"),
+ new IndexedValue<>(1, "B"),
+ new IndexedValue<>(2, "C")
+ );
}
- @Nested
- class WithIndex {
- @Test
- void objectWithIndex() {
- // Arrange
- final Stream input = Stream.of("A", "B", "C");
-
- // Act
- final List> output = input
- .gather(Gatherers4j.withIndex())
- .toList();
-
- // Assert
- assertThat(output)
- .containsExactly(
- new IndexedValue<>(0, "A"),
- new IndexedValue<>(1, "B"),
- new IndexedValue<>(2, "C")
- );
- }
-
- @Test
- void integerWithIndex() {
- // Arrange
- final Stream input = Stream.of(1, 2, 3);
-
- // Act
- final List> output = input
- .gather(Gatherers4j.withIndex())
- .toList();
-
- // Assert
- assertThat(output)
- .containsExactly(
- new IndexedValue<>(0, 1),
- new IndexedValue<>(1, 2),
- new IndexedValue<>(2, 3)
- );
- }
+ @Test
+ void integerWithIndex() {
+ // Arrange
+ final Stream input = Stream.of(1, 2, 3);
+
+ // Act
+ final List> output = input
+ .gather(Gatherers4j.withIndex())
+ .toList();
+
+ // Assert
+ assertThat(output)
+ .containsExactly(
+ new IndexedValue<>(0, 1),
+ new IndexedValue<>(1, 2),
+ new IndexedValue<>(2, 3)
+ );
}
}
\ No newline at end of file
diff --git a/src/test/java/com/ginsberg/gatherers4j/ZipGathererTest.java b/src/test/java/com/ginsberg/gatherers4j/ZipWithGathererTest.java
similarity index 91%
rename from src/test/java/com/ginsberg/gatherers4j/ZipGathererTest.java
rename to src/test/java/com/ginsberg/gatherers4j/ZipWithGathererTest.java
index 325612f..5eef0ed 100644
--- a/src/test/java/com/ginsberg/gatherers4j/ZipGathererTest.java
+++ b/src/test/java/com/ginsberg/gatherers4j/ZipWithGathererTest.java
@@ -23,7 +23,7 @@
import static org.assertj.core.api.Assertions.assertThat;
-class ZipGathererTest {
+class ZipWithGathererTest {
@Test
void zipGatherer() {
@@ -33,7 +33,7 @@ void zipGatherer() {
// Act
final List> output = left
- .gather(Gatherers4j.zip(right))
+ .gather(Gatherers4j.zipWith(right))
.toList();
// Assert
@@ -53,7 +53,7 @@ void zipGathererOtherEmpty() {
// Act
final List> output = left
- .gather(Gatherers4j.zip(right))
+ .gather(Gatherers4j.zipWith(right))
.toList();
// Assert
@@ -68,7 +68,7 @@ void interleavingGathererThisEmpty() {
// Act
final List> output = left
- .gather(Gatherers4j.zip(right))
+ .gather(Gatherers4j.zipWith(right))
.toList();
// Assert