Skip to content

Releases: tginsberg/gatherers4j

Release v0.15.0

Choose a tag to compare

@tginsberg tginsberg released this 11 Oct 23:10
9101e4c

New Gatherers

  • movingHarmonicMean(), movingHarmonicMeanBy(), runningHarmonicMean(), and runningHarmonicMeanBy()
  • movingRootMeanSquare(), movingRootMeanSquareBy(), runningRootMeanSquare(), and runningRootMeanSquareBy()
  • movingVariance(), movingVarianceBy(), runningVariance(), and runningVarianceBy()
  • movingStandardDeviation() and movingStandardDeviationBy()
  • movingStatistics(), movingStatisticsBy(), runningStatistics(), and runningStatisticsBy(), which emit a StatisticalSummary record (count, sum, mean, min, max, and population and sample variance and standard deviation) for each element
  • movingPercentile(), movingPercentileBy(), runningPercentile(), and runningPercentileBy()
  • movingWeightedMean() and movingWeightedMeanBy(), the weighted moving average, with linear weights or your own weights ordered oldest to newest

Behavior Changes

  • The BigDecimal gatherers now round each input to the MathContext as it arrives, then accumulate sums, means, and standard deviations exactly instead of rounding at every step. Results can differ from 0.14.0 in the final digits.
  • exponentialMovingAverageWithAlpha(), exponentialMovingAverageWithPeriod(), and their By variants now round at every step. Previously they never rounded, so long streams gained digits with every element and slowed down.
  • Sample standard deviation now emits nothing for the first element, where runningSampleStandardDeviation() emitted 0.
  • samplePercentage() and exponentialMovingAverageWithAlpha() (and its By variant) now reject NaN.
  • withMathContext() now rejects a MathContext with a precision of 0, such as MathContext.UNLIMITED.

API Changes

  • Breaking: rename simpleMovingAverage(), simpleMovingAverageBy(), simpleRunningAverage(), and simpleRunningAverageBy() to movingMean(), movingMeanBy(), runningMean(), and runningMeanBy().
  • Breaking: replace runningPopulationStandardDeviation(), runningSampleStandardDeviation(), and their By variants with runningStandardDeviation(Dataset) and runningStandardDeviationBy(Dataset, Function).
  • Breaking: the BigDecimal gatherers now return BigDecimalMovingStatGatherer or BigDecimalRunningStatGatherer. The public classes they used to return (BigDecimalGatherer, BigDecimalSumGatherer, BigDecimalMedianGatherer, and the others listed in the changelog) are removed. Code that only calls Gatherers4j factory methods is unaffected.
  • Breaking: remove the public SamplePercentageGatherers.poisson(). Use Gatherers4j.samplePercentage().
  • treatNullAsOne() and withMathContext() are now available on all of the BigDecimal gatherers.
  • Add sampleFixedSize(int, RandomGenerator) and samplePercentage(double, RandomGenerator) to choose the source of randomness.
  • Add the Dataset enum (Population, Sample) and the StatisticalSummary record.

Other Changes

  • Fix sampleFixedSize() not sampling with equal probability: the first sampleSize elements were chosen too rarely and later elements too often.
  • Fix moving product and geometric mean accumulating rounding error over long streams.
  • Fix geometric mean throwing or returning wrong results when the product of the values is beyond the range of a double.
  • Fix movingMin() and movingMax() slowing down with large windows on rising or falling input, and evicting the wrong values after about 2.1 billion elements.
  • Upgrade JSpecify from 1.0.0 to 1.0.1.
  • Document intersperse(), which had been missing from the docs since 0.8.0.

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.15.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.15.0")

Release v0.14.0

Choose a tag to compare

@tginsberg tginsberg released this 17 May 13:12
6c39a8f

New Gatherers

  • Implement movingGeometricMean(), movingGeometricMeanBy(), runningGeometricMean(), and runningGeometricMeanBy().
  • Implement filterNotNull(), which filters out null values from the input stream and is useful for lining up JSpecify annotations (from nullable to non-nullable).

Bug Fixes

  • Fix bug in movingProduct() and movingProductBy() where zero values were incorrectly handled. Addresses #184.

Behavior Changes

  • Change CrossGatherer, TypeFilteringGatherer, and FlattenSingleOrFail to use Greedy integrators.

Other Changes

  • Thank you to @Riggs333 for contributing code cleanups, making comparisons in FrequencyGatherer easier to understand!
  • Thank you to @Riggs333 for contributing changes to tests to use AssertJ's type-specific exception assertions, which clarifies the intent of the code!

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.14.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.14.0")

Release v0.13.0

Choose a tag to compare

@tginsberg tginsberg released this 04 Jan 18:35
58532b9

New Gatherers

  • Implement uniquelyOccurringBy() to limit the stream to uniquely occurring elements as measured by the given function
  • Implement movingMedian() and movingMedianBy()
  • Implement runningMedian() and runningMedianBy()
  • Implement movingMax(), movingMaxBy(), movingMin(), and movingMinBy()
  • Implement runningMax(), runningMaxBy(), runningMin(), and runningMinBy()

Behavior Changes

  • All “moving” gatherers will now include all calculated values by default, even when the full lookback window has not been reached.
    • To turn this behavior off, use excludePartialValues().
    • Previously, partial results were suppressed and turned on via includePartialValues().
    • This affects movingMax(), movingMaxBy(), movingMin(), movingMinBy(), movingMedian(), movingMedianBy(), movingProduct(), movingProductBy(), movingSum(), movingSumBy(), simpleMovingAverage(), and simpleMovingAverageBy()

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.13.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.13.0")

Release v0.12.0

Choose a tag to compare

@tginsberg tginsberg released this 27 Sep 16:51
04cbdd1

Changes

  • Move Java version to 25 (was 24) Addresses #164
  • Support Java Modularization. Addresses #156, thanks @Goldmensch!
  • Support parallelization in UniquelyOccurringGatherer

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.12.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.12.0")

Release v0.11.0

Choose a tag to compare

@tginsberg tginsberg released this 05 May 23:36
efe8e20

New Implementations

  • Implement exponential moving averages with exponentialMovingAverageWithAlpha(), exponentialMovingAverageWithAlphaBy(),exponentialMovingAverageWithPeriod(), and exponentialMovingAverageWithPeriodBy().

Changes and Consistency Fixes

  • Fix and document behavior of window() when there are multiple partial groupings at the end. Addresses #135, thanks @paulk-asert!
  • Change index to be an int rather than a long in filterIndexed(), foldIndexed(), mapIndexed(), peekIndexed(), scanIndexed() and withIndex(). Addresses #140.
  • Optimize rotate(Left) to store a minimal set of elements instead of the entire stream. Addresses #141, thanks @paulk-asert!
  • Enable Gradle wrapper validation. Addressed in #114, thanks @sullis

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.11.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.11.0")

Release v0.10.0

Choose a tag to compare

@tginsberg tginsberg released this 19 Mar 23:03
1c3d291

Java 24 Support!

  • Upgrade to Java 24
    • This uses Corretto JDK for 24 in GitHub Actions until Temurin is out
    • Remove mentions of Java 23
    • Use JaCoCo Snapshot until full release
    • Upgrade Gradle to 8.13

New Implementations

  • Implement mapIndexed() (#102)
  • Implement peekIndexed() (#108)
  • Implement fixed and percentage sampling (#109)
    • Adding commons-statistics-inference to test scope to validate results are statistically accurate

Changes and Consistency Fixes

  • Use merge instead of compute in FrequencyGatherer
  • Documentation fix in changelog for mapIndexed()
  • Gatherers4j methods should return Gatherer interface when the implementation has no user-callable methods
  • Consistency fix: Rename IndexedValue to WithIndex (#105)
  • Reorganize packages (#106)
    • Reorg: Move utils to subpackage
    • Reorg: Move dtos to subpackage
    • Reorg: Move test utils
  • Ensure bulk pushes to downstream listen for short-circuit signals (#110)

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.10.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.10.0")

Release v0.9.0

Choose a tag to compare

@tginsberg tginsberg released this 23 Feb 16:42
1445e6b

Documentation!

The biggest delivery in this release is the start of the Gatherers4j Documentation Website!

New Implementations

  • filterInstanceOf() to filter a stream by type more easily. Addresses #86, thanks @nipafx.
  • groupOrdered(), and groupOrderedBy() to appropriately group elements in the input stream to lists in the output stream. Addresses #88, thanks @nipafx.
  • ensureOrdred() and ensureOrderedBy() to ensure the given stream meets an ordering criteria, or fail exceptionally otherwise
  • filterOrdered() and filterOrderedBy() to remove non-ordered elements from the input stream
  • window() to provide more options to windowing functions, namely - ability to specify size, how many to skip each time, and whether to include partial windows
  • repeat(n) and repeatInfinitely() to repeatedly emit the input stream to the output stream
  • rotate(n) rotate the stream either left or right (consumes entire stream)

Renaming for Consistency

Since Gatherers are still in preview in Java 23, now is the time to rename things mostly consequence-free!

  • everyNth(n) to takeEveryNth(n) and added dropEveryNth(n) for completeness
  • filterWithIndex() to filterIndexed() to match other indexing Gatherers
  • cross() to crossWith() for consistency
  • interleave() to interleaveWith() for consistency
  • grouping() to group() and groupingBy() to groupBy() for consistency
  • last() to takeLast() to match dropLast()

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.9.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.9.0")

Release v0.8.0

Choose a tag to compare

@tginsberg tginsberg released this 01 Feb 21:06

What's Changed

  • Add support for orElse() and orElseEmpty() on size-based gatherers to provide a non-exceptional output stream
  • Implement everyNth() to get every nth element from the stream
  • Implement uniquelyOccurring() to emit stream elements that occur a single time
  • Implement takeUntil() to take from a stream until a predicate is met, including the first element that matches the predicate
  • Implement foldIndexed() to perform a fold along with the index of each element
  • Implement scanIndexed() to perform a scan along with the index of each element
  • Implement intersperse() to put the given element between each element of the stream
  • Implement cross(iterable), cross(iterator), and cross(stream) to combine elements in the input stream with the given source of elements

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.8.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.8.0")

Release v0.7.0

Choose a tag to compare

@tginsberg tginsberg released this 06 Jan 22:43
f08e0eb

What's Changed

  • Use greedy integrators where possible (Fixes #57)
  • Add JSpecify annotations for static analysis
  • Implement orderByFrequencyAscending() and orderByFrequencyDescending()
  • Implement movingProduct() and movingProductBy()
  • Implement movingSum() and movingSumBy()
  • Remove maxBy(fn) and minBy(fn), can be done with JDK methods trivially
  • Rename exactSize() to sizeExactly()
  • Implement sizeLessThan(), sizeLessThanOrEqualTo(), sizeGreaterThan(), and sizeGreaterThanOrEqualTo()
  • API Style - Functions, when used as arguments, should come last for consistency and to play nice with Kotlin (Fixes #64)

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.7.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.7.0")

Release v0.6.0

Choose a tag to compare

@tginsberg tginsberg released this 02 Nov 12:24

What's Changed

  • Implement dropLast(n)
  • Implement grouping() and groupingBy(fn)
  • Add support for zipWith(iterable) and zipWith(iterator)
  • Add support for interleave(iterable) and interleave(iterator)
  • Add support for appendLonger(), appendArgumentIfLonger(), and appendSourceIfLonger() on interleave()
  • Add support for argumentWhenSourceLonger(fn), sourceWhenArgumentLonger(fn), nullArgumentWhenSourceLonger(), and nullSourceWhenArgumentLonger on zipWith()

Using in Maven

<dependency>
    <groupId>com.ginsberg</groupId>
    <artifactId>gatherers4j</artifactId>
    <version>0.6.0</version>
</dependency>

Using in Gradle

implementation("com.ginsberg:gatherers4j:0.6.0")