Skip to content

Commit

Permalink
Add MoreGatherers.distinctUntilChanged()
Browse files Browse the repository at this point in the history
  • Loading branch information
pivovarit committed Oct 10, 2024
1 parent da25b09 commit 9be4c47
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ Provided `Gatherers`:
- `MoreGatherers.zip(Collection<T2>, BiFunction<T1,T2>)`
- `MoreGatherers.zip(Iterator<T2>, BiFunction<T1,T2>)`
- `MoreGatherers.zip(Stream<T2>, BiFunction<T1,T2>)`
- `MoreGatherers.distinctUntilChanged()`
- `MoreGatherers.distinctUntilChanged(Function<T, R>)`
- `MoreGatherers.distinctBy(Function<T, R>)`
24 changes: 24 additions & 0 deletions src/main/java/com/pivovarit/gatherers/MoreGatherers.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,30 @@ private MoreGatherers() {
);
}

public static <T> Gatherer<T, ?, T> distinctUntilChanged() {
return distinctUntilChanged(Function.identity());
}

public static <T, U> Gatherer<T, ?, T> distinctUntilChanged(Function<? super T, ? extends U> keyExtractor) {
Objects.requireNonNull(keyExtractor, "keyExtractor can't be null");
class State {
U value;
boolean hasValue;
}
return Gatherer.ofSequential(
State::new,
(state, element, downstream) -> {
U key = keyExtractor.apply(element);
if (!state.hasValue || !Objects.equals(state.value, key)) {
state.value = key;
state.hasValue = true;
downstream.push(element);
}
return true;
}
);
}

public static <T1, T2> Gatherer<T1, ?, Map.Entry<T1, T2>> zip(Stream<T2> other) {
Objects.requireNonNull(other, "other can't be null");
return zip(other.iterator());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.pivovarit.gatherers;

import org.junit.jupiter.api.Test;

import java.util.stream.Stream;

import static com.pivovarit.gatherers.MoreGatherers.distinctUntilChanged;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

class DistinctUntilChangedMapperTest {

@Test
void shouldDistinctUntilChangedEmptyStream() {
assertThat(Stream.empty().gather(distinctUntilChanged(i -> i))).isEmpty();
}

@Test
void shouldDistinctUntilChangedMapper() {
assertThat(Stream.of("a", "b", "bb", "cc", "ddd", "eee", "ffff", "ggggg", "hhhhh", "iiiii", "j", "k")
.gather(distinctUntilChanged(s -> s.length())))
.containsExactly("a", "bb", "ddd", "ffff", "ggggg", "j");
}

@Test
void shouldRejectNullMapper() {
assertThatThrownBy(() -> distinctUntilChanged(null)).isInstanceOf(NullPointerException.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.pivovarit.gatherers;

import org.junit.jupiter.api.Test;

import java.util.stream.Stream;

import static com.pivovarit.gatherers.MoreGatherers.distinctUntilChanged;
import static org.assertj.core.api.Assertions.assertThat;

class DistinctUntilChangedTest {

@Test
void shouldDistinctUntilChangedEmptyStream() {
assertThat(Stream.empty().gather(distinctUntilChanged())).isEmpty();
}

@Test
void shouldDistinctUntilChanged() {
assertThat(Stream.of(1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 1, 1)
.gather(distinctUntilChanged()))
.containsExactly(1, 2, 3, 4, 5, 1);
}
}

0 comments on commit 9be4c47

Please sign in to comment.