diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java b/classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java index 28accc844..0f3c3fc7e 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/TSpliterators.java @@ -17,8 +17,11 @@ package org.teavm.classlib.java.util; import java.util.Collection; 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; public class TSpliterators { @@ -126,4 +129,209 @@ public class TSpliterators { } }; } + + public static TSpliterator spliteratorUnknownSize(Iterator iterator, int characteristics) { + return new TSpliterator() { + @Override + public boolean tryAdvance(Consumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public TSpliterator trySplit() { + return null; + } + + @Override + public long estimateSize() { + return Long.MAX_VALUE; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } + + public static TSpliterator.OfInt spliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics) { + return new TSpliterator.OfInt() { + @Override + public boolean tryAdvance(IntConsumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public OfInt trySplit() { + return null; + } + + @Override + public long estimateSize() { + return size; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } + + public static TSpliterator.OfInt spliteratorUnknownSize(PrimitiveIterator.OfInt iterator, int characteristics) { + return new TSpliterator.OfInt() { + @Override + public boolean tryAdvance(IntConsumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public OfInt trySplit() { + return null; + } + + @Override + public long estimateSize() { + return Long.MAX_VALUE; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } + + public static TSpliterator.OfLong spliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics) { + return new TSpliterator.OfLong() { + @Override + public boolean tryAdvance(LongConsumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public OfLong trySplit() { + return null; + } + + @Override + public long estimateSize() { + return size; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } + + public static TSpliterator.OfLong spliteratorUnknownSize(PrimitiveIterator.OfLong iterator, int characteristics) { + return new TSpliterator.OfLong() { + @Override + public boolean tryAdvance(LongConsumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public OfLong trySplit() { + return null; + } + + @Override + public long estimateSize() { + return Long.MAX_VALUE; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } + + public static TSpliterator.OfDouble spliterator(PrimitiveIterator.OfDouble iterator, long size, + int characteristics) { + return new TSpliterator.OfDouble() { + @Override + public boolean tryAdvance(DoubleConsumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public OfDouble trySplit() { + return null; + } + + @Override + public long estimateSize() { + return size; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } + + public static TSpliterator.OfDouble spliteratorUnknownSize(PrimitiveIterator.OfDouble iterator, + int characteristics) { + return new TSpliterator.OfDouble() { + @Override + public boolean tryAdvance(DoubleConsumer action) { + if (iterator.hasNext()) { + action.accept(iterator.next()); + return true; + } else { + return false; + } + } + + @Override + public OfDouble trySplit() { + return null; + } + + @Override + public long estimateSize() { + return Long.MAX_VALUE; + } + + @Override + public int characteristics() { + return characteristics; + } + }; + } } diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStreamSupport.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStreamSupport.java index 3da611c91..66828478d 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStreamSupport.java +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/TStreamSupport.java @@ -16,7 +16,9 @@ package org.teavm.classlib.java.util.stream; import java.util.Spliterator; +import java.util.function.Supplier; import org.teavm.classlib.java.util.stream.impl.TStreamOverSpliterator; +import org.teavm.classlib.java.util.stream.impl.TStreamOverSpliteratorSupplier; public final class TStreamSupport { private TStreamSupport() { @@ -25,4 +27,8 @@ public final class TStreamSupport { public static TStream stream(Spliterator spliterator, boolean parallel) { return new TStreamOverSpliterator<>(spliterator); } + + public static TStream stream(Supplier> spliterator, int characteristics, boolean parallel) { + return new TStreamOverSpliteratorSupplier<>(spliterator, characteristics); + } } diff --git a/classlib/src/main/java/org/teavm/classlib/java/util/stream/impl/TStreamOverSpliteratorSupplier.java b/classlib/src/main/java/org/teavm/classlib/java/util/stream/impl/TStreamOverSpliteratorSupplier.java new file mode 100644 index 000000000..df7f61765 --- /dev/null +++ b/classlib/src/main/java/org/teavm/classlib/java/util/stream/impl/TStreamOverSpliteratorSupplier.java @@ -0,0 +1,77 @@ +/* + * Copyright 2017 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.Spliterator; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.function.Supplier; + +public class TStreamOverSpliteratorSupplier extends TSimpleStreamImpl { + private Supplier> supplier; + private int characteristics; + private Spliterator spliterator; + + public TStreamOverSpliteratorSupplier(Supplier> supplier, int characteristics) { + this.supplier = supplier; + this.characteristics = characteristics; + } + + private void init() { + if (spliterator == null) { + spliterator = supplier.get(); + supplier = null; + } + } + + @Override + public boolean next(Predicate consumer) { + AdapterAction action = new AdapterAction<>(consumer); + init(); + while (spliterator.tryAdvance(action)) { + if (!action.wantsMore) { + return true; + } + } + return false; + } + + static class AdapterAction implements Consumer { + private Predicate consumer; + boolean wantsMore; + + AdapterAction(Predicate consumer) { + this.consumer = consumer; + } + + @Override + public void accept(T t) { + wantsMore = consumer.test(t); + } + } + + @Override + protected int estimateSize() { + init(); + return (int) spliterator.estimateSize(); + } + + @Override + public long count() { + init(); + return spliterator.hasCharacteristics(Spliterator.SIZED) ? (int) spliterator.estimateSize() : super.count(); + } +}