{"id":23641247,"url":"https://github.com/tginsberg/gatherers4j","last_synced_at":"2026-01-04T20:14:59.268Z","repository":{"id":239244112,"uuid":"798438427","full_name":"tginsberg/gatherers4j","owner":"tginsberg","description":"A library of useful Stream Gatherers (custom intermediate operations) for Java. ","archived":false,"fork":false,"pushed_at":"2025-04-02T23:22:27.000Z","size":422,"stargazers_count":81,"open_issues_count":2,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-10T01:13:15.508Z","etag":null,"topics":["gatherer","gatherers","java","java-24","java24"],"latest_commit_sha":null,"homepage":"https://tginsberg.github.io/gatherers4j/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tginsberg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-09T19:22:52.000Z","updated_at":"2025-04-09T22:20:26.000Z","dependencies_parsed_at":"2024-10-26T23:35:23.693Z","dependency_job_id":"1f31b8bf-b25d-4419-b297-f6ab8d030f8d","html_url":"https://github.com/tginsberg/gatherers4j","commit_stats":null,"previous_names":["tginsberg/gatherers4j"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tginsberg%2Fgatherers4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tginsberg%2Fgatherers4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tginsberg%2Fgatherers4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tginsberg%2Fgatherers4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tginsberg","download_url":"https://codeload.github.com/tginsberg/gatherers4j/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137891,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gatherer","gatherers","java","java-24","java24"],"created_at":"2024-12-28T09:58:56.329Z","updated_at":"2026-01-04T20:14:59.262Z","avatar_url":"https://github.com/tginsberg.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gatherers4j\n\nA library of useful [Stream Gatherers](https://openjdk.org/jeps/485) (custom intermediate operations) for Java 25+.\n\nSee [the full set of documentation](https://tginsberg.github.io/gatherers4j/) for information on how to use Gatherers4j.\n\n# Installing\n\nTo use this library, add it as a dependency to your build. This library has one transitive\ndependency - the [JSpecify](https://jspecify.dev/) set of annotations for static analysis tools.\n\n**Maven**\n\nAdd the following dependency to `pom.xml`.\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.ginsberg\u003c/groupId\u003e\n    \u003cartifactId\u003egatherers4j\u003c/artifactId\u003e\n    \u003cversion\u003e0.13.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n**Gradle**\n\nAdd the following dependency to `build.gradle` or `build.gradle.kts`\n\n```groovy\nimplementation(\"com.ginsberg:gatherers4j:0.13.0\")\n```\n\n\n# Gatherers In This Library\n\nFor convenience, the full list of gatherers in this library are broken into five categories:\n\n1. [Sequence Operations](#sequence-operations)\n2. [Filtering and Selection](#filtering-and-selection)\n3. [Grouping and Windowing](#grouping-and-windowing)\n4. [Validation and Constraints](#validation-and-constraints)\n5. [Mathematical Operations](#mathematical-operations)\n\n## Sequence Operations\n\nGatherers that reorder, combine, or manipulate the sequence of elements.\n\n| Function                                                                                                        | Purpose                                                                                                                                             |\n|-----------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|\n| [`crossWith()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/crosswith/)               | Emit each element of the source stream with each element of the given `iterable`, `iterator`, `stream`, or varargs as a `Pair` to the output stream |\n| [`foldIndexed(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/foldindexed/)         | Perform a fold over the input stream where each element is included along with its zero-based index                                                 |\n| [`interleaveWith()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/interleavewith/)     | Creates a stream of alternating objects from the input stream and the argument `iterable`, `iterator`, `stream`, or varargs                         |\n| [`mapIndexed()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/mapindexed/)             | Perform a mapping operation given the element being mapped and its zero-based index.                                                                |\n| [`orderByFrequency()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/orderbyfrequency/) | Returns a stream where elements are ordered in either ascending or descending frequency contained in `WithCount\u003cT\u003e` wrapper objects.                |\n| [`orderByFrequencyBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/orderbyfrequencyby/) | Returns a stream of mapped values ordered by frequency (ascending or descending) contained in `WithCount\u003cMAPPED\u003e` wrapper objects.                |\n| [`peekIndexed()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/peekindexed/)           | Peek at each element of the stream along with its zero-based index                                                                                  |\n| [`repeat(n)`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/repeat/)                    | Repeat the input stream `n` times to the output stream                                                                                              |\n| [`repeatInfinitely()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/repeatinfinitely/) | Repeat the input stream to the output stream forever (or until some downstream operation stops it)                                                  |\n| [`reverse()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/reverse/)                   | Reverse the order of the stream                                                                                                                     |\n| [`rotate(direction, n)`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/rotate/)         | Rotate the stream `n` elements to direction specified. Stores entire stream into memory.                                                            |\n| [`scanIndexed(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/scanindexed/)         | Performs a scan on the input stream using the given function, and includes the index of the elements                                                |\n| [`shuffle()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/shuffle/)                   | Shuffle the stream into a random order, optionally taking a `RandomGenerator`                                                                       |\n| [`throttle(amount, duration)`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/throttle/) | Limit stream elements to `amount` elements over `duration`, pausing until a new `duration` period starts                                            |\n| [`withIndex()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/withindex/)               | Maps all elements of the stream as-is along with their 0-based index                                                                                |\n| [`zipWith()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/zipwith/)                   | Creates a stream of `Pair` objects whose values come from the input stream and argument `iterable`, `iterator`, `stream`, or varargs                |\n| [`zipWithNext()`](https://tginsberg.github.io/gatherers4j/gatherers/sequence-operations/zipwithnext/)           | Creates a stream of `List` objects via a sliding window of width 2 and stepping 1                                                                   |      \n\n## Filtering and Selection\n\nGatherers that select or remove elements based on some criteria.\n\n| Function                                                                                                                           | Purpose                                                                                                                        |\n|------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|\n| [`debounce(amount, duration)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/debounce/)                | Limit stream elements to `amount` elements over `duration`, dropping any elements over the limit until a new `duration` starts |\n| [`dedupeConsecutive()`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/dedupeconsecutive/)              | Remove consecutive duplicates from a stream                                                                                    |\n| [`dedupeConsecutiveBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/dedupeconsecutiveby/)        | Remove consecutive duplicates from a stream as returned by `fn`                                                                |\n| [`distinctBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/distinctby/)                          | Emit only distinct elements from the stream, as measured by `fn`                                                               |\n| [`dropEveryNth(n)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/dropeverynth/)                       | Drop every`n`\u003csup\u003eth\u003c/sup\u003e element from the input stream                                                                       |\n| [`dropLast(n)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/droplast/)                               | Keep all but the last `n` elements of the stream                                                                               |\n| [`filterIndexed()`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/filterindexed/)                      | Filter a stream according to a given predicate, which takes both the item being examined and its zero-based index.             |\n| [`filterInstanceOf`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/filterinstanceof/)                  | Filter the elements in the stream to only include elements of the given types.                                                 |\n| [`filterOrdered(order)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/filterordered/)                 | Filter the input stream of `Comparable` objects so that is strictly in the given `order`                                       |                                                                                           |\n| [`filterOrderedBy(order, comparator)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/filterorderedby/) | Filter the input stream of objects so that it contains only elements in the given `order`, as measured by a given `Comparator` |\n| [`sampleFixedSize(n)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/samplefixedsize/)                 | Perform a fixed size sampling over the input stream.                                                                           |\n| [`samplePercentage(d)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/samplepercentage/)               | Perform a percentage-based sampling over the input stream.                                                                     |                                                                                                                               | \n| [`takeEveryNth(n)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/takeeverynth/)                       | Keep every`n`\u003csup\u003eth\u003c/sup\u003e element from the input stream                                                                       |\n| [`takeLast(n)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/takelast/)                               | Emit the last `n` values                                                                                                       |\n| [`takeUntil(predicate)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/takeuntil/)                     | Take elements from the input stream until the `predicate` is met, including the first element that matches the `preciate`      |\n| [`uniquelyOccurring()`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/uniquelyoccurring/)              | Emit elements that occur a single time, dropping all others                                                                    |\n| [`uniquelyOccurringBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/filtering-and-selection/uniquelyoccurringby/)        | Emit elements that occur a single time, as measured by `fn`, dropping all others                                                |\n\n## Grouping and Windowing\n\nFunctions that group input elements by varying criteria.\n\n| Function                                                                                                                        | Purpose                                                                                                                                                                                             |\n|---------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [`group()`](https://tginsberg.github.io/gatherers4j/gatherers/grouping-and-windowing/group/)                                    | Group adjacent equal elements into lists                                                                                                                                                            |\n| [`groupBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/grouping-and-windowing/groupby/)                              | Group adjacent elements that are equal according to `fn` into lists                                                                                                                                 | \n| [`groupOrdered(order)`](https://tginsberg.github.io/gatherers4j/gatherers/grouping-and-windowing/groupordered/)                 | Group `Comparable` elements in the input stream to lists in the given order                                                                                                                         |\n| [`groupOrderedBy(order, comparator)`](https://tginsberg.github.io/gatherers4j/gatherers/grouping-and-windowing/grouporderedby/) | Group elements in the given `order` as measured by a `Comparator` to lists                                                                                                                          |\n| [`window()`](https://tginsberg.github.io/gatherers4j/gatherers/grouping-and-windowing/window/)                                  | Create windows over the elements of the input stream that are `windowSize` in length, sliding over `stepping` number of elements and optionally including partial windows at the end of ths stream. |\n\n## Validation and Constraints\n\nFunctions that enforce conditions on the stream.\n\n| Function                                                                                                                      | Purpose                                                                                                                                                                                            |\n|-------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [`ensureOrdered(orderType)`](https://tginsberg.github.io/gatherers4j/gatherers/validation-and-constraints/ensureordered/)     | Ensure that the input stream of `Comparable` objects is ordered according to the `orderType` (increasing, decreasing, non-increasing, non-decreasing), and fail otherwise.                         |                                                                                           |\n| [`ensureOrderedBy(orderType)`](https://tginsberg.github.io/gatherers4j/gatherers/validation-and-constraints/ensureorderedby/) | Ensure that the input stream of objects is ordered according to the `orderType` (increasing, decreasing, non-increasing, non-decreasing), as measured by a given `Comparator`, and fail otherwise. |\n| [`ensureSize(sizeType, n)`](https://tginsberg.github.io/gatherers4j/gatherers/validation-and-constraints/ensuresize/)         | Ensure the stream is `n` elements long with reference to `sizeType` (equals, less/greater than, less/greater than or equal to), and fail otherwise.                                                |\n\n## Mathematical Operations\n\nFunctions performing calculations over the stream.\n\n| Function                                                                                                                                                    | Purpose                                                                                                                                                          |\n|-------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [`exponentialMovingAverageWithAlpha(alpha)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/exponentialmovingaveragewithalpha/)             | Create an exponential average of `BigDecimal` values, with the given `alpha`.                                                                                    |\n| [`exponentialMovingAverageWithAlphaBy(alpha, fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/exponentialmovingaveragewithalphaby/)     | Create an exponential average of `BigDecimal` values with the given `alpha`, as mapped via `fn`.                                                                 |\n| [`exponentialMovingAverageWithPeriod(periods)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/exponentialmovingaveragewithperiod/)         | Create an exponential average of `BigDecimal` values, with the given number of `periods`.                                                                        |\n| [`exponentialMovingAverageWithPeriodBy(periods, fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/exponentialmovingaveragewithperiodby/) | Create an exponential average of `BigDecimal` values with the given number of `periods`, as mapped via `fn`.                                                     |\n| [`movingMax(window)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingmax/)                                                            | Create a `Stream\u003cT\u003e` representing the moving maximum over the previous `window` elements, where `T` implements `Comparable\u003cT\u003e`.                                  |\n| [`movingMaxBy(window, comparator)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingmaxby/)                                            | Create a `Stream\u003cT\u003e` representing the moving maximum over the previous `window` elements, according to the given `Comparator`.                                  |\n| [`movingMedian(window)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingmedian/)                                                      | Create a Stream that represents the moving median of a `Stream\u003cBigDecimal\u003e` looking back `window` number of elements.                                            |\n| [`movingMedianBy(window, fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingmedianby/)                                              | Create a Stream that represents the moving median of `BigDecimal` objects mapped from a `Stream\u003cINPUT\u003e` via a `fn` and looking back `window` number of elements. |\n| [`movingMin(window)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingmin/)                                                            | Create a `Stream\u003cT\u003e` representing the moving minimum over the previous `window` elements, where `T` implements `Comparable\u003cT\u003e`.                                  |\n| [`movingMinBy(window, comparator)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingminby/)                                            | Create a `Stream\u003cT\u003e` representing the moving minimum over the previous `window` elements, according to the given `Comparator`.                                  |\n| [`movingProduct(window)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingproduct/)                                                    | Create a moving product of `BigDecimal` objects over the previous `window` values.                                                                               |\n| [`movingProductBy(window, fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingproductby/)                                            | Create a moving product of `BigDecimal` objects over the previous `window` values, as mapped via `fn`.                                                           |\n| [`movingSum(window)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingsum/)                                                            | Create a moving sum of `BigDecimal` objects over the previous `window` values.                                                                                   |\n| [`movingSumBy(window, fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/movingsumby/)                                                    | Create a moving sum of `BigDecimal` objects over the previous `window` values, as mapped via `fn`.                                                               |\n| [`runningMax()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningmax/)                                                                | Create a `Stream\u003cT\u003e` representing the running maximum of the input stream, where `T` implements `Comparable\u003cT\u003e`.                                                 |\n| [`runningMaxBy(comparator)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningmaxby/)                                                  | Create a `Stream\u003cT\u003e` representing the running maximum of the input stream, according to the given `Comparator`.                                                  |\n| [`runningMedian()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningmedian/)                                                          | Create a `Stream\u003cBigDecimal\u003e` that represents the running median of a `Stream\u003cBigDecimal\u003e`.                                                                      |\n| [`runningMedianBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningmedianby/)                                                    | Create a `Stream\u003cBigDecimal\u003e` that represents the running median of `BigDecimal` objects mapped from a `Stream\u003cINPUT\u003e` via a `fn`.                               |\n| [`runningMin()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningmin/)                                                                | Create a `Stream\u003cT\u003e` representing the running minimum of the input stream, where `T` implements `Comparable\u003cT\u003e`.                                                 |\n| [`runningMinBy(comparator)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningminby/)                                                  | Create a `Stream\u003cT\u003e` representing the running minimum of the input stream, according to the given `Comparator`.                                                  |\n| [`runningPopulationStandardDeviation()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningpopulationstandarddeviation/)                | Create a stream of `BigDecimal` objects representing the running population standard deviation.                                                                  |\n| [`runningPopulationStandardDeviationBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningpopulationstandarddeviationby/)          | Create a stream of `BigDecimal` objects as mapped from the input via `fn`, representing the running population standard deviation.                               |\n| [`runningProduct()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningproduct/)                                                        | Create a stream of `BigDecimal` objects representing the running product.                                                                                        |                                                          |\n| [`runningProductBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningproductby/)                                                  | Create a stream of `BigDecimal` objects as mapped from the input via `fn`, representing the running product.                                                     |\n| [`runningSampleStandardDeviation()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningsamplestandarddeviation/)                        | Create a stream of `BigDecimal` objects representing the running sample standard deviation.                                                                      |\n| [`runningSampleStandardDeviationBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningsamplestandarddeviationby/)                  | Create a stream of `BigDecimal` objects as mapped from the input via `fn`, representing the running sample standard deviation.                                   |\n| [`runningSum()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningsum/)                                                                | Create a stream of `BigDecimal` objects representing the running sum.                                                                                            |\n| [`runningSumBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/runningsumby/)                                                          | Create a stream of `BigDecimal` objects as mapped from the input via `fn`, representing the running sum.                                                         |\n| [`simpleMovingAverage(window)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/simplemovingaverage/)                                        | Create a moving average of `BigDecimal` values over the previous `window` values.                                                                                |\n| [`simpleMovingAverageBy(window, fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/simplemovingaverageby/)                                | Create a moving average of `BigDecimal` values over the previous `window` values, as mapped via `fn`.                                                            |\n| [`simpleRunningAverage()`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/simplerunningaverage/)                                            | Create a running average of `BigDecimal` values. See below for options.                                                                                          |\n| [`simpleRunningAverageBy(fn)`](https://tginsberg.github.io/gatherers4j/gatherers/mathematical/simplerunningaverageby/)                                      | Create a running average of `BigDecimal` values as mapped via `fn`.                                                                                              |\n\n# Contributing\n\nPlease feel free to file issues for change requests or bugs. If you would like to contribute new functionality, please\ncontact me before starting work!\n\nCopyright © 2024-2025 by Todd Ginsberg","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftginsberg%2Fgatherers4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftginsberg%2Fgatherers4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftginsberg%2Fgatherers4j/lists"}