Skip to content

jhspetersson/packrat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Packrat

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

Availability

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

Gatherers

Name Description
distinctBy Distinct values with custom mapper
filterBy Filter with custom mapper and (optionally) predicate
minBy The smallest element compared after mapping applied
maxBy The greatest element compared after mapping applied
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
sample Sample of the specified size
last Last n elements
lastUnique Last n unique elements
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
zipWithIndex Zips values with an increasing index
asGatherer Converts Collector into Gatherer

distinctBy

distinctBy(mapper) - returns elements with distinct values that result from a mapping by the supplied function

  import static io.github.jhspetersson.packrat.Packrat.distinctBy;
  var oneOddOneEven = IntStream.range(1, 10).boxed().gather(distinctBy(i -> i % 2)).toList();
  System.out.println(oneOddOneEven);

[1, 2]

filterBy

filterBy(mapper, value) - filters mapped elements based on the equality to the value, stream continues with original elements

  import static io.github.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 io.github.jhspetersson.packrat.Packrat.filterBy;
  var ffValue = IntStream.range(0, 1000).boxed().gather(filterBy(Integer::toHexString, "ff", String::equalsIgnoreCase)).toList();
  System.out.println(ffValue);

[255]

minBy

minBy(mapper) - returns the smallest element in the stream, comparing is done after mapping function applied.

  import static io.github.jhspetersson.packrat.Packrat.minBy;
  var check = Stream.of("2", "1", "-12", "22", "10").gather(minBy(Long::parseLong)).toList();
  System.out.println(check);

[-12]

However, resulting list contains original element of type String;

minBy(mapper, comparator) - returns the smallest element in the stream, comparing with given comparator is done after mapping function applied.

maxBy

maxBy(mapper) - returns the greatest element in the stream, comparing is done after mapping function applied.

  import static io.github.jhspetersson.packrat.Packrat.maxBy;
  var check = Stream.of("2", "1", "-12", "22", "10").gather(maxBy(Long::parseLong)).toList();
  System.out.println(check);

[22]

However, resulting list contains original element of type String;

maxBy(mapper, comparator) - returns the greatest element in the stream, comparing with given comparator is done after mapping function applied.

removeBy

removeBy(mapper, value) - removes mapped elements based on the equality to the value, stream continues with original elements

  import static io.github.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 io.github.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

increasing() - returns elements in an increasing sequence, elements out of the sequence, as well as repeating values, are dropped

  import static io.github.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

increasingOrEqual() - returns elements in an increasing sequence, repeating values are preserved, elements out of the sequence are dropped

decreasing

decreasing() - returns elements in a decreasing sequence, elements out of the sequence, as well as repeating values, are dropped

decreasingOrEqual

decreasingOrEqual() - returns elements in a decreasing sequence, repeating values are preserved, elements out of the sequence are dropped

increasingChunks

increasingChunks() - returns lists ("chunks") of elements, where each next element is greater than the previous one

  import static io.github.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

increasingOrEqualChunks() - returns lists ("chunks") of elements, where each next element is greater or equal than the previous one

  import static io.github.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

decreasingChunks() - returns lists ("chunks") of elements, where each next element is less than the previous one

decreasingOrEqualChunks

decreasingOrEqualChunks() - returns lists ("chunks") of elements, where each next element is less or equal than the previous one

reverse

reverse() - reverses the elements

  import static io.github.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

rotate(distance) - rotates the elements

  import static io.github.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() - shuffle the elements

  import static io.github.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]

sample

sample(n) - returns a sample of the specified size from the stream of elements.

  import static io.github.jhspetersson.packrat.Packrat.sample;
  var source = IntStream.range(0, 100).boxed().gather(sample(10)).toList();
  System.out.println(source);

[0, 8, 27, 33, 65, 66, 88, 90, 93, 96]

sample(n, maxSpan) - returns a sample of the specified size from the stream of elements, inspects first maxSpan elements.

last

last(n) - returns n last elements from the stream.

  import static io.github.jhspetersson.packrat.Packrat.last;
  var integers = IntStream.range(0, 100).boxed().gather(last(10)).toList();
  System.out.println(integers);

[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

lastUnique

lastUnique(n) - returns n last unique elements from the stream.

  import static io.github.jhspetersson.packrat.Packrat.lastUnique;
  var integers = List.of(1, 2, 3, 4, 5, 4, 1, 1, 1, 2, 2, 6).stream().gather(lastUnique(3)).toList();
  System.out.println(integers);

[1, 2, 6]

chars

chars() - returns characters as strings parsed from the stream elements

  import static io.github.jhspetersson.packrat.Packrat.chars;
  var charStrings = Stream.of("Hello, \uD83D\uDC22!").gather(chars()).toList();
  System.out.println(charStrings);

[H, e, l, l, o, ,, , 🐢, !]

words

words() - returns words as strings parsed from the stream elements

  import static io.github.jhspetersson.packrat.Packrat.words;
  var wordStrings = Stream.of("Another test!").gather(words()).toList();
  System.out.println(wordStrings);

[Another, test, !]

sentences

sentences() - returns sentences as strings parsed from the stream elements

  import static io.github.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

nCopies(n) - returns n copies of every element, n less than or equal to zero effectively empties the stream

  import static io.github.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

atLeast(n) - returns distinct elements that appear at least n times in the stream

  import static io.github.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

mapFirst(mapper) - returns all elements, the first element is mapped with the supplied mapping function

  import static io.github.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

mapN(n, mapper) - returns all elements, the first n elements are mapped with the supplied mapping function

  import static io.github.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

skipAndMap(n, mapper) - returns all elements that after the first n are mapped with the supplied mapping function

  import static io.github.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

skipAndMapN(skipN, mapN, mapper) - returns all elements, after skipN elements the first mapN elements are mapped with the supplied mapping function

  import static io.github.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

flatMapIf(mapper, predicate) - optionally flattens elements mapped to streams depending on the supplied predicate

  import static io.github.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

zip(input, mapper) - returns elements mapped ("zipped") with the values from some other stream, iterable or iterator.

  import static io.github.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]]

zip(input) - zips current stream and input into Map entries.

  import static io.github.jhspetersson.packrat.Packrat.zip;
  var names = List.of("Anna", "Mike", "Sandra");
  var ages = Stream.of(20, 30, 40);
  var users = names.stream().gather(zip(ages)).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
  System.out.println(users);

{Mike=30, Anna=20, Sandra=40}

zipWithIndex

zipWithIndex() - zips current stream with an increasing index into Map entries.

  import static io.github.jhspetersson.packrat.Packrat.zipWithIndex;
  var names = List.of("Anna", "Mike", "Sandra");
  var users = names.stream().gather(zipWithIndex()).toList();

[0=Anna, 1=Mike, 2=Sandra]

zipWithIndex(startIndex) - zips current stream with an increasing index (beginning with startIndex) into Map entries.

  import static io.github.jhspetersson.packrat.Packrat.zipWithIndex;
  var names = List.of("Anna", "Mike", "Sandra");
  var users = names.stream().gather(zipWithIndex(10)).toList();

[10=Anna, 11=Mike, 12=Sandra]

zipWithIndex(mapper) - zips current stream with an increasing index, mapping function receives the index as the first argument.

  import static io.github.jhspetersson.packrat.Packrat.zipWithIndex;
  var names = List.of("Anna", "Mike", "Sandra");
  var users = names.stream().gather(zipWithIndex(User::new)).toList();

[User[index=0, name=Anna], User[index=1, name=Mike], User[index=2, name=Sandra]]

zipWithIndex(mapper, startIndex) - zips current stream with an increasing index (beginning with startIndex), mapping function receives the index as the first argument.

  import static io.github.jhspetersson.packrat.Packrat.zipWithIndex;
  var names = List.of("Anna", "Mike", "Sandra");
  var users = names.stream().gather(zipWithIndex(User::new, 10)).toList();

[User[index=10, name=Anna], User[index=11, name=Mike], User[index=12, name=Sandra]]

asGatherer

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 io.github.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]]

License

Apache-2.0


Supported by JetBrains IDEA open source license.