Refactor stream implementation and tests, fix some bugs

This commit is contained in:
Alexey Andreev 2019-11-08 19:30:10 +03:00
parent 74ee848e0c
commit b090c2f47d
44 changed files with 1342 additions and 697 deletions

View File

@ -0,0 +1,35 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.doubleimpl;
import java.util.function.DoublePredicate;
public class TAllMatchConsumer implements DoublePredicate {
public boolean matched = true;
private DoublePredicate predicate;
public TAllMatchConsumer(DoublePredicate predicate) {
this.predicate = predicate;
}
@Override
public boolean test(double t) {
if (!predicate.test(t)) {
matched = false;
}
return matched;
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.doubleimpl;
import java.util.function.DoublePredicate;
public class TAnyMatchConsumer implements DoublePredicate {
public boolean matched;
private DoublePredicate predicate;
public TAnyMatchConsumer(DoublePredicate predicate) {
this.predicate = predicate;
}
@Override
public boolean test(double t) {
matched = predicate.test(t);
return !matched;
}
}

View File

@ -30,6 +30,6 @@ public class TEmptyDoubleStreamImpl extends TSimpleDoubleStreamImpl {
@Override
public long count() {
return 1;
return 0;
}
}

View File

@ -22,6 +22,7 @@ import org.teavm.classlib.java.util.stream.TDoubleStream;
public class TFlatMappingDoubleStreamImpl extends TSimpleDoubleStreamImpl {
private TSimpleDoubleStreamImpl sourceStream;
private boolean currentSet;
private TDoubleStream current;
private PrimitiveIterator.OfDouble iterator;
private DoubleFunction<? extends TDoubleStream> mapper;
@ -35,25 +36,27 @@ public class TFlatMappingDoubleStreamImpl extends TSimpleDoubleStreamImpl {
@Override
public boolean next(DoublePredicate consumer) {
while (true) {
if (current == null) {
if (done) {
return false;
}
currentSet = false;
while (!currentSet) {
boolean hasMore = sourceStream.next(e -> {
current = mapper.apply(e);
currentSet = true;
return false;
});
if (!hasMore) {
done = true;
break;
}
}
if (current == null) {
done = true;
return false;
}
}
if (current instanceof TSimpleDoubleStreamImpl) {
@SuppressWarnings("unchecked")
TSimpleDoubleStreamImpl castCurrent = (TSimpleDoubleStreamImpl) current;
if (castCurrent.next(consumer)) {
return true;
@ -62,7 +65,7 @@ public class TFlatMappingDoubleStreamImpl extends TSimpleDoubleStreamImpl {
} else {
iterator = current.iterator();
while (iterator.hasNext()) {
double e = iterator.nextDouble();
double e = iterator.next();
if (!consumer.test(e)) {
return true;
}
@ -70,7 +73,7 @@ public class TFlatMappingDoubleStreamImpl extends TSimpleDoubleStreamImpl {
iterator = null;
current = null;
}
}
return true;
}
@Override

View File

@ -101,10 +101,15 @@ public abstract class TSimpleDoubleStreamImpl implements TDoubleStream {
@Override
public void forEachOrdered(DoubleConsumer action) {
next(e -> {
while (true) {
boolean hasMore = next(e -> {
action.accept(e);
return true;
});
if (!hasMore) {
return;
}
}
}
@Override
@ -112,7 +117,9 @@ public abstract class TSimpleDoubleStreamImpl implements TDoubleStream {
int estimatedSize = estimateSize();
if (estimatedSize < 0) {
List<Double> list = new ArrayList<>();
next(list::add);
while (next(list::add)) {
// go on
}
double[] array = new double[list.size()];
for (int i = 0; i < array.length; ++i) {
array[i] = list.get(i);
@ -121,8 +128,9 @@ public abstract class TSimpleDoubleStreamImpl implements TDoubleStream {
} else {
double[] array = new double[estimatedSize];
ArrayFillingConsumer consumer = new ArrayFillingConsumer(array);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have reported done status";
while (next(consumer)) {
// go on
}
if (consumer.index < array.length) {
array = Arrays.copyOf(array, consumer.index);
}
@ -133,26 +141,33 @@ public abstract class TSimpleDoubleStreamImpl implements TDoubleStream {
@Override
public double reduce(double identity, DoubleBinaryOperator accumulator) {
TReducingDoubleConsumer consumer = new TReducingDoubleConsumer(accumulator, identity, true);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.result;
}
@Override
public OptionalDouble reduce(DoubleBinaryOperator accumulator) {
TReducingDoubleConsumer consumer = new TReducingDoubleConsumer(accumulator, 0, false);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.initialized ? OptionalDouble.of(consumer.result) : OptionalDouble.empty();
}
@Override
public <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner) {
R collection = supplier.get();
next(e -> {
while (true) {
boolean hasMore = next(e -> {
accumulator.accept(collection, e);
return true;
});
if (!hasMore) {
break;
}
}
return collection;
}
@ -169,32 +184,46 @@ public abstract class TSimpleDoubleStreamImpl implements TDoubleStream {
@Override
public long count() {
TCountingDoubleConsumer consumer = new TCountingDoubleConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.count;
}
@Override
public double sum() {
TSumDoubleConsumer consumer = new TSumDoubleConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.sum;
}
@Override
public OptionalDouble average() {
TAverageDoubleConsumer consumer = new TAverageDoubleConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.count > 0 ? OptionalDouble.of(consumer.sum / consumer.count) : OptionalDouble.empty();
}
@Override
public boolean anyMatch(DoublePredicate predicate) {
return next(predicate.negate());
TAnyMatchConsumer consumer = new TAnyMatchConsumer(predicate);
while (!consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
public boolean allMatch(DoublePredicate predicate) {
return !next(predicate);
TAllMatchConsumer consumer = new TAllMatchConsumer(predicate);
while (consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
@ -205,7 +234,9 @@ public abstract class TSimpleDoubleStreamImpl implements TDoubleStream {
@Override
public OptionalDouble findFirst() {
TFindFirstDoubleConsumer consumer = new TFindFirstDoubleConsumer();
next(consumer);
while (!consumer.hasAny && next(consumer)) {
// go on
}
return consumer.hasAny ? OptionalDouble.of(consumer.result) : OptionalDouble.empty();
}
@ -264,7 +295,7 @@ public abstract class TSimpleDoubleStreamImpl implements TDoubleStream {
public abstract boolean next(DoublePredicate consumer);
class ArrayFillingConsumer implements DoublePredicate {
static class ArrayFillingConsumer implements DoublePredicate {
double[] array;
int index;

View File

@ -53,13 +53,21 @@ public class TSimpleDoubleStreamIterator implements PrimitiveIterator.OfDouble {
if (state != NEEDS_MORE) {
return;
}
state = NEEDS_MORE;
while (state == NEEDS_MORE) {
boolean hasMore = stream.next(e -> {
lastElement = e;
state = HAS_DATA;
return false;
});
state = hasMore ? HAS_DATA : LAST_ELEMENT;
if (state == LAST_ELEMENT) {
if (!hasMore) {
if (state == NEEDS_MORE) {
state = DONE;
} else {
state = LAST_ELEMENT;
}
stream = null;
}
}
}
}

View File

@ -20,6 +20,7 @@ import java.util.function.DoubleConsumer;
public class TSimpleDoubleStreamSpliterator implements Spliterator.OfDouble {
private TSimpleDoubleStreamImpl stream;
private boolean foundItems;
private boolean done;
public TSimpleDoubleStreamSpliterator(TSimpleDoubleStreamImpl stream) {
@ -39,10 +40,14 @@ public class TSimpleDoubleStreamSpliterator implements Spliterator.OfDouble {
if (done) {
return false;
}
foundItems = false;
while (!foundItems && !done) {
done = !stream.next(x -> {
action.accept(x);
foundItems = true;
return false;
});
}
return true;
}

View File

@ -30,7 +30,7 @@ public class TSkippingDoubleStreamImpl extends TSimpleDoubleStreamImpl {
@Override
public boolean next(DoublePredicate consumer) {
if (remaining > 0) {
while (remaining > 0) {
if (!sourceStream.next(e -> --remaining > 0)) {
return false;
}

View File

@ -33,18 +33,17 @@ public class TSpecializedConcatDoubleStream extends TSimpleDoubleStreamImpl {
if (current == null) {
return false;
}
while (true) {
if (current.next(consumer)) {
return true;
}
if (current == first) {
current = second;
return true;
} else {
current = null;
return false;
}
}
}
@Override
protected int estimateSize() {

View File

@ -0,0 +1,35 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.impl;
import java.util.function.Predicate;
public class TAllMatchConsumer<T> implements Predicate<T> {
public boolean matched = true;
private Predicate<? super T> predicate;
public TAllMatchConsumer(Predicate<? super T> predicate) {
this.predicate = predicate;
}
@Override
public boolean test(T t) {
if (!predicate.test(t)) {
matched = false;
}
return matched;
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.impl;
import java.util.function.Predicate;
public class TAnyMatchConsumer<T> implements Predicate<T> {
public boolean matched;
private Predicate<? super T> predicate;
public TAnyMatchConsumer(Predicate<? super T> predicate) {
this.predicate = predicate;
}
@Override
public boolean test(T t) {
matched = predicate.test(t);
return !matched;
}
}

View File

@ -30,6 +30,6 @@ public class TEmptyStreamImpl<T> extends TSimpleStreamImpl<T> {
@Override
public long count() {
return 1;
return 0;
}
}

View File

@ -22,6 +22,7 @@ import org.teavm.classlib.java.util.stream.TStream;
public class TFlatMappingStreamImpl<T, S> extends TSimpleStreamImpl<T> {
private TSimpleStreamImpl<S> sourceStream;
private boolean currentSet;
private TStream<? extends T> current;
private Iterator<? extends T> iterator;
private Function<? super S, ? extends TStream<? extends T>> mapper;
@ -35,20 +36,23 @@ public class TFlatMappingStreamImpl<T, S> extends TSimpleStreamImpl<T> {
@Override
public boolean next(Predicate<? super T> consumer) {
while (true) {
if (current == null) {
if (done) {
return false;
}
currentSet = false;
while (!currentSet) {
boolean hasMore = sourceStream.next(e -> {
current = mapper.apply(e);
currentSet = true;
return false;
});
if (!hasMore) {
done = true;
break;
}
}
if (current == null) {
done = true;
return false;
}
}
@ -70,7 +74,7 @@ public class TFlatMappingStreamImpl<T, S> extends TSimpleStreamImpl<T> {
iterator = null;
current = null;
}
}
return true;
}
@Override

View File

@ -24,6 +24,7 @@ import org.teavm.classlib.java.util.stream.doubleimpl.TSimpleDoubleStreamImpl;
public class TFlatMappingToDoubleStreamImpl<T> extends TSimpleDoubleStreamImpl {
private TSimpleStreamImpl<T> sourceStream;
private TDoubleStream current;
private boolean currentSet;
private PrimitiveIterator.OfDouble iterator;
private Function<? super T, ? extends TDoubleStream> mapper;
private boolean done;
@ -36,25 +37,27 @@ public class TFlatMappingToDoubleStreamImpl<T> extends TSimpleDoubleStreamImpl {
@Override
public boolean next(DoublePredicate consumer) {
while (true) {
if (current == null) {
if (done) {
return false;
}
currentSet = false;
while (!currentSet) {
boolean hasMore = sourceStream.next(e -> {
current = mapper.apply(e);
currentSet = true;
return false;
});
if (!hasMore) {
done = true;
break;
}
}
if (current == null) {
done = true;
return false;
}
}
if (current instanceof TSimpleDoubleStreamImpl) {
@SuppressWarnings("unchecked")
TSimpleDoubleStreamImpl castCurrent = (TSimpleDoubleStreamImpl) current;
if (castCurrent.next(consumer)) {
return true;
@ -63,7 +66,7 @@ public class TFlatMappingToDoubleStreamImpl<T> extends TSimpleDoubleStreamImpl {
} else {
iterator = current.iterator();
while (iterator.hasNext()) {
double e = iterator.nextDouble();
double e = iterator.next();
if (!consumer.test(e)) {
return true;
}
@ -71,7 +74,7 @@ public class TFlatMappingToDoubleStreamImpl<T> extends TSimpleDoubleStreamImpl {
iterator = null;
current = null;
}
}
return true;
}
@Override

View File

@ -24,6 +24,7 @@ import org.teavm.classlib.java.util.stream.intimpl.TSimpleIntStreamImpl;
public class TFlatMappingToIntStreamImpl<T> extends TSimpleIntStreamImpl {
private TSimpleStreamImpl<T> sourceStream;
private TIntStream current;
private boolean currentSet;
private PrimitiveIterator.OfInt iterator;
private Function<? super T, ? extends TIntStream> mapper;
private boolean done;
@ -36,25 +37,27 @@ public class TFlatMappingToIntStreamImpl<T> extends TSimpleIntStreamImpl {
@Override
public boolean next(IntPredicate consumer) {
while (true) {
if (current == null) {
if (done) {
return false;
}
currentSet = false;
while (!currentSet) {
boolean hasMore = sourceStream.next(e -> {
current = mapper.apply(e);
currentSet = true;
return false;
});
if (!hasMore) {
done = true;
break;
}
}
if (current == null) {
done = true;
return false;
}
}
if (current instanceof TSimpleIntStreamImpl) {
@SuppressWarnings("unchecked")
TSimpleIntStreamImpl castCurrent = (TSimpleIntStreamImpl) current;
if (castCurrent.next(consumer)) {
return true;
@ -63,7 +66,7 @@ public class TFlatMappingToIntStreamImpl<T> extends TSimpleIntStreamImpl {
} else {
iterator = current.iterator();
while (iterator.hasNext()) {
int e = iterator.nextInt();
int e = iterator.next();
if (!consumer.test(e)) {
return true;
}
@ -71,7 +74,7 @@ public class TFlatMappingToIntStreamImpl<T> extends TSimpleIntStreamImpl {
iterator = null;
current = null;
}
}
return true;
}
@Override

View File

@ -24,6 +24,7 @@ import org.teavm.classlib.java.util.stream.longimpl.TSimpleLongStreamImpl;
public class TFlatMappingToLongStreamImpl<T> extends TSimpleLongStreamImpl {
private TSimpleStreamImpl<T> sourceStream;
private TLongStream current;
private boolean currentSet;
private PrimitiveIterator.OfLong iterator;
private Function<? super T, ? extends TLongStream> mapper;
private boolean done;
@ -36,25 +37,27 @@ public class TFlatMappingToLongStreamImpl<T> extends TSimpleLongStreamImpl {
@Override
public boolean next(LongPredicate consumer) {
while (true) {
if (current == null) {
if (done) {
return false;
}
currentSet = false;
while (!currentSet) {
boolean hasMore = sourceStream.next(e -> {
current = mapper.apply(e);
currentSet = true;
return false;
});
if (!hasMore) {
done = true;
break;
}
}
if (current == null) {
done = true;
return false;
}
}
if (current instanceof TSimpleLongStreamImpl) {
@SuppressWarnings("unchecked")
TSimpleLongStreamImpl castCurrent = (TSimpleLongStreamImpl) current;
if (castCurrent.next(consumer)) {
return true;
@ -63,7 +66,7 @@ public class TFlatMappingToLongStreamImpl<T> extends TSimpleLongStreamImpl {
} else {
iterator = current.iterator();
while (iterator.hasNext()) {
long e = iterator.nextLong();
long e = iterator.next();
if (!consumer.test(e)) {
return true;
}
@ -71,7 +74,7 @@ public class TFlatMappingToLongStreamImpl<T> extends TSimpleLongStreamImpl {
iterator = null;
current = null;
}
}
return true;
}
@Override

View File

@ -123,10 +123,15 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
@Override
public void forEachOrdered(Consumer<? super T> action) {
next(e -> {
while (true) {
boolean hasMore = next(e -> {
action.accept(e);
return true;
});
if (!hasMore) {
return;
}
}
}
@Override
@ -140,7 +145,9 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
int estimatedSize = estimateSize();
if (estimatedSize < 0) {
List<T> list = new ArrayList<>();
next(list::add);
while (next(list::add)) {
// go on
}
A[] array = generator.apply(list.size());
for (int i = 0; i < array.length; ++i) {
array[i] = (A) list.get(i);
@ -148,9 +155,10 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
return array;
} else {
A[] array = generator.apply(estimatedSize);
ArrayFillingConsumer<A> consumer = new ArrayFillingConsumer<>(array);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have reported done status";
ArrayFillingConsumer<A, T> consumer = new ArrayFillingConsumer<>(array);
while (next(consumer)) {
// go on
}
if (consumer.index < array.length) {
array = Arrays.copyOf(array, consumer.index);
}
@ -161,34 +169,42 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
@Override
public T reduce(T identity, BinaryOperator<T> accumulator) {
TReducingConsumer<T> consumer = new TReducingConsumer<>(accumulator, identity, true);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.result;
}
@Override
public Optional<T> reduce(BinaryOperator<T> accumulator) {
TReducingConsumer<T> consumer = new TReducingConsumer<>(accumulator, null, false);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return Optional.ofNullable(consumer.result);
}
@Override
public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner) {
TReducingConsumer2<T, U> consumer = new TReducingConsumer2<>(accumulator, identity);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.result;
}
@Override
public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner) {
R collection = supplier.get();
next(e -> {
while (true) {
boolean hasMore = next(e -> {
accumulator.accept(collection, e);
return true;
});
if (!hasMore) {
break;
}
}
return collection;
}
@ -216,18 +232,28 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
@Override
public long count() {
TCountingConsumer<T> consumer = new TCountingConsumer<>();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.count;
}
@Override
public boolean anyMatch(Predicate<? super T> predicate) {
return next(predicate.negate());
TAnyMatchConsumer<T> consumer = new TAnyMatchConsumer<>(predicate);
while (!consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
public boolean allMatch(Predicate<? super T> predicate) {
return !next(predicate);
TAllMatchConsumer<T> consumer = new TAllMatchConsumer<>(predicate);
while (consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
@ -238,7 +264,9 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
@Override
public Optional<T> findFirst() {
TFindFirstConsumer<T> consumer = new TFindFirstConsumer<>();
next(consumer);
while (consumer.result == null && next(consumer)) {
// go on
}
return Optional.ofNullable(consumer.result);
}
@ -292,7 +320,7 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
public abstract boolean next(Predicate<? super T> consumer);
class ArrayFillingConsumer<A> implements Predicate<T> {
static class ArrayFillingConsumer<A, T> implements Predicate<T> {
A[] array;
int index;

View File

@ -63,13 +63,21 @@ public class TSimpleStreamIterator<T> implements Iterator<T> {
if (state != NEEDS_MORE) {
return;
}
state = NEEDS_MORE;
while (state == NEEDS_MORE) {
boolean hasMore = stream.next(e -> {
lastElement = e;
state = HAS_DATA;
return false;
});
state = hasMore ? HAS_DATA : LAST_ELEMENT;
if (state == LAST_ELEMENT) {
if (!hasMore) {
if (state == NEEDS_MORE) {
state = DONE;
} else {
state = LAST_ELEMENT;
}
stream = null;
}
}
}
}

View File

@ -20,6 +20,7 @@ import java.util.function.Consumer;
public class TSimpleStreamSpliterator<T> implements Spliterator<T> {
private TSimpleStreamImpl<T> stream;
private boolean foundItems;
private boolean done;
public TSimpleStreamSpliterator(TSimpleStreamImpl<T> stream) {
@ -28,10 +29,15 @@ public class TSimpleStreamSpliterator<T> implements Spliterator<T> {
@Override
public void forEachRemaining(Consumer<? super T> action) {
stream.next(x -> {
while (true) {
boolean hasMore = stream.next(x -> {
action.accept(x);
return true;
});
if (!hasMore) {
break;
}
}
}
@Override
@ -39,10 +45,14 @@ public class TSimpleStreamSpliterator<T> implements Spliterator<T> {
if (done) {
return false;
}
foundItems = false;
while (!foundItems && !done) {
done = !stream.next(x -> {
action.accept(x);
foundItems = true;
return false;
});
}
return true;
}

View File

@ -30,7 +30,7 @@ public class TSkippingStreamImpl<T> extends TSimpleStreamImpl<T> {
@Override
public boolean next(Predicate<? super T> consumer) {
if (remaining > 0) {
while (remaining > 0) {
if (!sourceStream.next(e -> --remaining > 0)) {
return false;
}

View File

@ -33,18 +33,17 @@ public class TSpecializedConcatStream<T> extends TSimpleStreamImpl<T> {
if (current == null) {
return false;
}
while (true) {
if (current.next(consumer)) {
return true;
}
if (current == first) {
current = second;
return true;
} else {
current = null;
return false;
}
}
}
@Override
protected int estimateSize() {

View File

@ -0,0 +1,35 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.intimpl;
import java.util.function.IntPredicate;
public class TAllMatchConsumer implements IntPredicate {
public boolean matched = true;
private IntPredicate predicate;
public TAllMatchConsumer(IntPredicate predicate) {
this.predicate = predicate;
}
@Override
public boolean test(int t) {
if (!predicate.test(t)) {
matched = false;
}
return matched;
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.intimpl;
import java.util.function.IntPredicate;
public class TAnyMatchConsumer implements IntPredicate {
public boolean matched;
private IntPredicate predicate;
public TAnyMatchConsumer(IntPredicate predicate) {
this.predicate = predicate;
}
@Override
public boolean test(int t) {
matched = predicate.test(t);
return !matched;
}
}

View File

@ -30,6 +30,6 @@ public class TEmptyIntStreamImpl extends TSimpleIntStreamImpl {
@Override
public long count() {
return 1;
return 0;
}
}

View File

@ -22,6 +22,7 @@ import org.teavm.classlib.java.util.stream.TIntStream;
public class TFlatMappingIntStreamImpl extends TSimpleIntStreamImpl {
private TSimpleIntStreamImpl sourceStream;
private boolean currentSet;
private TIntStream current;
private PrimitiveIterator.OfInt iterator;
private IntFunction<? extends TIntStream> mapper;
@ -34,25 +35,27 @@ public class TFlatMappingIntStreamImpl extends TSimpleIntStreamImpl {
@Override
public boolean next(IntPredicate consumer) {
while (true) {
if (current == null) {
if (done) {
return false;
}
currentSet = false;
while (!currentSet) {
boolean hasMore = sourceStream.next(e -> {
current = mapper.apply(e);
currentSet = true;
return false;
});
if (!hasMore) {
done = true;
break;
}
}
if (current == null) {
done = true;
return false;
}
}
if (current instanceof TSimpleIntStreamImpl) {
@SuppressWarnings("unchecked")
TSimpleIntStreamImpl castCurrent = (TSimpleIntStreamImpl) current;
if (castCurrent.next(consumer)) {
return true;
@ -61,7 +64,7 @@ public class TFlatMappingIntStreamImpl extends TSimpleIntStreamImpl {
} else {
iterator = current.iterator();
while (iterator.hasNext()) {
int e = iterator.nextInt();
int e = iterator.next();
if (!consumer.test(e)) {
return true;
}
@ -69,7 +72,7 @@ public class TFlatMappingIntStreamImpl extends TSimpleIntStreamImpl {
iterator = null;
current = null;
}
}
return true;
}
@Override

View File

@ -102,10 +102,15 @@ public abstract class TSimpleIntStreamImpl implements TIntStream {
@Override
public void forEachOrdered(IntConsumer action) {
next(e -> {
while (true) {
boolean hasMore = next(e -> {
action.accept(e);
return true;
});
if (!hasMore) {
return;
}
}
}
@Override
@ -113,7 +118,9 @@ public abstract class TSimpleIntStreamImpl implements TIntStream {
int estimatedSize = estimateSize();
if (estimatedSize < 0) {
List<Integer> list = new ArrayList<>();
next(list::add);
while (next(list::add)) {
// go on
}
int[] array = new int[list.size()];
for (int i = 0; i < array.length; ++i) {
array[i] = list.get(i);
@ -122,8 +129,9 @@ public abstract class TSimpleIntStreamImpl implements TIntStream {
} else {
int[] array = new int[estimatedSize];
ArrayFillingConsumer consumer = new ArrayFillingConsumer(array);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have reported done status";
while (next(consumer)) {
// go on
}
if (consumer.index < array.length) {
array = Arrays.copyOf(array, consumer.index);
}
@ -134,26 +142,33 @@ public abstract class TSimpleIntStreamImpl implements TIntStream {
@Override
public int reduce(int identity, IntBinaryOperator accumulator) {
TReducingIntConsumer consumer = new TReducingIntConsumer(accumulator, identity, true);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.result;
}
@Override
public OptionalInt reduce(IntBinaryOperator accumulator) {
TReducingIntConsumer consumer = new TReducingIntConsumer(accumulator, 0, false);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.initialized ? OptionalInt.of(consumer.result) : OptionalInt.empty();
}
@Override
public <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner) {
R collection = supplier.get();
next(e -> {
while (true) {
boolean hasMore = next(e -> {
accumulator.accept(collection, e);
return true;
});
if (!hasMore) {
break;
}
}
return collection;
}
@ -170,32 +185,46 @@ public abstract class TSimpleIntStreamImpl implements TIntStream {
@Override
public long count() {
TCountingIntConsumer consumer = new TCountingIntConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.count;
}
@Override
public int sum() {
TSumIntConsumer consumer = new TSumIntConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.sum;
}
@Override
public OptionalDouble average() {
TSumIntAsDoubleConsumer consumer = new TSumIntAsDoubleConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.count > 0 ? OptionalDouble.of(consumer.sum / consumer.count) : OptionalDouble.empty();
}
@Override
public boolean anyMatch(IntPredicate predicate) {
return next(predicate.negate());
TAnyMatchConsumer consumer = new TAnyMatchConsumer(predicate);
while (!consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
public boolean allMatch(IntPredicate predicate) {
return !next(predicate);
TAllMatchConsumer consumer = new TAllMatchConsumer(predicate);
while (consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
@ -206,7 +235,9 @@ public abstract class TSimpleIntStreamImpl implements TIntStream {
@Override
public OptionalInt findFirst() {
TFindFirstIntConsumer consumer = new TFindFirstIntConsumer();
next(consumer);
while (!consumer.hasAny && next(consumer)) {
// go on
}
return consumer.hasAny ? OptionalInt.of(consumer.result) : OptionalInt.empty();
}
@ -275,7 +306,7 @@ public abstract class TSimpleIntStreamImpl implements TIntStream {
public abstract boolean next(IntPredicate consumer);
class ArrayFillingConsumer implements IntPredicate {
static class ArrayFillingConsumer implements IntPredicate {
int[] array;
int index;

View File

@ -53,13 +53,21 @@ public class TSimpleIntStreamIterator implements PrimitiveIterator.OfInt {
if (state != NEEDS_MORE) {
return;
}
state = NEEDS_MORE;
while (state == NEEDS_MORE) {
boolean hasMore = stream.next(e -> {
lastElement = e;
state = HAS_DATA;
return false;
});
state = hasMore ? HAS_DATA : LAST_ELEMENT;
if (state == LAST_ELEMENT) {
if (!hasMore) {
if (state == NEEDS_MORE) {
state = DONE;
} else {
state = LAST_ELEMENT;
}
stream = null;
}
}
}
}

View File

@ -20,6 +20,7 @@ import java.util.function.IntConsumer;
public class TSimpleIntStreamSpliterator implements Spliterator.OfInt {
private TSimpleIntStreamImpl stream;
private boolean foundItems;
private boolean done;
public TSimpleIntStreamSpliterator(TSimpleIntStreamImpl stream) {
@ -39,10 +40,14 @@ public class TSimpleIntStreamSpliterator implements Spliterator.OfInt {
if (done) {
return false;
}
foundItems = false;
while (!foundItems && !done) {
done = !stream.next(x -> {
action.accept(x);
foundItems = true;
return false;
});
}
return true;
}

View File

@ -30,7 +30,7 @@ public class TSkippingIntStreamImpl extends TSimpleIntStreamImpl {
@Override
public boolean next(IntPredicate consumer) {
if (remaining > 0) {
while (remaining > 0) {
if (!sourceStream.next(e -> --remaining > 0)) {
return false;
}

View File

@ -33,18 +33,17 @@ public class TSpecializedConcatIntStream extends TSimpleIntStreamImpl {
if (current == null) {
return false;
}
while (true) {
if (current.next(consumer)) {
return true;
}
if (current == first) {
current = second;
return true;
} else {
current = null;
return false;
}
}
}
@Override
protected int estimateSize() {

View File

@ -0,0 +1,35 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.longimpl;
import java.util.function.LongPredicate;
public class TAllMatchConsumer implements LongPredicate {
public boolean matched = true;
private LongPredicate predicate;
public TAllMatchConsumer(LongPredicate predicate) {
this.predicate = predicate;
}
@Override
public boolean test(long t) {
if (!predicate.test(t)) {
matched = false;
}
return matched;
}
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream.longimpl;
import java.util.function.LongPredicate;
public class TAnyMatchConsumer implements LongPredicate {
public boolean matched;
private LongPredicate predicate;
public TAnyMatchConsumer(LongPredicate predicate) {
this.predicate = predicate;
}
@Override
public boolean test(long t) {
matched = predicate.test(t);
return !matched;
}
}

View File

@ -30,6 +30,6 @@ public class TEmptyLongStreamImpl extends TSimpleLongStreamImpl {
@Override
public long count() {
return 1;
return 0;
}
}

View File

@ -22,6 +22,7 @@ import org.teavm.classlib.java.util.stream.TLongStream;
public class TFlatMappingLongStreamImpl extends TSimpleLongStreamImpl {
private TSimpleLongStreamImpl sourceStream;
private boolean currentSet;
private TLongStream current;
private PrimitiveIterator.OfLong iterator;
private LongFunction<? extends TLongStream> mapper;
@ -34,25 +35,27 @@ public class TFlatMappingLongStreamImpl extends TSimpleLongStreamImpl {
@Override
public boolean next(LongPredicate consumer) {
while (true) {
if (current == null) {
if (done) {
return false;
}
currentSet = false;
while (!currentSet) {
boolean hasMore = sourceStream.next(e -> {
current = mapper.apply(e);
currentSet = true;
return false;
});
if (!hasMore) {
done = true;
break;
}
}
if (current == null) {
done = true;
return false;
}
}
if (current instanceof TSimpleLongStreamImpl) {
@SuppressWarnings("unchecked")
TSimpleLongStreamImpl castCurrent = (TSimpleLongStreamImpl) current;
if (castCurrent.next(consumer)) {
return true;
@ -61,7 +64,7 @@ public class TFlatMappingLongStreamImpl extends TSimpleLongStreamImpl {
} else {
iterator = current.iterator();
while (iterator.hasNext()) {
long e = iterator.nextLong();
long e = iterator.next();
if (!consumer.test(e)) {
return true;
}
@ -69,7 +72,7 @@ public class TFlatMappingLongStreamImpl extends TSimpleLongStreamImpl {
iterator = null;
current = null;
}
}
return true;
}
@Override

View File

@ -102,10 +102,15 @@ public abstract class TSimpleLongStreamImpl implements TLongStream {
@Override
public void forEachOrdered(LongConsumer action) {
next(e -> {
while (true) {
boolean hasMore = next(e -> {
action.accept(e);
return true;
});
if (!hasMore) {
return;
}
}
}
@Override
@ -113,7 +118,9 @@ public abstract class TSimpleLongStreamImpl implements TLongStream {
int estimatedSize = estimateSize();
if (estimatedSize < 0) {
List<Long> list = new ArrayList<>();
next(list::add);
while (next(list::add)) {
// go on
}
long[] array = new long[list.size()];
for (int i = 0; i < array.length; ++i) {
array[i] = list.get(i);
@ -122,8 +129,9 @@ public abstract class TSimpleLongStreamImpl implements TLongStream {
} else {
long[] array = new long[estimatedSize];
ArrayFillingConsumer consumer = new ArrayFillingConsumer(array);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have reported done status";
while (next(consumer)) {
// go on
}
if (consumer.index < array.length) {
array = Arrays.copyOf(array, consumer.index);
}
@ -134,26 +142,33 @@ public abstract class TSimpleLongStreamImpl implements TLongStream {
@Override
public long reduce(long identity, LongBinaryOperator accumulator) {
TReducingLongConsumer consumer = new TReducingLongConsumer(accumulator, identity, true);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.result;
}
@Override
public OptionalLong reduce(LongBinaryOperator accumulator) {
TReducingLongConsumer consumer = new TReducingLongConsumer(accumulator, 0, false);
boolean wantsMore = next(consumer);
assert !wantsMore : "next() should have returned true";
while (next(consumer)) {
// go on
}
return consumer.initialized ? OptionalLong.of(consumer.result) : OptionalLong.empty();
}
@Override
public <R> R collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer<R, R> combiner) {
R collection = supplier.get();
next(e -> {
while (true) {
boolean hasMore = next(e -> {
accumulator.accept(collection, e);
return true;
});
if (!hasMore) {
break;
}
}
return collection;
}
@ -170,32 +185,46 @@ public abstract class TSimpleLongStreamImpl implements TLongStream {
@Override
public long count() {
TCountingLongConsumer consumer = new TCountingLongConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.count;
}
@Override
public long sum() {
TSumLongConsumer consumer = new TSumLongConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.sum;
}
@Override
public OptionalDouble average() {
TSumLongAsDoubleConsumer consumer = new TSumLongAsDoubleConsumer();
next(consumer);
while (next(consumer)) {
// go on
}
return consumer.count > 0 ? OptionalDouble.of(consumer.sum / consumer.count) : OptionalDouble.empty();
}
@Override
public boolean anyMatch(LongPredicate predicate) {
return next(predicate.negate());
TAnyMatchConsumer consumer = new TAnyMatchConsumer(predicate);
while (!consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
public boolean allMatch(LongPredicate predicate) {
return !next(predicate);
TAllMatchConsumer consumer = new TAllMatchConsumer(predicate);
while (consumer.matched && next(consumer)) {
// go on
}
return consumer.matched;
}
@Override
@ -206,7 +235,9 @@ public abstract class TSimpleLongStreamImpl implements TLongStream {
@Override
public OptionalLong findFirst() {
TFindFirstLongConsumer consumer = new TFindFirstLongConsumer();
next(consumer);
while (!consumer.hasAny && next(consumer)) {
// go on
}
return consumer.hasAny ? OptionalLong.of(consumer.result) : OptionalLong.empty();
}
@ -270,7 +301,7 @@ public abstract class TSimpleLongStreamImpl implements TLongStream {
public abstract boolean next(LongPredicate consumer);
class ArrayFillingConsumer implements LongPredicate {
static class ArrayFillingConsumer implements LongPredicate {
long[] array;
int index;

View File

@ -53,13 +53,21 @@ public class TSimpleLongStreamIterator implements PrimitiveIterator.OfLong {
if (state != NEEDS_MORE) {
return;
}
state = NEEDS_MORE;
while (state == NEEDS_MORE) {
boolean hasMore = stream.next(e -> {
lastElement = e;
state = HAS_DATA;
return false;
});
state = hasMore ? HAS_DATA : LAST_ELEMENT;
if (state == LAST_ELEMENT) {
if (!hasMore) {
if (state == NEEDS_MORE) {
state = DONE;
} else {
state = LAST_ELEMENT;
}
stream = null;
}
}
}
}

View File

@ -20,6 +20,7 @@ import java.util.function.LongConsumer;
public class TSimpleLongStreamSpliterator implements Spliterator.OfLong {
private TSimpleLongStreamImpl stream;
private boolean foundItems;
private boolean done;
public TSimpleLongStreamSpliterator(TSimpleLongStreamImpl stream) {
@ -39,10 +40,14 @@ public class TSimpleLongStreamSpliterator implements Spliterator.OfLong {
if (done) {
return false;
}
foundItems = false;
while (!foundItems && !done) {
done = !stream.next(x -> {
action.accept(x);
foundItems = true;
return false;
});
}
return true;
}

View File

@ -30,7 +30,7 @@ public class TSkippingLongStreamImpl extends TSimpleLongStreamImpl {
@Override
public boolean next(LongPredicate consumer) {
if (remaining > 0) {
while (remaining > 0) {
if (!sourceStream.next(e -> --remaining > 0)) {
return false;
}

View File

@ -33,18 +33,17 @@ public class TSpecializedConcatLongStream extends TSimpleLongStreamImpl {
if (current == null) {
return false;
}
while (true) {
if (current.next(consumer)) {
return true;
}
if (current == first) {
current = second;
return true;
} else {
current = null;
return false;
}
}
}
@Override
protected int estimateSize() {

View File

@ -19,13 +19,15 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.teavm.classlib.java.util.stream.Helper.appendDoubleNumbersTo;
import static org.teavm.classlib.java.util.stream.Helper.testDoubleStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntegerStream;
import static org.teavm.classlib.java.util.stream.Helper.testLongStream;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.LongStream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.teavm.junit.TeaVMTestRunner;
@ -34,85 +36,94 @@ import org.teavm.junit.TeaVMTestRunner;
public class DoubleStreamTest {
@Test
public void forEachWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(1, 2, 3).forEach(appendNumbersTo(sb));
assertEquals("1.0;2.0;3.0;", sb.toString());
testDoubleStream(() -> DoubleStream.of(1, 2, 3), 1, 2, 3);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.of(1), DoubleStream.of(2, 3)), 1, 2, 3);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.empty(), DoubleStream.of(1, 2, 3)), 1, 2, 3);
}
@Test
public void mapWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(1, 2, 3).map(n -> n * n).forEach(appendNumbersTo(sb));
assertEquals("1.0;4.0;9.0;", sb.toString());
testDoubleStream(() -> DoubleStream.of(1, 2, 3).map(n -> n * n), 1, 4, 9);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.of(1), DoubleStream.of(2, 3))
.map(n -> n * n), 1, 4, 9);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.empty(), DoubleStream.of(1, 2, 3))
.map(n -> n * n), 1, 4, 9);
}
@Test
public void mapToObjWorks() {
String result = DoubleStream.of(1, 2, 3).mapToObj(n -> String.valueOf(n * n)).collect(Collectors.joining(";"));
assertEquals("1.0;4.0;9.0", result);
testIntegerStream(() -> DoubleStream.of(1, 2, 3).mapToObj(n -> (int) (n * n)), 1, 4, 9);
testIntegerStream(() -> DoubleStream.concat(DoubleStream.of(1), DoubleStream.of(2, 3))
.mapToObj(n -> (int) (n * n)), 1, 4, 9);
testIntegerStream(() -> DoubleStream.concat(DoubleStream.empty(), DoubleStream.of(1, 2, 3))
.mapToObj(n -> (int) (n * n)), 1, 4, 9);
}
@Test
public void mapToIntWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(1, 2, 3).mapToInt(n -> (int) (n * n)).forEach(appendIntNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testIntStream(() -> DoubleStream.of(1, 2, 3).mapToInt(n -> (int) (n * n)), 1, 4, 9);
testIntStream(() -> DoubleStream.concat(DoubleStream.of(1), DoubleStream.of(2, 3))
.mapToInt(n -> (int) (n * n)), 1, 4, 9);
testIntStream(() -> DoubleStream.concat(DoubleStream.empty(), DoubleStream.of(1, 2, 3))
.mapToInt(n -> (int) (n * n)), 1, 4, 9);
}
@Test
public void mapToLongWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(1, 2, 3).mapToLong(n -> (long) (n * n)).forEach(appendLongNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testLongStream(() -> DoubleStream.of(1, 2, 3).mapToLong(n -> (long) (n * n)), 1, 4, 9);
testLongStream(() -> DoubleStream.concat(DoubleStream.of(1), DoubleStream.of(2, 3))
.mapToLong(n -> (long) (n * n)), 1, 4, 9);
testLongStream(() -> DoubleStream.concat(DoubleStream.empty(), DoubleStream.of(1, 2, 3))
.mapToLong(n -> (long) (n * n)), 1, 4, 9);
}
@Test
public void filterWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(1, 2, 3, 4, 5, 6).filter(n -> (n % 2) == 0).forEach(appendNumbersTo(sb));
assertEquals("2.0;4.0;6.0;", sb.toString());
testDoubleStream(() -> DoubleStream.of(1, 2, 3, 4, 5, 6).filter(n -> (n % 2) == 0), 2, 4, 6);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.of(1), DoubleStream.of(2, 3, 4, 5, 6))
.filter(n -> ((int) n & 1) == 0), 2, 4, 6);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.empty(), DoubleStream.of(1, 2, 3, 4, 5, 6))
.filter(n -> ((int) n & 1) == 0), 2, 4, 6);
}
@Test
public void flatMapWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(1, 3).flatMap(n -> DoubleStream.of(n, n + 1)).forEach(appendNumbersTo(sb));
assertEquals("1.0;2.0;3.0;4.0;", sb.toString());
testDoubleStream(() -> DoubleStream.of(1, 3).flatMap(n -> DoubleStream.of(n, n + 1)), 1, 2, 3, 4);
testDoubleStream(() -> DoubleStream.of(1, 3).flatMap(n -> DoubleStream.of(n, n + 1)).skip(1), 2, 3, 4);
testDoubleStream(() -> DoubleStream.of(1, 4).flatMap(n -> DoubleStream.of(n, n + 1, n + 2)).skip(3), 4, 5, 6);
sb.setLength(0);
DoubleStream.of(1, 3).flatMap(n -> DoubleStream.of(n, n + 1)).skip(1).forEach(appendNumbersTo(sb));
assertEquals("2.0;3.0;4.0;", sb.toString());
sb.setLength(0);
DoubleStream.of(1, 4).flatMap(n -> DoubleStream.of(n, n + 1, n + 2)).skip(4).forEach(appendNumbersTo(sb));
assertEquals("5.0;6.0;", sb.toString());
testDoubleStream(() -> DoubleStream.of(1, 3, 100)
.flatMap(n -> n < 100 ? DoubleStream.of(n, n + 1) : DoubleStream.empty()), 1, 2, 3, 4);
testDoubleStream(() -> DoubleStream.of(100, 1, 3)
.flatMap(n -> n < 100 ? DoubleStream.of(n, n + 1) : DoubleStream.empty()), 1, 2, 3, 4);
}
@Test
public void skipWorks() {
for (int i = 0; i <= 6; ++i) {
StringBuilder sb = new StringBuilder();
DoubleStream.iterate(1, n -> n + 1).limit(5).skip(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int i = 0; i <= 5; ++i) {
int index = i;
double[] expected = new double[5 - i];
for (int j = i; j < 5; ++j) {
expected.append((double) j + 1).append(';');
expected[j - i] = j + 1;
}
assertEquals("Error skipping " + i + " elements", expected.toString(), sb.toString());
testDoubleStream(() -> DoubleStream.iterate(1, n -> n + 1).limit(5).skip(index), expected);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.of(1), DoubleStream.iterate(2, n -> n + 1)
.limit(4)).skip(index), expected);
testDoubleStream(() -> DoubleStream.concat(DoubleStream.empty(), DoubleStream.iterate(1, n -> n + 1)
.limit(5)).skip(index), expected);
}
}
@Test
public void limitWorks() {
for (int i = 0; i <= 3; ++i) {
StringBuilder sb = new StringBuilder();
DoubleStream.iterate(1, n -> n + 1).limit(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int j = 0; j < i; ++j) {
expected.append((double) j + 1).append(';');
int index = i;
long[] expected = new long[i];
for (int j = 0; j < expected.length; ++j) {
expected[j] = j + 1;
}
assertEquals("Error limiting to " + i + " elements", expected.toString(), sb.toString());
testLongStream(() -> LongStream.iterate(1, n -> n + 1).limit(index), expected);
}
}
@ -135,19 +146,19 @@ public class DoubleStreamTest {
@Test
public void distinctWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(2, 3, 2, 3).distinct().forEach(appendNumbersTo(sb));
DoubleStream.of(2, 3, 2, 3).distinct().forEach(appendDoubleNumbersTo(sb));
assertEquals("2.0;3.0;", sb.toString());
sb.setLength(0);
DoubleStream.of(2, 3, 2, 3).skip(1).distinct().forEach(appendNumbersTo(sb));
DoubleStream.of(2, 3, 2, 3).skip(1).distinct().forEach(appendDoubleNumbersTo(sb));
assertEquals("3.0;2.0;", sb.toString());
sb.setLength(0);
DoubleStream.of(2, 3, 2, 3).limit(2).distinct().forEach(appendNumbersTo(sb));
DoubleStream.of(2, 3, 2, 3).limit(2).distinct().forEach(appendDoubleNumbersTo(sb));
assertEquals("2.0;3.0;", sb.toString());
sb.setLength(0);
DoubleStream.of(2, 2, 3, 2, 4, 3, 1).distinct().forEach(appendNumbersTo(sb));
DoubleStream.of(2, 2, 3, 2, 4, 3, 1).distinct().forEach(appendDoubleNumbersTo(sb));
assertEquals("2.0;3.0;4.0;1.0;", sb.toString());
}
@ -164,22 +175,22 @@ public class DoubleStreamTest {
@Test
public void concatWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.concat(DoubleStream.of(1, 2), DoubleStream.of(3, 4)).forEach(appendNumbersTo(sb));
DoubleStream.concat(DoubleStream.of(1, 2), DoubleStream.of(3, 4)).forEach(appendDoubleNumbersTo(sb));
assertEquals("1.0;2.0;3.0;4.0;", sb.toString());
sb.setLength(0);
DoubleStream.concat(DoubleStream.of(1, 2), DoubleStream.of(3, 4)).skip(1).forEach(appendNumbersTo(sb));
DoubleStream.concat(DoubleStream.of(1, 2), DoubleStream.of(3, 4)).skip(1).forEach(appendDoubleNumbersTo(sb));
assertEquals("2.0;3.0;4.0;", sb.toString());
sb.setLength(0);
DoubleStream.concat(DoubleStream.of(1, 2), DoubleStream.of(3, 4, 5)).skip(3).forEach(appendNumbersTo(sb));
DoubleStream.concat(DoubleStream.of(1, 2), DoubleStream.of(3, 4, 5)).skip(3).forEach(appendDoubleNumbersTo(sb));
assertEquals("4.0;5.0;", sb.toString());
}
@Test
public void peekWorks() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(1, 2, 3).peek(appendNumbersTo(sb)).map(n -> n + 10).forEach(appendNumbersTo(sb));
DoubleStream.of(1, 2, 3).peek(appendDoubleNumbersTo(sb)).map(n -> n + 10).forEach(appendDoubleNumbersTo(sb));
assertEquals("1.0;11.0;2.0;12.0;3.0;13.0;", sb.toString());
}
@ -196,31 +207,31 @@ public class DoubleStreamTest {
@Test
public void streamOfOneElement() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(5).forEach(appendNumbersTo(sb));
DoubleStream.of(5).forEach(appendDoubleNumbersTo(sb));
assertEquals("5.0;", sb.toString());
sb.setLength(0);
DoubleStream.of(5).skip(1).forEach(appendNumbersTo(sb));
DoubleStream.of(5).skip(1).forEach(appendDoubleNumbersTo(sb));
assertEquals("", sb.toString());
sb.setLength(0);
DoubleStream.concat(DoubleStream.of(5), DoubleStream.of(6)).forEach(appendNumbersTo(sb));
DoubleStream.concat(DoubleStream.of(5), DoubleStream.of(6)).forEach(appendDoubleNumbersTo(sb));
assertEquals("5.0;6.0;", sb.toString());
}
@Test
public void sortedStream() {
StringBuilder sb = new StringBuilder();
DoubleStream.of(5, 7, 1, 2, 4, 3).sorted().forEach(appendNumbersTo(sb));
DoubleStream.of(5, 7, 1, 2, 4, 3).sorted().forEach(appendDoubleNumbersTo(sb));
assertEquals("1.0;2.0;3.0;4.0;5.0;7.0;", sb.toString());
sb.setLength(0);
DoubleStream.of(2, 3, 1).peek(appendNumbersTo(sb)).sorted().limit(2).map(n -> n + 10)
.forEach(appendNumbersTo(sb));
DoubleStream.of(2, 3, 1).peek(appendDoubleNumbersTo(sb)).sorted().limit(2).map(n -> n + 10)
.forEach(appendDoubleNumbersTo(sb));
assertEquals("2.0;3.0;1.0;11.0;12.0;", sb.toString());
sb.setLength(0);
DoubleStream.of(2, 3, 1).peek(appendNumbersTo(sb)).sorted().limit(0).forEach(appendNumbersTo(sb));
DoubleStream.of(2, 3, 1).peek(appendDoubleNumbersTo(sb)).sorted().limit(0).forEach(appendDoubleNumbersTo(sb));
assertEquals("2.0;3.0;1.0;", sb.toString());
}
@ -299,7 +310,7 @@ public class DoubleStreamTest {
sb.setLength(0);
iterator = DoubleStream.of(1, 2, 3).iterator();
iterator.forEachRemaining(appendNumbersTo(sb));
iterator.forEachRemaining(appendDoubleNumbersTo(sb));
assertEquals("1.0;2.0;3.0;", sb.toString());
}
@ -307,14 +318,14 @@ public class DoubleStreamTest {
public void spliterator() {
StringBuilder sb = new StringBuilder();
Spliterator.OfDouble spliterator = DoubleStream.of(1, 2, 3).spliterator();
while (spliterator.tryAdvance(appendNumbersTo(sb))) {
while (spliterator.tryAdvance(appendDoubleNumbersTo(sb))) {
// continue
}
assertEquals("1.0;2.0;3.0;", sb.toString());
sb.setLength(0);
spliterator = DoubleStream.of(1, 2, 3).spliterator();
spliterator.forEachRemaining(appendNumbersTo(sb));
spliterator.forEachRemaining(appendDoubleNumbersTo(sb));
assertEquals("1.0;2.0;3.0;", sb.toString());
}
@ -323,16 +334,4 @@ public class DoubleStreamTest {
assertEquals(2.5, DoubleStream.of(1, 2, 3, 4).average().getAsDouble(), 0.001);
assertFalse(DoubleStream.empty().average().isPresent());
}
private DoubleConsumer appendNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private IntConsumer appendIntNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private LongConsumer appendLongNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
}

View File

@ -0,0 +1,208 @@
/*
* Copyright 2019 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.util.stream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Iterator;
import java.util.PrimitiveIterator;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import java.util.function.Supplier;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
final class Helper {
private Helper() {
}
static void testIntegerStream(Supplier<Stream<Integer>> streamSupplier, Integer... expected) {
StringBuilder sb = new StringBuilder();
for (Integer e : expected) {
sb.append(e).append(';');
}
String expectedText = sb.toString();
sb.setLength(0);
streamSupplier.get().forEach(appendNumbersTo(sb));
assertEquals(expectedText, sb.toString());
sb.setLength(0);
Iterator<Integer> iter = streamSupplier.get().iterator();
while (iter.hasNext()) {
sb.append(iter.next()).append(';');
}
assertEquals(expectedText, sb.toString());
assertEquals(expected.length, streamSupplier.get().count());
if (expected.length > 0) {
int max = expected[0];
for (Integer e : expected) {
max = Math.max(max, e);
}
int notInCollection = max + 1;
int inCollection = expected[0];
assertTrue(streamSupplier.get().allMatch(e -> e < notInCollection));
assertFalse(streamSupplier.get().allMatch(e -> e < inCollection));
assertTrue(streamSupplier.get().anyMatch(e -> e == inCollection));
assertFalse(streamSupplier.get().anyMatch(e -> e == notInCollection));
} else {
assertTrue(streamSupplier.get().allMatch(e -> false));
assertTrue(streamSupplier.get().allMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> false));
}
}
static void testIntStream(Supplier<IntStream> streamSupplier, int... expected) {
StringBuilder sb = new StringBuilder();
for (int e : expected) {
sb.append(e).append(';');
}
String expectedText = sb.toString();
sb.setLength(0);
streamSupplier.get().forEach(appendIntNumbersTo(sb));
assertEquals(expectedText, sb.toString());
sb.setLength(0);
PrimitiveIterator.OfInt iter = streamSupplier.get().iterator();
while (iter.hasNext()) {
sb.append(iter.next()).append(';');
}
assertEquals(expectedText, sb.toString());
assertEquals(expected.length, streamSupplier.get().count());
if (expected.length > 0) {
int max = expected[0];
for (int e : expected) {
max = Math.max(max, e);
}
int notInCollection = max + 1;
int inCollection = expected[0];
assertTrue(streamSupplier.get().allMatch(e -> e < notInCollection));
assertFalse(streamSupplier.get().allMatch(e -> e < inCollection));
assertTrue(streamSupplier.get().anyMatch(e -> e == inCollection));
assertFalse(streamSupplier.get().anyMatch(e -> e == notInCollection));
} else {
assertTrue(streamSupplier.get().allMatch(e -> false));
assertTrue(streamSupplier.get().allMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> false));
}
}
static void testLongStream(Supplier<LongStream> streamSupplier, long... expected) {
StringBuilder sb = new StringBuilder();
for (long e : expected) {
sb.append(e).append(';');
}
String expectedText = sb.toString();
sb.setLength(0);
streamSupplier.get().forEach(appendLongNumbersTo(sb));
assertEquals(expectedText, sb.toString());
sb.setLength(0);
PrimitiveIterator.OfLong iter = streamSupplier.get().iterator();
while (iter.hasNext()) {
sb.append(iter.next()).append(';');
}
assertEquals(expectedText, sb.toString());
assertEquals(expected.length, streamSupplier.get().count());
if (expected.length > 0) {
long max = expected[0];
for (long e : expected) {
max = Math.max(max, e);
}
long notInCollection = max + 1;
long inCollection = expected[0];
assertTrue(streamSupplier.get().allMatch(e -> e < notInCollection));
assertFalse(streamSupplier.get().allMatch(e -> e < inCollection));
assertTrue(streamSupplier.get().anyMatch(e -> e == inCollection));
assertFalse(streamSupplier.get().anyMatch(e -> e == notInCollection));
} else {
assertTrue(streamSupplier.get().allMatch(e -> false));
assertTrue(streamSupplier.get().allMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> false));
}
}
static void testDoubleStream(Supplier<DoubleStream> streamSupplier, double... expected) {
StringBuilder sb = new StringBuilder();
for (double e : expected) {
sb.append(e).append(';');
}
String expectedText = sb.toString();
sb.setLength(0);
streamSupplier.get().forEach(appendDoubleNumbersTo(sb));
assertEquals(expectedText, sb.toString());
sb.setLength(0);
PrimitiveIterator.OfDouble iter = streamSupplier.get().iterator();
while (iter.hasNext()) {
sb.append(iter.next()).append(';');
}
assertEquals(expectedText, sb.toString());
assertEquals(expected.length, streamSupplier.get().count());
if (expected.length > 0) {
double max = expected[0];
for (double e : expected) {
max = Math.max(max, e);
}
double notInCollection = max + 1;
double inCollection = expected[0];
assertTrue(streamSupplier.get().allMatch(e -> e < notInCollection));
assertFalse(streamSupplier.get().allMatch(e -> e < inCollection));
assertTrue(streamSupplier.get().anyMatch(e -> e == inCollection));
assertFalse(streamSupplier.get().anyMatch(e -> e == notInCollection));
} else {
assertTrue(streamSupplier.get().allMatch(e -> false));
assertTrue(streamSupplier.get().allMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> true));
assertFalse(streamSupplier.get().anyMatch(e -> false));
}
}
static Consumer<Integer> appendNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
static IntConsumer appendIntNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
static LongConsumer appendLongNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
static DoubleConsumer appendDoubleNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
}

View File

@ -19,12 +19,13 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.teavm.classlib.java.util.stream.Helper.appendIntNumbersTo;
import static org.teavm.classlib.java.util.stream.Helper.testDoubleStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntegerStream;
import static org.teavm.classlib.java.util.stream.Helper.testLongStream;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -34,85 +35,88 @@ import org.teavm.junit.TeaVMTestRunner;
public class IntStreamTest {
@Test
public void forEachWorks() {
StringBuilder sb = new StringBuilder();
IntStream.of(1, 2, 3).forEach(appendNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
testIntStream(() -> IntStream.of(1, 2, 3), 1, 2, 3);
testIntStream(() -> IntStream.concat(IntStream.of(1), IntStream.of(2, 3)), 1, 2, 3);
testIntStream(() -> IntStream.concat(IntStream.empty(), IntStream.of(1, 2, 3)), 1, 2, 3);
}
@Test
public void mapWorks() {
StringBuilder sb = new StringBuilder();
IntStream.of(1, 2, 3).map(n -> n * n).forEach(appendNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testIntStream(() -> IntStream.of(1, 2, 3).map(n -> n * n), 1, 4, 9);
testIntStream(() -> IntStream.concat(IntStream.of(1), IntStream.of(2, 3)).map(n -> n * n), 1, 4, 9);
testIntStream(() -> IntStream.concat(IntStream.empty(), IntStream.of(1, 2, 3)).map(n -> n * n), 1, 4, 9);
}
@Test
public void mapToObjWorks() {
String result = IntStream.of(1, 2, 3).mapToObj(n -> String.valueOf(n * n)).collect(Collectors.joining(";"));
assertEquals("1;4;9", result);
testIntegerStream(() -> IntStream.of(1, 2, 3).mapToObj(n -> n * n), 1, 4, 9);
testIntegerStream(() -> IntStream.concat(IntStream.of(1), IntStream.of(2, 3)).mapToObj(n -> n * n), 1, 4, 9);
testIntegerStream(() -> IntStream.concat(IntStream.empty(), IntStream.of(1, 2, 3))
.mapToObj(n -> n * n), 1, 4, 9);
}
@Test
public void mapToLongWorks() {
StringBuilder sb = new StringBuilder();
IntStream.of(1, 2, 3).mapToLong(n -> n * n).forEach(appendLongNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testLongStream(() -> IntStream.of(1, 2, 3).mapToLong(n -> n * n), 1, 4, 9);
testLongStream(() -> IntStream.concat(IntStream.of(1), IntStream.of(2, 3)).mapToLong(n -> n * n), 1, 4, 9);
testLongStream(() -> IntStream.concat(IntStream.empty(), IntStream.of(1, 2, 3)).mapToLong(n -> n * n), 1, 4, 9);
}
@Test
public void mapToDoubleWorks() {
StringBuilder sb = new StringBuilder();
IntStream.of(1, 2, 3).mapToDouble(n -> n * n).forEach(appendDoubleNumbersTo(sb));
assertEquals("1.0;4.0;9.0;", sb.toString());
testDoubleStream(() -> IntStream.of(1, 2, 3).mapToDouble(n -> n * n), 1, 4, 9);
testDoubleStream(() -> IntStream.concat(IntStream.of(1), IntStream.of(2, 3)).mapToDouble(n -> n * n), 1, 4, 9);
testDoubleStream(() -> IntStream.concat(IntStream.empty(), IntStream.of(1, 2, 3)).mapToDouble(n -> n * n),
1, 4, 9);
}
@Test
public void filterWorks() {
StringBuilder sb = new StringBuilder();
IntStream.of(1, 2, 3, 4, 5, 6).filter(n -> (n & 1) == 0).forEach(appendNumbersTo(sb));
assertEquals("2;4;6;", sb.toString());
testIntStream(() -> IntStream.of(1, 2, 3, 4, 5, 6).filter(n -> (n & 1) == 0), 2, 4, 6);
testIntStream(() -> IntStream.concat(IntStream.of(1), IntStream.of(2, 3, 4, 5, 6))
.filter(n -> (n & 1) == 0), 2, 4, 6);
testIntStream(() -> IntStream.concat(IntStream.empty(), IntStream.of(1, 2, 3, 4, 5, 6))
.filter(n -> (n & 1) == 0), 2, 4, 6);
}
@Test
public void flatMapWorks() {
StringBuilder sb = new StringBuilder();
IntStream.of(1, 3).flatMap(n -> IntStream.of(n, n + 1)).forEach(appendNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
testIntStream(() -> IntStream.of(1, 3).flatMap(n -> IntStream.of(n, n + 1)), 1, 2, 3, 4);
testIntStream(() -> IntStream.of(1, 3).flatMap(n -> IntStream.of(n, n + 1)).skip(1), 2, 3, 4);
testIntStream(() -> IntStream.of(1, 4).flatMap(n -> IntStream.of(n, n + 1, n + 2)).skip(3), 4, 5, 6);
sb.setLength(0);
IntStream.of(1, 3).flatMap(n -> IntStream.of(n, n + 1)).skip(1).forEach(appendNumbersTo(sb));
assertEquals("2;3;4;", sb.toString());
sb.setLength(0);
IntStream.of(1, 4).flatMap(n -> IntStream.of(n, n + 1, n + 2)).skip(4).forEach(appendNumbersTo(sb));
assertEquals("5;6;", sb.toString());
testIntStream(() -> IntStream.of(1, 3, 100)
.flatMap(n -> n < 100 ? IntStream.of(n, n + 1) : IntStream.empty()), 1, 2, 3, 4);
testIntStream(() -> IntStream.of(100, 1, 3)
.flatMap(n -> n < 100 ? IntStream.of(n, n + 1) : IntStream.empty()), 1, 2, 3, 4);
}
@Test
public void skipWorks() {
for (int i = 0; i <= 6; ++i) {
StringBuilder sb = new StringBuilder();
IntStream.iterate(1, n -> n + 1).limit(5).skip(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int i = 0; i <= 5; ++i) {
int index = i;
int[] expected = new int[5 - i];
for (int j = i; j < 5; ++j) {
expected.append(j + 1).append(';');
expected[j - i] = j + 1;
}
assertEquals("Error skipping " + i + " elements", expected.toString(), sb.toString());
testIntStream(() -> IntStream.iterate(1, n -> n + 1).limit(5).skip(index), expected);
testIntStream(() -> IntStream.concat(IntStream.of(1), IntStream.iterate(2, n -> n + 1).limit(4))
.skip(index), expected);
testIntStream(() -> IntStream.concat(IntStream.empty(), IntStream.iterate(1, n -> n + 1).limit(5))
.skip(index), expected);
}
}
@Test
public void limitWorks() {
for (int i = 0; i <= 3; ++i) {
StringBuilder sb = new StringBuilder();
IntStream.iterate(1, n -> n + 1).limit(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int j = 0; j < i; ++j) {
expected.append(j + 1).append(';');
int index = i;
int[] expected = new int[i];
for (int j = 0; j < expected.length; ++j) {
expected[j] = j + 1;
}
assertEquals("Error limiting to " + i + " elements", expected.toString(), sb.toString());
testIntStream(() -> IntStream.iterate(1, n -> n + 1).limit(index), expected);
}
}
@ -153,22 +157,22 @@ public class IntStreamTest {
@Test
public void concatWorks() {
StringBuilder sb = new StringBuilder();
IntStream.concat(IntStream.of(1, 2), IntStream.of(3, 4)).forEach(appendNumbersTo(sb));
IntStream.concat(IntStream.of(1, 2), IntStream.of(3, 4)).forEach(appendIntNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
sb.setLength(0);
IntStream.concat(IntStream.of(1, 2), IntStream.of(3, 4)).skip(1).forEach(appendNumbersTo(sb));
IntStream.concat(IntStream.of(1, 2), IntStream.of(3, 4)).skip(1).forEach(appendIntNumbersTo(sb));
assertEquals("2;3;4;", sb.toString());
sb.setLength(0);
IntStream.concat(IntStream.of(1, 2), IntStream.of(3, 4, 5)).skip(3).forEach(appendNumbersTo(sb));
IntStream.concat(IntStream.of(1, 2), IntStream.of(3, 4, 5)).skip(3).forEach(appendIntNumbersTo(sb));
assertEquals("4;5;", sb.toString());
}
@Test
public void peekWorks() {
StringBuilder sb = new StringBuilder();
IntStream.of(1, 2, 3).peek(appendNumbersTo(sb)).map(n -> n + 10).forEach(appendNumbersTo(sb));
IntStream.of(1, 2, 3).peek(appendIntNumbersTo(sb)).map(n -> n + 10).forEach(appendIntNumbersTo(sb));
assertEquals("1;11;2;12;3;13;", sb.toString());
}
@ -185,30 +189,31 @@ public class IntStreamTest {
@Test
public void streamOfOneElement() {
StringBuilder sb = new StringBuilder();
IntStream.of(5).forEach(appendNumbersTo(sb));
IntStream.of(5).forEach(appendIntNumbersTo(sb));
assertEquals("5;", sb.toString());
sb.setLength(0);
IntStream.of(5).skip(1).forEach(appendNumbersTo(sb));
IntStream.of(5).skip(1).forEach(appendIntNumbersTo(sb));
assertEquals("", sb.toString());
sb.setLength(0);
IntStream.concat(IntStream.of(5), IntStream.of(6)).forEach(appendNumbersTo(sb));
IntStream.concat(IntStream.of(5), IntStream.of(6)).forEach(appendIntNumbersTo(sb));
assertEquals("5;6;", sb.toString());
}
@Test
public void sortedStream() {
StringBuilder sb = new StringBuilder();
IntStream.of(5, 7, 1, 2, 4, 3).sorted().forEach(appendNumbersTo(sb));
IntStream.of(5, 7, 1, 2, 4, 3).sorted().forEach(appendIntNumbersTo(sb));
assertEquals("1;2;3;4;5;7;", sb.toString());
sb.setLength(0);
IntStream.of(2, 3, 1).peek(appendNumbersTo(sb)).sorted().limit(2).map(n -> n + 10).forEach(appendNumbersTo(sb));
IntStream.of(2, 3, 1).peek(appendIntNumbersTo(sb)).sorted().limit(2).map(n -> n + 10)
.forEach(appendIntNumbersTo(sb));
assertEquals("2;3;1;11;12;", sb.toString());
sb.setLength(0);
IntStream.of(2, 3, 1).peek(appendNumbersTo(sb)).sorted().limit(0).forEach(appendNumbersTo(sb));
IntStream.of(2, 3, 1).peek(appendIntNumbersTo(sb)).sorted().limit(0).forEach(appendIntNumbersTo(sb));
assertEquals("2;3;1;", sb.toString());
}
@ -287,7 +292,7 @@ public class IntStreamTest {
sb.setLength(0);
iterator = IntStream.of(1, 2, 3).iterator();
iterator.forEachRemaining(appendNumbersTo(sb));
iterator.forEachRemaining(appendIntNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
}
@ -295,14 +300,14 @@ public class IntStreamTest {
public void spliterator() {
StringBuilder sb = new StringBuilder();
Spliterator.OfInt spliterator = IntStream.of(1, 2, 3).spliterator();
while (spliterator.tryAdvance(appendNumbersTo(sb))) {
while (spliterator.tryAdvance(appendIntNumbersTo(sb))) {
// continue
}
assertEquals("1;2;3;", sb.toString());
sb.setLength(0);
spliterator = IntStream.of(1, 2, 3).spliterator();
spliterator.forEachRemaining(appendNumbersTo(sb));
spliterator.forEachRemaining(appendIntNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
}
@ -315,23 +320,11 @@ public class IntStreamTest {
@Test
public void range() {
StringBuilder sb = new StringBuilder();
IntStream.range(1, 4).forEach(appendNumbersTo(sb));
IntStream.range(1, 4).forEach(appendIntNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
sb.setLength(0);
IntStream.rangeClosed(1, 4).forEach(appendNumbersTo(sb));
IntStream.rangeClosed(1, 4).forEach(appendIntNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
}
private IntConsumer appendNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private LongConsumer appendLongNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private DoubleConsumer appendDoubleNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
}

View File

@ -19,12 +19,13 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.teavm.classlib.java.util.stream.Helper.appendLongNumbersTo;
import static org.teavm.classlib.java.util.stream.Helper.testDoubleStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntegerStream;
import static org.teavm.classlib.java.util.stream.Helper.testLongStream;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -34,85 +35,92 @@ import org.teavm.junit.TeaVMTestRunner;
public class LongStreamTest {
@Test
public void forEachWorks() {
StringBuilder sb = new StringBuilder();
LongStream.of(1, 2, 3).forEach(appendNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
testLongStream(() -> LongStream.of(1, 2, 3), 1, 2, 3);
testLongStream(() -> LongStream.concat(LongStream.of(1), LongStream.of(2, 3)), 1, 2, 3);
testLongStream(() -> LongStream.concat(LongStream.empty(), LongStream.of(1, 2, 3)), 1, 2, 3);
}
@Test
public void mapWorks() {
StringBuilder sb = new StringBuilder();
LongStream.of(1, 2, 3).map(n -> n * n).forEach(appendNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testLongStream(() -> LongStream.of(1, 2, 3).map(n -> n * n), 1, 4, 9);
testLongStream(() -> LongStream.concat(LongStream.of(1), LongStream.of(2, 3)).map(n -> n * n), 1, 4, 9);
testLongStream(() -> LongStream.concat(LongStream.empty(), LongStream.of(1, 2, 3)).map(n -> n * n), 1, 4, 9);
}
@Test
public void mapToObjWorks() {
String result = LongStream.of(1, 2, 3).mapToObj(n -> String.valueOf(n * n)).collect(Collectors.joining(";"));
assertEquals("1;4;9", result);
testIntegerStream(() -> LongStream.of(1, 2, 3).mapToObj(n -> (int) (n * n)), 1, 4, 9);
testIntegerStream(() -> LongStream.concat(LongStream.of(1), LongStream.of(2, 3))
.mapToObj(n -> (int) (n * n)), 1, 4, 9);
testIntegerStream(() -> LongStream.concat(LongStream.empty(), LongStream.of(1, 2, 3))
.mapToObj(n -> (int) (n * n)), 1, 4, 9);
}
@Test
public void mapToIntWorks() {
StringBuilder sb = new StringBuilder();
LongStream.of(1, 2, 3).mapToInt(n -> (int) (n * n)).forEach(appendIntNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testIntStream(() -> LongStream.of(1, 2, 3).mapToInt(n -> (int) (n * n)), 1, 4, 9);
testIntStream(() -> LongStream.concat(LongStream.of(1), LongStream.of(2, 3))
.mapToInt(n -> (int) (n * n)), 1, 4, 9);
testIntStream(() -> LongStream.concat(LongStream.empty(), LongStream.of(1, 2, 3))
.mapToInt(n -> (int) (n * n)), 1, 4, 9);
}
@Test
public void mapToDoubleWorks() {
StringBuilder sb = new StringBuilder();
LongStream.of(1, 2, 3).mapToDouble(n -> n * n).forEach(appendDoubleNumbersTo(sb));
assertEquals("1.0;4.0;9.0;", sb.toString());
testDoubleStream(() -> LongStream.of(1, 2, 3).mapToDouble(n -> n * n), 1, 4, 9);
testDoubleStream(() -> LongStream.concat(LongStream.of(1), LongStream.of(2, 3)).mapToDouble(n -> n * n),
1, 4, 9);
testDoubleStream(() -> LongStream.concat(LongStream.empty(), LongStream.of(1, 2, 3)).mapToDouble(n -> n * n),
1, 4, 9);
}
@Test
public void filterWorks() {
StringBuilder sb = new StringBuilder();
LongStream.of(1, 2, 3, 4, 5, 6).filter(n -> (n & 1) == 0).forEach(appendNumbersTo(sb));
assertEquals("2;4;6;", sb.toString());
testLongStream(() -> LongStream.of(1, 2, 3, 4, 5, 6).filter(n -> (n & 1) == 0), 2, 4, 6);
testLongStream(() -> LongStream.concat(LongStream.of(1), LongStream.of(2, 3, 4, 5, 6))
.filter(n -> (n & 1) == 0), 2, 4, 6);
testLongStream(() -> LongStream.concat(LongStream.empty(), LongStream.of(1, 2, 3, 4, 5, 6))
.filter(n -> (n & 1) == 0), 2, 4, 6);
}
@Test
public void flatMapWorks() {
StringBuilder sb = new StringBuilder();
LongStream.of(1, 3).flatMap(n -> LongStream.of(n, n + 1)).forEach(appendNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
testLongStream(() -> LongStream.of(1, 3).flatMap(n -> LongStream.of(n, n + 1)), 1, 2, 3, 4);
testLongStream(() -> LongStream.of(1, 3).flatMap(n -> LongStream.of(n, n + 1)).skip(1), 2, 3, 4);
testLongStream(() -> LongStream.of(1, 4).flatMap(n -> LongStream.of(n, n + 1, n + 2)).skip(3), 4, 5, 6);
sb.setLength(0);
LongStream.of(1, 3).flatMap(n -> LongStream.of(n, n + 1)).skip(1).forEach(appendNumbersTo(sb));
assertEquals("2;3;4;", sb.toString());
sb.setLength(0);
LongStream.of(1, 4).flatMap(n -> LongStream.of(n, n + 1, n + 2)).skip(4).forEach(appendNumbersTo(sb));
assertEquals("5;6;", sb.toString());
testLongStream(() -> LongStream.of(1, 3, 100)
.flatMap(n -> n < 100 ? LongStream.of(n, n + 1) : LongStream.empty()), 1, 2, 3, 4);
testLongStream(() -> LongStream.of(100, 1, 3)
.flatMap(n -> n < 100 ? LongStream.of(n, n + 1) : LongStream.empty()), 1, 2, 3, 4);
}
@Test
public void skipWorks() {
for (int i = 0; i <= 6; ++i) {
StringBuilder sb = new StringBuilder();
LongStream.iterate(1, n -> n + 1).limit(5).skip(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int i = 0; i <= 5; ++i) {
int index = i;
long[] expected = new long[5 - i];
for (int j = i; j < 5; ++j) {
expected.append(j + 1).append(';');
expected[j - i] = j + 1;
}
assertEquals("Error skipping " + i + " elements", expected.toString(), sb.toString());
testLongStream(() -> LongStream.iterate(1, n -> n + 1).limit(5).skip(index), expected);
testLongStream(() -> LongStream.concat(LongStream.of(1), LongStream.iterate(2, n -> n + 1).limit(4))
.skip(index), expected);
testLongStream(() -> LongStream.concat(LongStream.empty(), LongStream.iterate(1, n -> n + 1).limit(5))
.skip(index), expected);
}
}
@Test
public void limitWorks() {
for (int i = 0; i <= 3; ++i) {
StringBuilder sb = new StringBuilder();
LongStream.iterate(1, n -> n + 1).limit(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int j = 0; j < i; ++j) {
expected.append(j + 1).append(';');
int index = i;
long[] expected = new long[i];
for (int j = 0; j < expected.length; ++j) {
expected[j] = j + 1;
}
assertEquals("Error limiting to " + i + " elements", expected.toString(), sb.toString());
testLongStream(() -> LongStream.iterate(1, n -> n + 1).limit(index), expected);
}
}
@ -153,22 +161,22 @@ public class LongStreamTest {
@Test
public void concatWorks() {
StringBuilder sb = new StringBuilder();
LongStream.concat(LongStream.of(1, 2), LongStream.of(3, 4)).forEach(appendNumbersTo(sb));
LongStream.concat(LongStream.of(1, 2), LongStream.of(3, 4)).forEach(appendLongNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
sb.setLength(0);
LongStream.concat(LongStream.of(1, 2), LongStream.of(3, 4)).skip(1).forEach(appendNumbersTo(sb));
LongStream.concat(LongStream.of(1, 2), LongStream.of(3, 4)).skip(1).forEach(appendLongNumbersTo(sb));
assertEquals("2;3;4;", sb.toString());
sb.setLength(0);
LongStream.concat(LongStream.of(1, 2), LongStream.of(3, 4, 5)).skip(3).forEach(appendNumbersTo(sb));
LongStream.concat(LongStream.of(1, 2), LongStream.of(3, 4, 5)).skip(3).forEach(appendLongNumbersTo(sb));
assertEquals("4;5;", sb.toString());
}
@Test
public void peekWorks() {
StringBuilder sb = new StringBuilder();
LongStream.of(1, 2, 3).peek(appendNumbersTo(sb)).map(n -> n + 10).forEach(appendNumbersTo(sb));
LongStream.of(1, 2, 3).peek(appendLongNumbersTo(sb)).map(n -> n + 10).forEach(appendLongNumbersTo(sb));
assertEquals("1;11;2;12;3;13;", sb.toString());
}
@ -185,31 +193,31 @@ public class LongStreamTest {
@Test
public void streamOfOneElement() {
StringBuilder sb = new StringBuilder();
LongStream.of(5).forEach(appendNumbersTo(sb));
LongStream.of(5).forEach(appendLongNumbersTo(sb));
assertEquals("5;", sb.toString());
sb.setLength(0);
LongStream.of(5).skip(1).forEach(appendNumbersTo(sb));
LongStream.of(5).skip(1).forEach(appendLongNumbersTo(sb));
assertEquals("", sb.toString());
sb.setLength(0);
LongStream.concat(LongStream.of(5), LongStream.of(6)).forEach(appendNumbersTo(sb));
LongStream.concat(LongStream.of(5), LongStream.of(6)).forEach(appendLongNumbersTo(sb));
assertEquals("5;6;", sb.toString());
}
@Test
public void sortedStream() {
StringBuilder sb = new StringBuilder();
LongStream.of(5, 7, 1, 2, 4, 3).sorted().forEach(appendNumbersTo(sb));
LongStream.of(5, 7, 1, 2, 4, 3).sorted().forEach(appendLongNumbersTo(sb));
assertEquals("1;2;3;4;5;7;", sb.toString());
sb.setLength(0);
LongStream.of(2, 3, 1).peek(appendNumbersTo(sb)).sorted().limit(2).map(n -> n + 10)
.forEach(appendNumbersTo(sb));
LongStream.of(2, 3, 1).peek(appendLongNumbersTo(sb)).sorted().limit(2).map(n -> n + 10)
.forEach(appendLongNumbersTo(sb));
assertEquals("2;3;1;11;12;", sb.toString());
sb.setLength(0);
LongStream.of(2, 3, 1).peek(appendNumbersTo(sb)).sorted().limit(0).forEach(appendNumbersTo(sb));
LongStream.of(2, 3, 1).peek(appendLongNumbersTo(sb)).sorted().limit(0).forEach(appendLongNumbersTo(sb));
assertEquals("2;3;1;", sb.toString());
}
@ -288,7 +296,7 @@ public class LongStreamTest {
sb.setLength(0);
iterator = LongStream.of(1, 2, 3).iterator();
iterator.forEachRemaining(appendNumbersTo(sb));
iterator.forEachRemaining(appendLongNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
}
@ -296,14 +304,14 @@ public class LongStreamTest {
public void spliterator() {
StringBuilder sb = new StringBuilder();
Spliterator.OfLong spliterator = LongStream.of(1, 2, 3).spliterator();
while (spliterator.tryAdvance(appendNumbersTo(sb))) {
while (spliterator.tryAdvance(appendLongNumbersTo(sb))) {
// continue
}
assertEquals("1;2;3;", sb.toString());
sb.setLength(0);
spliterator = LongStream.of(1, 2, 3).spliterator();
spliterator.forEachRemaining(appendNumbersTo(sb));
spliterator.forEachRemaining(appendLongNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
}
@ -316,23 +324,11 @@ public class LongStreamTest {
@Test
public void range() {
StringBuilder sb = new StringBuilder();
LongStream.range(1, 4).forEach(appendNumbersTo(sb));
LongStream.range(1, 4).forEach(appendLongNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
sb.setLength(0);
LongStream.rangeClosed(1, 4).forEach(appendNumbersTo(sb));
LongStream.rangeClosed(1, 4).forEach(appendLongNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
}
private LongConsumer appendNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private IntConsumer appendIntNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private DoubleConsumer appendDoubleNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
}

View File

@ -19,14 +19,15 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.teavm.classlib.java.util.stream.Helper.appendNumbersTo;
import static org.teavm.classlib.java.util.stream.Helper.testDoubleStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntStream;
import static org.teavm.classlib.java.util.stream.Helper.testIntegerStream;
import static org.teavm.classlib.java.util.stream.Helper.testLongStream;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
@ -39,137 +40,139 @@ import org.teavm.junit.TeaVMTestRunner;
public class StreamTest {
@Test
public void forEachWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(1, 2, 3).forEach(appendNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
testIntegerStream(() -> Stream.of(1, 2, 3), 1, 2, 3);
testIntegerStream(() -> Stream.concat(Stream.of(1), Stream.of(2, 3)), 1, 2, 3);
testIntegerStream(() -> Stream.concat(Stream.empty(), Stream.of(1, 2, 3)), 1, 2, 3);
}
@Test
public void mapWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(1, 2, 3).map(n -> n * n).forEach(appendNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testIntegerStream(() -> Stream.of(1, 2, 3).map(n -> n * n), 1, 4, 9);
testIntegerStream(() -> Stream.concat(Stream.of(1), Stream.of(2, 3)).map(n -> n * n), 1, 4, 9);
testIntegerStream(() -> Stream.concat(Stream.empty(), Stream.of(1, 2, 3)).map(n -> n * n), 1, 4, 9);
}
@Test
public void mapToIntWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(1, 2, 3).mapToInt(n -> n * n).forEach(appendIntNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testIntStream(() -> Stream.of(1, 2, 3).mapToInt(n -> n * n), 1, 4, 9);
testIntStream(() -> Stream.concat(Stream.of(1), Stream.of(2, 3)).mapToInt(n -> n * n), 1, 4, 9);
testIntStream(() -> Stream.concat(Stream.empty(), Stream.of(1, 2, 3)).mapToInt(n -> n * n), 1, 4, 9);
}
@Test
public void mapToLongWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(1, 2, 3).mapToLong(n -> n * n).forEach(appendLongNumbersTo(sb));
assertEquals("1;4;9;", sb.toString());
testLongStream(() -> Stream.of(1, 2, 3).mapToLong(n -> n * n), 1, 4, 9);
testLongStream(() -> Stream.concat(Stream.of(1), Stream.of(2, 3)).mapToLong(n -> n * n), 1, 4, 9);
testLongStream(() -> Stream.concat(Stream.empty(), Stream.of(1, 2, 3)).mapToLong(n -> n * n), 1, 4, 9);
}
@Test
public void mapToDoubleWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(1, 2, 3).mapToDouble(n -> n * n).forEach(appendDoubleNumbersTo(sb));
assertEquals("1.0;4.0;9.0;", sb.toString());
testDoubleStream(() -> Stream.of(1, 2, 3).mapToDouble(n -> n * n), 1, 4, 9);
testDoubleStream(() -> Stream.concat(Stream.of(1), Stream.of(2, 3)).mapToDouble(n -> n * n), 1, 4, 9);
testDoubleStream(() -> Stream.concat(Stream.empty(), Stream.of(1, 2, 3)).mapToDouble(n -> n * n), 1, 4, 9);
}
@Test
public void filterWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(1, 2, 3, 4, 5, 6).filter(n -> (n & 1) == 0).forEach(appendNumbersTo(sb));
assertEquals("2;4;6;", sb.toString());
testIntegerStream(() -> Stream.of(1, 2, 3, 4, 5, 6).filter(n -> (n & 1) == 0), 2, 4, 6);
testIntegerStream(() -> Stream.concat(Stream.of(1), Stream.of(2, 3, 4, 5, 6)).filter(n -> (n & 1) == 0),
2, 4, 6);
testIntegerStream(() -> Stream.concat(Stream.empty(), Stream.of(1, 2, 3, 4, 5, 6)).filter(n -> (n & 1) == 0),
2, 4, 6);
}
@Test
public void flatMapWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(Stream.of(1, 2), Stream.of(3, 4)).flatMap(n -> n).forEach(appendNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
testIntegerStream(() -> Stream.of(Stream.of(1, 2), Stream.of(3, 4)).flatMap(n -> n), 1, 2, 3, 4);
testIntegerStream(() -> Stream.of(Stream.<Integer>empty(), Stream.of(1, 2), Stream.of(3, 4)).flatMap(n -> n),
1, 2, 3, 4);
testIntegerStream(() -> Stream.of(Stream.of(1, 2), Stream.<Integer>empty(), Stream.of(3, 4)).flatMap(n -> n),
1, 2, 3, 4);
testIntegerStream(() -> Stream.of(Stream.of(1, 2), Stream.of(3, 4), Stream.<Integer>empty()).flatMap(n -> n),
1, 2, 3, 4);
sb.setLength(0);
Stream.of(Stream.of(1, 2), Stream.of(3, 4)).flatMap(n -> n).skip(1).forEach(appendNumbersTo(sb));
assertEquals("2;3;4;", sb.toString());
testIntegerStream(() -> Stream.of(Stream.of(1, 2), Stream.of(3, 4)).flatMap(n -> n).skip(1), 2, 3, 4);
sb.setLength(0);
Stream.of(Stream.of(1, 2), Stream.of(3, 4, 5)).flatMap(n -> n).skip(3).forEach(appendNumbersTo(sb));
assertEquals("4;5;", sb.toString());
testIntegerStream(() -> Stream.of(Stream.of(1, 2), Stream.of(3, 4, 5)).flatMap(n -> n).skip(3), 4, 5);
}
@Test
public void flatMapToIntWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(IntStream.of(1, 2), IntStream.of(3, 4)).flatMapToInt(n -> n).forEach(appendIntNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
testIntStream(() -> Stream.of(IntStream.of(1, 2), IntStream.of(3, 4)).flatMapToInt(n -> n), 1, 2, 3, 4);
testIntStream(() -> Stream.of(IntStream.empty(), IntStream.of(1, 2), IntStream.of(3, 4)).flatMapToInt(n -> n),
1, 2, 3, 4);
testIntStream(() -> Stream.of(IntStream.of(1, 2), IntStream.empty(), IntStream.of(3, 4)).flatMapToInt(n -> n),
1, 2, 3, 4);
testIntStream(() -> Stream.of(IntStream.of(1, 2), IntStream.of(3, 4), IntStream.empty()).flatMapToInt(n -> n),
1, 2, 3, 4);
sb.setLength(0);
Stream.of(IntStream.of(1, 2), IntStream.of(3, 4)).flatMapToInt(n -> n).skip(1).forEach(appendIntNumbersTo(sb));
assertEquals("2;3;4;", sb.toString());
testIntStream(() -> Stream.of(IntStream.of(1, 2), IntStream.of(3, 4)).flatMapToInt(n -> n).skip(1), 2, 3, 4);
sb.setLength(0);
Stream.of(IntStream.of(1, 2), IntStream.of(3, 4, 5)).flatMapToInt(n -> n).skip(3)
.forEach(appendIntNumbersTo(sb));
assertEquals("4;5;", sb.toString());
testIntStream(() -> Stream.of(IntStream.of(1, 2), IntStream.of(3, 4, 5)).flatMapToInt(n -> n).skip(3), 4, 5);
}
@Test
public void flatMapToLongWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(LongStream.of(1, 2), LongStream.of(3, 4)).flatMapToLong(n -> n).forEach(appendLongNumbersTo(sb));
assertEquals("1;2;3;4;", sb.toString());
testLongStream(() -> Stream.of(LongStream.of(1, 2), LongStream.of(3, 4)).flatMapToLong(n -> n), 1, 2, 3, 4);
testLongStream(() -> Stream.of(LongStream.empty(), LongStream.of(1, 2), LongStream.of(3, 4))
.flatMapToLong(n -> n), 1, 2, 3, 4);
testLongStream(() -> Stream.of(LongStream.of(1, 2), LongStream.empty(), LongStream.of(3, 4))
.flatMapToLong(n -> n), 1, 2, 3, 4);
testLongStream(() -> Stream.of(LongStream.of(1, 2), LongStream.of(3, 4), LongStream.empty())
.flatMapToLong(n -> n), 1, 2, 3, 4);
sb.setLength(0);
Stream.of(LongStream.of(1, 2), LongStream.of(3, 4)).flatMapToLong(n -> n).skip(1)
.forEach(appendLongNumbersTo(sb));
assertEquals("2;3;4;", sb.toString());
testLongStream(() -> Stream.of(LongStream.of(1, 2), LongStream.of(3, 4))
.flatMapToLong(n -> n).skip(1), 2, 3, 4);
sb.setLength(0);
Stream.of(LongStream.of(1, 2), LongStream.of(3, 4, 5)).flatMapToLong(n -> n).skip(3)
.forEach(appendLongNumbersTo(sb));
assertEquals("4;5;", sb.toString());
testLongStream(() -> Stream.of(LongStream.of(1, 2), LongStream.of(3, 4, 5))
.flatMapToLong(n -> n).skip(3), 4, 5);
}
@Test
public void flatMapToDoubleWorks() {
StringBuilder sb = new StringBuilder();
Stream.of(DoubleStream.of(1, 2), DoubleStream.of(3, 4)).flatMapToDouble(n -> n)
.forEach(appendDoubleNumbersTo(sb));
assertEquals("1.0;2.0;3.0;4.0;", sb.toString());
testDoubleStream(() -> Stream.of(DoubleStream.of(1, 2), DoubleStream.of(3, 4)).flatMapToDouble(n -> n),
1, 2, 3, 4);
testDoubleStream(() -> Stream.of(DoubleStream.empty(), DoubleStream.of(1, 2), DoubleStream.of(3, 4))
.flatMapToDouble(n -> n), 1, 2, 3, 4);
testDoubleStream(() -> Stream.of(DoubleStream.of(1, 2), DoubleStream.empty(), DoubleStream.of(3, 4))
.flatMapToDouble(n -> n), 1, 2, 3, 4);
testDoubleStream(() -> Stream.of(DoubleStream.of(1, 2), DoubleStream.of(3, 4), DoubleStream.empty())
.flatMapToDouble(n -> n), 1, 2, 3, 4);
sb.setLength(0);
Stream.of(DoubleStream.of(1, 2), DoubleStream.of(3, 4)).flatMapToDouble(n -> n).skip(1)
.forEach(appendDoubleNumbersTo(sb));
assertEquals("2.0;3.0;4.0;", sb.toString());
testDoubleStream(() -> Stream.of(DoubleStream.of(1, 2), DoubleStream.of(3, 4))
.flatMapToDouble(n -> n).skip(1), 2, 3, 4);
sb.setLength(0);
Stream.of(DoubleStream.of(1, 2), DoubleStream.of(3, 4, 5)).flatMapToDouble(n -> n).skip(3)
.forEach(appendDoubleNumbersTo(sb));
assertEquals("4.0;5.0;", sb.toString());
testDoubleStream(() -> Stream.of(DoubleStream.of(1, 2), DoubleStream.of(3, 4, 5))
.flatMapToDouble(n -> n).skip(3), 4, 5);
}
@Test
public void skipWorks() {
for (int i = 0; i <= 6; ++i) {
StringBuilder sb = new StringBuilder();
Stream.iterate(1, n -> n + 1).limit(5).skip(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int i = 0; i <= 5; ++i) {
int index = i;
Integer[] expected = new Integer[5 - i];
for (int j = i; j < 5; ++j) {
expected.append(j + 1).append(';');
expected[j - i] = j + 1;
}
assertEquals("Error skipping " + i + " elements", expected.toString(), sb.toString());
testIntegerStream(() -> Stream.iterate(1, n -> n + 1).limit(5).skip(index), expected);
testIntegerStream(() -> Stream.concat(Stream.of(1), Stream.iterate(2, n -> n + 1).limit(4))
.skip(index), expected);
testIntegerStream(() -> Stream.concat(Stream.empty(), Stream.iterate(1, n -> n + 1).limit(5))
.skip(index), expected);
}
}
@Test
public void limitWorks() {
for (int i = 0; i <= 3; ++i) {
StringBuilder sb = new StringBuilder();
Stream.iterate(1, n -> n + 1).limit(i).forEach(appendNumbersTo(sb));
StringBuilder expected = new StringBuilder();
for (int j = 0; j < i; ++j) {
expected.append(j + 1).append(';');
int index = i;
Integer[] expected = new Integer[i];
for (int j = 0; j < expected.length; ++j) {
expected[j] = j + 1;
}
assertEquals("Error limiting to " + i + " elements", expected.toString(), sb.toString());
testIntegerStream(() -> Stream.iterate(1, n -> n + 1).limit(index), expected);
}
}
@ -242,26 +245,20 @@ public class StreamTest {
@Test
public void streamOfOneElement() {
StringBuilder sb = new StringBuilder();
Stream.of(5).forEach(appendNumbersTo(sb));
assertEquals("5;", sb.toString());
sb.setLength(0);
Stream.of(5).skip(1).forEach(appendNumbersTo(sb));
assertEquals("", sb.toString());
sb.setLength(0);
Stream.concat(Stream.of(5), Stream.of(6)).forEach(appendNumbersTo(sb));
assertEquals("5;6;", sb.toString());
testIntegerStream(() -> Stream.of(5), 5);
testIntegerStream(() -> Stream.of(5).skip(1));
testIntegerStream(() -> Stream.concat(Stream.of(5), Stream.of(6)), 5, 6);
testIntegerStream(() -> Stream.concat(Stream.empty(), Stream.of(5)), 5);
testIntegerStream(() -> Stream.concat(Stream.of(5), Stream.empty()), 5);
}
@Test
public void sortedStream() {
StringBuilder sb = new StringBuilder();
Stream.of(5, 7, 1, 2, 4, 3).sorted().forEach(appendNumbersTo(sb));
assertEquals("1;2;3;4;5;7;", sb.toString());
testIntegerStream(() -> Stream.of(5, 7, 1, 2, 4, 3).sorted(), 1, 2, 3, 4, 5, 7);
testIntegerStream(() -> Stream.concat(Stream.of(5), Stream.of(7, 1, 2, 4, 3)).sorted(), 1, 2, 3, 4, 5, 7);
testIntegerStream(() -> Stream.concat(Stream.empty(), Stream.of(5, 7, 1, 2, 4, 3)).sorted(), 1, 2, 3, 4, 5, 7);
sb.setLength(0);
StringBuilder sb = new StringBuilder();
Stream.of(2, 3, 1).peek(appendNumbersTo(sb)).sorted().limit(2).map(n -> n + 10).forEach(appendNumbersTo(sb));
assertEquals("2;3;1;11;12;", sb.toString());
@ -367,20 +364,4 @@ public class StreamTest {
spliterator.forEachRemaining(appendNumbersTo(sb));
assertEquals("1;2;3;", sb.toString());
}
private Consumer<Integer> appendNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private IntConsumer appendIntNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private LongConsumer appendLongNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
private DoubleConsumer appendDoubleNumbersTo(StringBuilder sb) {
return n -> sb.append(n).append(';');
}
}