Gatherers library for Java Stream API
APACHE-2.0 License
Packrat is a Java library that provides various Gatherer implementations for the Stream API. Gatherers can enhance streams with custom intermediate operations.
Introduction to the Gatherers by Viktor Klang
[!IMPORTANT] You will need a very fresh JDK version with preview features enabled to actually use Gatherers.
JEP | JDK | Status |
---|---|---|
461 | 22 | Preview |
473 | 23 | Second Preview |
485 | 24 | Final |
Name | Description |
---|---|
distinctBy | Distinct values with custom mapper |
filterBy | Filter with custom mapper and (optionally) predicate |
removeBy | Remove with custom mapper and (optionally) predicate |
increasing | Increasing sequence, other elements dropped |
increasingOrEqual | Increasing (or equal) sequence, other elements dropped |
decreasing | Decreasing sequence, other elements dropped |
decreasingOrEqual | Decreasing (or equal) sequence, other elements dropped |
increasingChunks | Lists of increasing values |
increasingOrEqualChunks | Lists of increasing or equal values |
decreasingChunks | Lists of decreasing values |
decreasingOrEqualChunks | Lists of decreasing or equal values |
reverse | All elements in reverse order |
rotate | All elements rotated left or right |
shuffle | All elements in random order |
chars | String splitted by Unicode graphemes |
words | String splitted by words |
sentences | String splitted by sentences |
nCopies | Copies every element n times |
atLeast | Distinct values that appear at least n times |
mapFirst | Maps first element with mapper, other unchanged |
mapN | Maps n elements, other unchanged |
skipAndMap | Skips n elements, maps others |
skipAndMapN | Skips skipN elements, maps mapN others |
flatMapIf | Optional flatMap depending on predicate |
zip | Zips values with zipper, leftovers dropped |
asGatherer | Converts Collector into Gatherer
|
distinctBy(mapper)
- returns elements with distinct values that result from a mapping by the supplied function
import static jhspetersson.packrat.Packrat.distinctBy;
var oneOddOneEven = IntStream.range(1, 10).boxed().gather(distinctBy(i -> i % 2)).toList();
System.out.println(oneOddOneEven);
[1, 2]
filterBy(mapper, value)
- filters mapped elements based on the equality to the value, stream continues with original elements
import static jhspetersson.packrat.Packrat.filterBy;
var oneDigitNumbers = IntStream.range(0, 100).boxed().gather(filterBy(i -> i.toString().length(), 1)).toList();
System.out.println(oneDigitNumbers);
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
filterBy(mapper, value, predicate)
- filters mapped elements based on the predicate test against the value, stream continues with original elements
import static jhspetersson.packrat.Packrat.filterBy;
var ffValue = IntStream.range(0, 1000).boxed().gather(filterBy(Integer::toHexString, "ff", String::equalsIgnoreCase)).toList();
System.out.println(ffValue);
[255]
removeBy(mapper, value)
- removes mapped elements based on the equality to the value, stream continues with original elements
import static jhspetersson.packrat.Packrat.removeBy;
var oneDigitNumbers = IntStream.range(0, 100).boxed().gather(removeBy(i -> i.toString().length(), 2)).toList();
System.out.println(oneDigitNumbers);
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
removeBy(mapper, value, predicate)
- removes mapped elements based on the predicate test against the value, stream continues with original elements
import static jhspetersson.packrat.Packrat.removeBy;
var ageDivisibleByThree = getEmployees().gather(removeBy(emp -> emp.age() % 3, 0, (i, value) -> !Objects.equals(i, value))).toList();
System.out.println(ageDivisibleByThree);
[Employee[name=Mark Bloom, age=21], Employee[name=Rebecca Schneider, age=24]]
increasing()
- returns elements in an increasing sequence, elements out of the sequence, as well as repeating values, are dropped
import static jhspetersson.packrat.Packrat.increasing;
var numbers = Stream.of(1, 2, 2, 5, 4, 2, 6, 9, 3, 11, 0, 1, 20);
var increasingNumbers = numbers.gather(increasing()).toList();
System.out.println(increasingNumbers);
[1, 2, 5, 6, 9, 11, 20]
increasingOrEqual()
- returns elements in an increasing sequence, repeating values are preserved, elements out of the sequence are dropped
decreasing()
- returns elements in a decreasing sequence, elements out of the sequence, as well as repeating values, are dropped
decreasingOrEqual()
- returns elements in a decreasing sequence, repeating values are preserved, elements out of the sequence are dropped
increasingChunks()
- returns lists ("chunks") of elements, where each next element is greater than the previous one
import static jhspetersson.packrat.Packrat.increasingChunks;
var numbers = Stream.of(1, 2, 2, 5, 4, 2, 6, 9, 3, 11, 0, 1, 20);
var result = numbers.gather(increasingChunks()).toList();
System.out.println(result);
[[1, 2], [2, 5], [4], [2, 6, 9], [3, 11], [0, 1, 20]]
increasingOrEqualChunks()
- returns lists ("chunks") of elements, where each next element is greater or equal than the previous one
import static jhspetersson.packrat.Packrat.increasingOrEqualChunks;
var numbers = Stream.of(1, 2, 2, 5, 4, 2, 6, 9, 3, 11, 0, 1, 20);
var result = numbers.gather(increasingOrEqualChunks()).toList();
System.out.println(result);
[[1, 2, 2, 5], [4], [2, 6, 9], [3, 11], [0, 1, 20]]
decreasingChunks()
- returns lists ("chunks") of elements, where each next element is less than the previous one
decreasingOrEqualChunks()
- returns lists ("chunks") of elements, where each next element is less or equal than the previous one
reverse()
- reverses the elements
import static jhspetersson.packrat.Packrat.reverse;
var reverseOrdered = IntStream.range(0, 10).boxed().gather(reverse()).toList();
System.out.println(reverseOrdered);
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rotate(distance)
- rotates the elements
import static jhspetersson.packrat.Packrat.rotate;
var positiveRotation = IntStream.range(0, 10).boxed().gather(rotate(3)).toList();
System.out.println(positiveRotation);
var negativeRotation = IntStream.range(0, 10).boxed().gather(rotate(-4)).toList();
System.out.println(negativeRotation);
[7, 8, 9, 0, 1, 2, 3, 4, 5, 6]
[4, 5, 6, 7, 8, 9, 0, 1, 2, 3]
shuffle()
- shuffle the elements
import static jhspetersson.packrat.Packrat.shuffle;
var randomlyOrdered = IntStream.range(0, 10).boxed().gather(shuffle()).toList();
System.out.println(randomlyOrdered);
[2, 7, 6, 9, 8, 5, 1, 3, 0, 4]
chars()
- returns characters as strings parsed from the stream elements
import static jhspetersson.packrat.Packrat.chars;
var charStrings = Stream.of("Hello, \uD83D\uDC22!").gather(chars()).toList();
System.out.println(charStrings);
[H, e, l, l, o, ,, , 🐢, !]
words()
- returns words as strings parsed from the stream elements
import static jhspetersson.packrat.Packrat.words;
var wordStrings = Stream.of("Another test!").gather(words()).toList();
System.out.println(wordStrings);
[Another, test, !]
sentences()
- returns sentences as strings parsed from the stream elements
import static jhspetersson.packrat.Packrat.sentences;
var sentenceStrings = Stream.of("And another one. How many left?").gather(sentences()).toList();
System.out.println(sentenceStrings);
[And another one. , How many left?]
nCopies(n)
- returns n copies of every element, n less than or equal to zero effectively empties the stream
import static jhspetersson.packrat.Packrat.nCopies;
var numbers = IntStream.of(5).boxed().gather(nCopies(10)).toList();
System.out.println(numbers);
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
atLeast(n)
- returns distinct elements that appear at least n times in the stream
import static jhspetersson.packrat.Packrat.atLeast;
var numbers = Stream.of(1, 2, 3, 3, 3, 4, 5, 5, 6, 7, 8, 8, 8, 8, 9, 10);
var atLeastThree = numbers.gather(atLeast(3)).toList();
System.out.println(atLeastThree);
[3, 3, 3, 8, 8, 8, 8]
mapFirst(mapper)
- returns all elements, the first element is mapped with the supplied mapping function
import static jhspetersson.packrat.Packrat.mapFirst;
var mapped = IntStream.rangeClosed(1, 10).boxed().gather(mapFirst(n -> n * 10)).toList();
System.out.println(mapped);
[10, 2, 3, 4, 5, 6, 7, 8, 9, 10]
mapN(n, mapper)
- returns all elements, the first n elements are mapped with the supplied mapping function
import static jhspetersson.packrat.Packrat.mapN;
var mapped = IntStream.rangeClosed(1, 10).boxed().gather(mapN(5, n -> n * 10)).toList();
System.out.println(mapped);
[10, 20, 30, 40, 50, 6, 7, 8, 9, 10]
skipAndMap(n, mapper)
- returns all elements that after the first n are mapped with the supplied mapping function
import static jhspetersson.packrat.Packrat.skipAndMap;
var mapped = IntStream.rangeClosed(1, 10).boxed().gather(skipAndMap(3, n -> n * 10)).toList();
System.out.println(mapped);
[1, 2, 3, 40, 50, 60, 70, 80, 90, 100]
skipAndMapN(skipN, mapN, mapper)
- returns all elements, after skipN elements the first mapN elements are mapped with the supplied mapping function
import static jhspetersson.packrat.Packrat.skipAndMapN;
var mapped = IntStream.rangeClosed(1, 10).boxed().gather(skipAndMapN(3, 5, n -> n * 10)).toList();
System.out.println(mapped);
[1, 2, 3, 40, 50, 60, 70, 80, 9, 10]
flatMapIf(mapper, predicate)
- optionally flattens elements mapped to streams depending on the supplied predicate
import static jhspetersson.packrat.Packrat.flatMapIf;
var strings = Stream.of("A", "B", "CDE");
var result = strings.gather(flatMapIf(s -> Arrays.stream(s.split("")), s -> s.length() > 1)).toList();
System.out.println(result);
[A, B, C, D, E]
zip(input, mapper)
- returns elements mapped ("zipped") with the values from some other stream or iterable
import static jhspetersson.packrat.Packrat.zip;
var names = List.of("Anna", "Mike", "Sandra");
var ages = Stream.of(20, 30, 40, 50, 60, 70, 80, 90);
var users = names.stream().gather(zip(ages, User::new)).toList();
System.out.println(users);
[User[name=Anna, age=20], User[name=Mike, age=30], User[name=Sandra, age=40]]
asGatherer(collector)
- provides the result of the supplied collector as a single element into the stream, effectively converts any Collector into a Gatherer
import static jhspetersson.packrat.Packrat.asGatherer;
var numbers = Stream.of(1, 2, 3, 4, 5);
var listOfCollectedList = numbers.gather(asGatherer(Collectors.toList())).toList();
System.out.println(listOfCollectedList);
[[1, 2, 3, 4, 5]]
Apache-2.0
Supported by JetBrains IDEA open source license.