Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Java 9 Stream APIs #9837

Merged
merged 19 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions user/super/com/google/gwt/emul/java/util/stream/Collectors.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,38 @@ public static Collector<CharSequence,?,String> joining(CharSequence delimiter) {
downstream.finisher());
}

public static <T, U, A, R> Collector<T, ?, R> flatMapping(Function<? super T,? extends Stream<?
extends U>> mapper, Collector<? super U, A, R> downstream) {
return new CollectorImpl<>(
downstream.supplier(),
(A a, T t) -> {
Stream<? extends U> stream = mapper.apply(t);
if (stream == null) {
return;
}
stream.forEach(u -> {
downstream.accumulator().accept(a, u);
niloc132 marked this conversation as resolved.
Show resolved Hide resolved
});
},
downstream.combiner(),
downstream.finisher()
);
}

public static <T, A, R> Collector<T, ?, R> filtering(Predicate<? super T> predicate,
Collector<? super T, A, R> downstream) {
return new CollectorImpl<>(
downstream.supplier(),
(a, t) -> {
if (predicate.test(t)) {
downstream.accumulator().accept(a, t);
}
},
downstream.combiner(),
downstream.finisher()
);
}

public static <T> Collector<T,?,Optional<T>> maxBy(Comparator<? super T> comparator) {
return reducing(BinaryOperator.maxBy(comparator));
}
Expand Down
82 changes: 80 additions & 2 deletions user/super/com/google/gwt/emul/java/util/stream/DoubleStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,35 @@ public boolean tryAdvance(DoubleConsumer action) {
}

static DoubleStream iterate(double seed, DoubleUnaryOperator f) {
return iterate(seed, ignore -> true, f);
}

static DoubleStream iterate(double seed, DoublePredicate hasNext, DoubleUnaryOperator f) {
Spliterator.OfDouble spliterator =
new Spliterators.AbstractDoubleSpliterator(
Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED) {
private boolean first = true;
private double next = seed;
private boolean terminated = false;

@Override
public boolean tryAdvance(DoubleConsumer action) {
if (terminated) {
return false;
}
if (!first) {
next = f.applyAsDouble(next);
}
first = false;

if (!hasNext.test(next)) {
terminated = true;
return false;
}
action.accept(next);
next = f.applyAsDouble(next);
return true;
}
};

return StreamSupport.doubleStream(spliterator, false);
}

Expand All @@ -185,6 +201,39 @@ static DoubleStream of(double t) {

DoubleStream distinct();

default DoubleStream dropWhile(DoublePredicate predicate) {
Spliterator.OfDouble prev = spliterator();
Spliterator.OfDouble spliterator =
new Spliterators.AbstractDoubleSpliterator(prev.estimateSize(),
prev.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED)) {
private boolean drop = true;
private boolean found;

@Override
public boolean tryAdvance(DoubleConsumer action) {
found = false;
if (drop) {
// drop items until we find one that matches
while (drop && prev.tryAdvance((double item) -> {
if (!predicate.test(item)) {
drop = false;
found = true;
action.accept(item);
}
})) {
// do nothing, work is done in tryAdvance
}
// only return true if we accepted at least one item
return found;
} else {
// accept one item, return result
return prev.tryAdvance(action);
}
}
};
return StreamSupport.doubleStream(spliterator, false);
}

DoubleStream filter(DoublePredicate predicate);

OptionalDouble findAny();
Expand Down Expand Up @@ -239,5 +288,34 @@ static DoubleStream of(double t) {

DoubleSummaryStatistics summaryStatistics();

default DoubleStream takeWhile(DoublePredicate predicate) {
niloc132 marked this conversation as resolved.
Show resolved Hide resolved
Spliterator.OfDouble original = spliterator();
Spliterator.OfDouble spliterator =
new Spliterators.AbstractDoubleSpliterator(original.estimateSize(),
original.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED)) {
private boolean take = true;
private boolean found;

@Override
public boolean tryAdvance(DoubleConsumer action) {
found = false;
if (!take) {
// already failed the check
return false;
}
original.tryAdvance((double item) -> {
if (predicate.test(item)) {
found = true;
action.accept(item);
} else {
take = false;
}
});
return found;
}
};
return StreamSupport.doubleStream(spliterator, false);
}

double[] toArray();
}
83 changes: 80 additions & 3 deletions user/super/com/google/gwt/emul/java/util/stream/IntStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,20 +149,35 @@ public boolean tryAdvance(IntConsumer action) {
}

static IntStream iterate(int seed, IntUnaryOperator f) {
return iterate(seed, ignore -> true, f);
}

AbstractIntSpliterator spliterator =
static IntStream iterate(int seed, IntPredicate hasNext, IntUnaryOperator f) {
Spliterator.OfInt spliterator =
new Spliterators.AbstractIntSpliterator(
Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED) {
private boolean first = true;
private int next = seed;
private boolean terminated = false;

@Override
public boolean tryAdvance(IntConsumer action) {
if (terminated) {
return false;
}
if (!first) {
next = f.applyAsInt(next);
}
first = false;

if (!hasNext.test(next)) {
terminated = true;
return false;
}
action.accept(next);
next = f.applyAsInt(next);
return true;
}
};

return StreamSupport.intStream(spliterator, false);
}

Expand Down Expand Up @@ -235,6 +250,39 @@ public boolean tryAdvance(IntConsumer action) {

IntStream distinct();

default IntStream dropWhile(IntPredicate predicate) {
Spliterator.OfInt prev = spliterator();
Spliterator.OfInt spliterator =
new Spliterators.AbstractIntSpliterator(prev.estimateSize(),
prev.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED)) {
private boolean drop = true;
private boolean found;

@Override
public boolean tryAdvance(IntConsumer action) {
found = false;
if (drop) {
// drop items until we find one that matches
while (drop && prev.tryAdvance((int item) -> {
if (!predicate.test(item)) {
drop = false;
found = true;
action.accept(item);
}
})) {
// do nothing, work is done in tryAdvance
}
// only return true if we accepted at least one item
return found;
} else {
// accept one item, return result
return prev.tryAdvance(action);
}
}
};
return StreamSupport.intStream(spliterator, false);
}

IntStream filter(IntPredicate predicate);

OptionalInt findAny();
Expand Down Expand Up @@ -289,5 +337,34 @@ public boolean tryAdvance(IntConsumer action) {

IntSummaryStatistics summaryStatistics();

default IntStream takeWhile(IntPredicate predicate) {
Spliterator.OfInt original = spliterator();
Spliterator.OfInt spliterator =
new Spliterators.AbstractIntSpliterator(original.estimateSize(),
original.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED)) {
private boolean take = true;
private boolean found;

@Override
public boolean tryAdvance(IntConsumer action) {
found = false;
if (!take) {
// already failed the check
return false;
}
original.tryAdvance((int item) -> {
if (predicate.test(item)) {
found = true;
action.accept(item);
} else {
take = false;
}
});
return found;
}
};
return StreamSupport.intStream(spliterator, false);
}

int[] toArray();
}
83 changes: 81 additions & 2 deletions user/super/com/google/gwt/emul/java/util/stream/LongStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,32 @@ public boolean tryAdvance(LongConsumer action) {
}

static LongStream iterate(long seed, LongUnaryOperator f) {
AbstractLongSpliterator spliterator =
return iterate(seed, ignore -> true, f);
}

static LongStream iterate(long seed, LongPredicate hasNext, LongUnaryOperator f) {
Spliterator.OfLong spliterator =
new Spliterators.AbstractLongSpliterator(
Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED) {
private boolean first = true;
private long next = seed;
private boolean terminated = false;

@Override
public boolean tryAdvance(LongConsumer action) {
if (terminated) {
return false;
}
if (!first) {
next = f.applyAsLong(next);
}
first = false;

if (!hasNext.test(next)) {
terminated = true;
return false;
}
action.accept(next);
next = f.applyAsLong(next);
return true;
}
};
Expand Down Expand Up @@ -231,6 +248,39 @@ public boolean tryAdvance(LongConsumer action) {

LongStream distinct();

default LongStream dropWhile(LongPredicate predicate) {
Spliterator.OfLong prev = spliterator();
Spliterator.OfLong spliterator =
new Spliterators.AbstractLongSpliterator(prev.estimateSize(),
prev.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED)) {
private boolean drop = true;
private boolean found;

@Override
public boolean tryAdvance(LongConsumer action) {
found = false;
if (drop) {
// drop items until we find one that matches
while (drop && prev.tryAdvance((long item) -> {
if (!predicate.test(item)) {
drop = false;
found = true;
action.accept(item);
}
})) {
// do nothing, work is done in tryAdvance
}
// only return true if we accepted at least one item
return found;
} else {
// accept one item, return result
return prev.tryAdvance(action);
}
}
};
return StreamSupport.longStream(spliterator, false);
}

LongStream filter(LongPredicate predicate);

OptionalLong findAny();
Expand Down Expand Up @@ -285,5 +335,34 @@ public boolean tryAdvance(LongConsumer action) {

LongSummaryStatistics summaryStatistics();

default LongStream takeWhile(LongPredicate predicate) {
Spliterator.OfLong original = spliterator();
Spliterator.OfLong spliterator =
new Spliterators.AbstractLongSpliterator(original.estimateSize(),
original.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED)) {
private boolean take = true;
private boolean found;

@Override
public boolean tryAdvance(LongConsumer action) {
found = false;
if (!take) {
// already failed the check
return false;
}
original.tryAdvance((long item) -> {
if (predicate.test(item)) {
found = true;
action.accept(item);
} else {
take = false;
}
});
return found;
}
};
return StreamSupport.longStream(spliterator, false);
}

long[] toArray();
}
Loading
Loading