stdlib: implement Stream.takeWhile (#588)

Co-authored-by: Ulugbek <ulugbek.abdullaev@jetbrains.com>
This commit is contained in:
Ulugbek Abdullaev 2022-06-10 12:41:16 +02:00 committed by GitHub
parent b03518c493
commit eba1d1e574
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 0 deletions

View File

@ -79,6 +79,8 @@ public interface TStream<T> extends TBaseStream<T, TStream<T>> {
TStream<T> limit(long maxSize); TStream<T> limit(long maxSize);
TStream<T> takeWhile(Predicate<? super T> predicate);
TStream<T> skip(long n); TStream<T> skip(long n);
void forEach(Consumer<? super T> action); void forEach(Consumer<? super T> action);

View File

@ -111,6 +111,11 @@ public abstract class TSimpleStreamImpl<T> implements TStream<T> {
return new TLimitingStreamImpl<>(this, (int) maxSize); return new TLimitingStreamImpl<>(this, (int) maxSize);
} }
@Override
public TStream<T> takeWhile(Predicate<? super T> predicate) {
return new TTakeWhileStream<>(this, predicate);
}
@Override @Override
public TStream<T> skip(long n) { public TStream<T> skip(long n) {
return new TSkippingStreamImpl<>(this, (int) n); return new TSkippingStreamImpl<>(this, (int) n);

View File

@ -0,0 +1,46 @@
/*
* Copyright 2022 ulugbek.abdullaev.
*
* 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 TTakeWhileStream<T> extends TWrappingStreamImpl<T, T> {
private Predicate<? super T> predicate;
/* set to `true` as soon as we see a value `v` in the source stream for which `predicate.test(v)` is false */
private boolean isStopped;
TTakeWhileStream(TSimpleStreamImpl<T> innerStream, Predicate<? super T> predicate) {
super(innerStream);
this.predicate = predicate;
}
@Override
protected Predicate<T> wrap(Predicate<? super T> consumer) {
return t -> {
if (isStopped) {
return false;
}
if (predicate.test(t)) {
return consumer.test(t);
} else {
isStopped = true;
return false;
}
};
}
}

View File

@ -386,4 +386,18 @@ public class StreamTest {
spliterator.forEachRemaining(appendNumbersTo(sb)); spliterator.forEachRemaining(appendNumbersTo(sb));
assertEquals("1;2;3;", sb.toString()); assertEquals("1;2;3;", sb.toString());
} }
@Test
public void takeWhileWorks() {
var sb = new StringBuilder();
Stream.of(1, 2, 3, 4, 0, 5, 6).takeWhile(n -> n < 4).forEach(sb::append);
assertEquals("123", sb.toString());
}
@Test
public void takeWhileWithOtherStreamOps() {
var sb = new StringBuilder();
Stream.of(1, 2, 3, 4, 0, 5, 6).takeWhile(i -> i < 4).filter(i -> i % 2 != 0).forEach(sb::append);
assertEquals("13", sb.toString());
}
} }