diff --git a/.idea/libraries/Maven__junit_junit_4_12.xml b/.idea/libraries/Maven__junit_junit_4_12.xml deleted file mode 100644 index d4110417..00000000 --- a/.idea/libraries/Maven__junit_junit_4_12.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_13.xml b/.idea/libraries/Maven__junit_junit_4_13.xml new file mode 100644 index 00000000..6d570690 --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/streamex.iml b/.idea/streamex.iml index 4e3316bc..ce83ddbd 100644 --- a/.idea/streamex.iml +++ b/.idea/streamex.iml @@ -10,7 +10,7 @@ - + - \ No newline at end of file + diff --git a/pom.xml b/pom.xml index 77759294..da478d8c 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ junit junit - 4.12 + 4.13 test diff --git a/src/test/java/one/util/streamex/AverageLongTest.java b/src/test/java/one/util/streamex/AverageLongTest.java index 6516ba4a..2a11cfe3 100644 --- a/src/test/java/one/util/streamex/AverageLongTest.java +++ b/src/test/java/one/util/streamex/AverageLongTest.java @@ -1,109 +1,109 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.math.MathContext; -import java.util.Arrays; -import java.util.OptionalDouble; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.LongStream; - -import org.junit.Test; - -import static one.util.streamex.Internals.AverageLong; -import static one.util.streamex.TestHelpers.repeat; -import static one.util.streamex.TestHelpers.withRandom; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -/** - * @author Tagir Valeev - */ -public class AverageLongTest { - - @Test - public void testAverageLongNoOverflow() { - AverageLong avg = new AverageLong(); - assertFalse(avg.result().isPresent()); - avg.accept(1); - avg.accept(2); - avg.accept(3); - assertEquals(2.0, avg.result().getAsDouble(), 0.0); - - avg.accept(2); - avg.accept(-4); - avg.accept(8); - assertEquals(2.0, avg.result().getAsDouble(), 0.0); - - AverageLong avg1 = new AverageLong(); - avg1.accept(-2); - AverageLong avg2 = new AverageLong(); - avg2.accept(-2); - assertEquals(-2.0, avg1.combine(avg2).result().getAsDouble(), 0.0); - - withRandom(r -> { - int[] input = r.ints(1000).toArray(); - OptionalDouble expected = IntStream.of(input).average(); - assertEquals(expected, Arrays.stream(input) - .collect(AverageLong::new, AverageLong::accept, AverageLong::combine).result()); - - assertEquals(expected, Arrays.stream(input).parallel().collect(AverageLong::new, AverageLong::accept, - AverageLong::combine).result()); - }); - } - - @Test - public void testCombine() { - withRandom(r -> repeat(100, i -> { - AverageLong avg1 = new AverageLong(); - AverageLong avg2 = new AverageLong(); - long[] set1 = r.longs(100).toArray(); - long[] set2 = r.longs(100).toArray(); - double expected = LongStreamEx.of(set1).append(set2).boxed().collect(getBigIntegerAverager()).getAsDouble(); - LongStream.of(set1).forEach(avg1::accept); - LongStream.of(set2).forEach(avg2::accept); - assertEquals(expected, avg1.combine(avg2).result().getAsDouble(), Math.abs(expected / 1e14)); - })); - } - - @Test - public void testCompareToBigInteger() { - withRandom(r -> { - long[] input = LongStreamEx.of(r, 1000).toArray(); - Supplier supplier = () -> Arrays.stream(input); - double expected = supplier.get().boxed().collect(getBigIntegerAverager()).getAsDouble(); - assertEquals(expected, supplier.get().collect(AverageLong::new, AverageLong::accept, AverageLong::combine) - .result().getAsDouble(), Math.abs(expected) / 1e14); - assertEquals(expected, supplier.get().parallel().collect(AverageLong::new, AverageLong::accept, - AverageLong::combine).result().getAsDouble(), Math.abs(expected) / 1e14); - }); - } - - private static Collector getBigIntegerAverager() { - BiFunction finisher = (BigInteger sum, Long cnt) -> cnt == 0L ? OptionalDouble - .empty() - : OptionalDouble.of(new BigDecimal(sum).divide(BigDecimal.valueOf(cnt), MathContext.DECIMAL64) - .doubleValue()); - return MoreCollectors.pairing(Collectors.reducing(BigInteger.ZERO, - BigInteger::valueOf, BigInteger::add), Collectors.counting(), finisher); - } -} +/* + * Copyright 2015, 2019 StreamEx contributors + * + * 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 one.util.streamex; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.util.Arrays; +import java.util.OptionalDouble; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.LongStream; + +import org.junit.Test; + +import static one.util.streamex.Internals.AverageLong; +import static one.util.streamex.TestHelpers.repeat; +import static one.util.streamex.TestHelpers.withRandom; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +/** + * @author Tagir Valeev + */ +public class AverageLongTest { + + @Test + public void testAverageLongNoOverflow() { + AverageLong avg = new AverageLong(); + assertFalse(avg.result().isPresent()); + avg.accept(1); + avg.accept(2); + avg.accept(3); + assertEquals(2.0, avg.result().getAsDouble(), 0.0); + + avg.accept(2); + avg.accept(-4); + avg.accept(8); + assertEquals(2.0, avg.result().getAsDouble(), 0.0); + + AverageLong avg1 = new AverageLong(); + avg1.accept(-2); + AverageLong avg2 = new AverageLong(); + avg2.accept(-2); + assertEquals(-2.0, avg1.combine(avg2).result().getAsDouble(), 0.0); + + withRandom(r -> { + int[] input = r.ints(1000).toArray(); + OptionalDouble expected = IntStream.of(input).average(); + assertEquals(expected, Arrays.stream(input) + .collect(AverageLong::new, AverageLong::accept, AverageLong::combine).result()); + + assertEquals(expected, Arrays.stream(input).parallel().collect(AverageLong::new, AverageLong::accept, + AverageLong::combine).result()); + }); + } + + @Test + public void testCombine() { + withRandom(r -> repeat(100, i -> { + AverageLong avg1 = new AverageLong(); + AverageLong avg2 = new AverageLong(); + long[] set1 = r.longs(100).toArray(); + long[] set2 = r.longs(100).toArray(); + double expected = LongStreamEx.of(set1).append(set2).boxed().collect(getBigIntegerAverager()).getAsDouble(); + LongStream.of(set1).forEach(avg1::accept); + LongStream.of(set2).forEach(avg2::accept); + assertEquals(expected, avg1.combine(avg2).result().getAsDouble(), Math.abs(expected / 1e14)); + })); + } + + @Test + public void testCompareToBigInteger() { + withRandom(r -> { + long[] input = LongStreamEx.of(r, 1000).toArray(); + Supplier supplier = () -> Arrays.stream(input); + double expected = supplier.get().boxed().collect(getBigIntegerAverager()).getAsDouble(); + assertEquals(expected, supplier.get().collect(AverageLong::new, AverageLong::accept, AverageLong::combine) + .result().getAsDouble(), Math.abs(expected) / 1e14); + assertEquals(expected, supplier.get().parallel().collect(AverageLong::new, AverageLong::accept, + AverageLong::combine).result().getAsDouble(), Math.abs(expected) / 1e14); + }); + } + + private static Collector getBigIntegerAverager() { + BiFunction finisher = (BigInteger sum, Long cnt) -> cnt == 0L ? OptionalDouble + .empty() + : OptionalDouble.of(new BigDecimal(sum).divide(BigDecimal.valueOf(cnt), MathContext.DECIMAL64) + .doubleValue()); + return MoreCollectors.pairing(Collectors.reducing(BigInteger.ZERO, + BigInteger::valueOf, BigInteger::add), Collectors.counting(), finisher); + } +} diff --git a/src/test/java/one/util/streamex/EntryStreamInternalTest.java b/src/test/java/one/util/streamex/EntryStreamInternalTest.java new file mode 100644 index 00000000..2477de1f --- /dev/null +++ b/src/test/java/one/util/streamex/EntryStreamInternalTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class EntryStreamInternalTest { + + @Test + public void testCreate() { + EntryStream stream = EntryStream.of(createMap()); + assertSame(stream.stream(), EntryStream.of(stream).stream()); + assertSame(stream.stream(), EntryStream.of(StreamEx.of(EntryStream.of(stream))).stream()); + } + + private static Map createMap() { + Map data = new LinkedHashMap<>(); + data.put("a", 1); + data.put("bb", 22); + data.put("ccc", 33); + return data; + } + +} diff --git a/src/test/java/one/util/streamex/StreamExInternalTest.java b/src/test/java/one/util/streamex/StreamExInternalTest.java new file mode 100644 index 00000000..4e34905b --- /dev/null +++ b/src/test/java/one/util/streamex/StreamExInternalTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex; + +import java.util.Spliterator; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import static java.util.Arrays.asList; +import static one.util.streamex.TestHelpers.streamEx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class StreamExInternalTest { + @Test + public void testCreate() { + StreamEx stream = StreamEx.of("foo", "bar"); + assertSame(stream.stream(), StreamEx.of(stream).stream()); + } + + @Test + public void testDropWhile() { + // Test that in JDK9 operation is propagated to JDK dropWhile method. + boolean hasDropWhile = VerSpec.VER_SPEC.getClass().getSimpleName().equals("Java9Specific"); + Spliterator spliterator = StreamEx.of("aaa", "b", "cccc").dropWhile(x -> x.length() > 1).spliterator(); + assertEquals(hasDropWhile, !spliterator.getClass().getSimpleName().equals("TDOfRef")); + } + + @Test + public void testSplit() { + assertEquals(CharSpliterator.class, StreamEx.split("a#a", "\\#").spliterator().getClass()); + } +} diff --git a/src/test/java/one/util/streamex/TestHelpers.java b/src/test/java/one/util/streamex/TestHelpers.java index 3e95a906..e3cf7313 100644 --- a/src/test/java/one/util/streamex/TestHelpers.java +++ b/src/test/java/one/util/streamex/TestHelpers.java @@ -1,504 +1,519 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Random; -import java.util.Set; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.IntConsumer; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.LongStream; -import java.util.stream.Stream; - -import org.junit.ComparisonFailure; - -import static one.util.streamex.Internals.TailSpliterator; -import static one.util.streamex.Internals.finished; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author Tagir Valeev - */ -public class TestHelpers { - - enum Mode { - NORMAL, SPLITERATOR, PARALLEL, APPEND, PREPEND, RANDOM - } - - static class StreamSupplier { - final Mode mode; - final Supplier> base; - - public StreamSupplier(Supplier> base, Mode mode) { - this.base = base; - this.mode = mode; - } - - public Stream get() { - Stream res = base.get(); - switch (mode) { - case NORMAL: - case SPLITERATOR: - return res.sequential(); - case PARALLEL: - return res.parallel(); - case APPEND: - // using Stream.empty() or Arrays.asList() here is optimized out - // in append/prepend which is undesired - return StreamEx.of(res.parallel()).append(new ConcurrentLinkedQueue<>()); - case PREPEND: - return StreamEx.of(res.parallel()).prepend(new ConcurrentLinkedQueue<>()); - case RANDOM: - return StreamEx.of(new EmptyingSpliterator<>(res.parallel().spliterator())).parallel(); - default: - throw new InternalError("Unsupported mode: " + mode); - } - } - - @Override - public String toString() { - return mode.toString(); - } - } - - static class StreamExSupplier extends StreamSupplier { - - public StreamExSupplier(Supplier> base, Mode mode) { - super(base, mode); - } - - @Override - public StreamEx get() { - if (mode == Mode.SPLITERATOR) - return StreamEx.of(base.get().spliterator()); - return StreamEx.of(super.get()); - } - } - - static class EntryStreamSupplier extends StreamSupplier> { - - public EntryStreamSupplier(Supplier>> base, Mode mode) { - super(base, mode); - } - - @Override - public EntryStream get() { - return EntryStream.of(super.get()); - } - } - - static List> streamEx(Supplier> base) { - return StreamEx.of(Mode.values()).map(mode -> new StreamExSupplier<>(base, mode)).toList(); - } - - /** - * Run the consumer once feeding it with RNG initialized with auto-generated seed - * adding the seed value to every failed assertion message - * - * @param cons consumer to run - */ - static void withRandom(Consumer cons) { - long seed = ThreadLocalRandom.current().nextLong(); - withRandom(seed, cons); - } - - /** - * Run the consumer once feeding it with RNG initialized with given seed - * adding the seed value to every failed assertion message - * - * @param seed random seed to use - * @param cons consumer to run - */ - static void withRandom(long seed, Consumer cons) { - Random random = new Random(seed); - withMessage("Using new Random(" + seed + ")", () -> cons.accept(random)); - } - - /** - * Run the runnable automatically adding given message to every failed assertion - * - * @param message message to prepend - * @param r runnable to run - */ - private static void withMessage(String message, Runnable r) { - try { - r.run(); - } catch (ComparisonFailure cmp) { - ComparisonFailure ex = new ComparisonFailure(message + ": " + cmp.getMessage(), cmp.getExpected(), cmp - .getActual()); - ex.setStackTrace(cmp.getStackTrace()); - throw ex; - } catch (AssertionError err) { - AssertionError ex = new AssertionError(message + ": " + err.getMessage(), err.getCause()); - ex.setStackTrace(err.getStackTrace()); - throw ex; - } catch (RuntimeException | Error err) { - throw new RuntimeException(message + ": " + err.getMessage(), err); - } - } - - static void repeat(int times, IntConsumer consumer) { - for (int i = 1; i <= times; i++) { - int finalI = i; - withMessage("#" + i, () -> consumer.accept(finalI)); - } - } - - static void streamEx(Supplier> base, Consumer> consumer) { - for (StreamExSupplier supplier : StreamEx.of(Mode.values()).map(mode -> new StreamExSupplier<>(base, mode))) { - withMessage(supplier.toString(), () -> consumer.accept(supplier)); - } - } - - static void intStreamEx(Supplier base, Consumer consumer) { - streamEx(() -> base.get().boxed(), s -> consumer.accept(s.get().mapToInt(x -> x))); - } - - static void longStreamEx(Supplier base, Consumer consumer) { - streamEx(() -> base.get().boxed(), s -> consumer.accept(s.get().mapToLong(x -> x))); - } - - static void emptyStreamEx(Class clazz, Consumer> consumer) { - streamEx(Stream::empty, consumer); - } - - static void entryStream(Supplier>> base, Consumer> consumer) { - for (EntryStreamSupplier supplier : StreamEx.of(Mode.values()).map( - mode -> new EntryStreamSupplier<>(base, mode))) { - withMessage(supplier.toString(), () -> consumer.accept(supplier)); - } - } - - /** - * Spliterator which randomly inserts empty spliterators on splitting - * - * @author Tagir Valeev - * - * @param type of the elements - */ - private static class EmptyingSpliterator implements Spliterator { - private Spliterator source; - - public EmptyingSpliterator(Spliterator source) { - this.source = Objects.requireNonNull(source); - } - - @Override - public boolean tryAdvance(Consumer action) { - return source.tryAdvance(action); - } - - @Override - public void forEachRemaining(Consumer action) { - source.forEachRemaining(action); - } - - @Override - public Comparator getComparator() { - return source.getComparator(); - } - - @Override - public Spliterator trySplit() { - Spliterator source = this.source; - switch (ThreadLocalRandom.current().nextInt(3)) { - case 0: - return Spliterators.emptySpliterator(); - case 1: - this.source = Spliterators.emptySpliterator(); - return source; - default: - Spliterator split = source.trySplit(); - return split == null ? null : new EmptyingSpliterator<>(split); - } - } - - @Override - public long estimateSize() { - return source.estimateSize(); - } - - @Override - public int characteristics() { - return source.characteristics(); - } - } - - static void checkCollectorEmpty(String message, R expected, Collector collector) { - if (finished(collector) != null) - checkShortCircuitCollector(message, expected, 0, Stream::empty, collector); - else - checkCollector(message, expected, Stream::empty, collector); - } - - static void checkShortCircuitCollector(String message, R expected, - int expectedConsumedElements, Supplier> base, Collector collector) { - checkShortCircuitCollector(message, expected, expectedConsumedElements, base, collector, false); - } - - static void checkShortCircuitCollector(String message, R expected, - int expectedConsumedElements, Supplier> base, Collector collector, boolean skipIdentity) { - assertNotNull(message, finished(collector)); - Collector withIdentity = Collectors.collectingAndThen(collector, Function.identity()); - for (StreamExSupplier supplier : streamEx(base)) { - AtomicInteger counter = new AtomicInteger(); - assertEquals(message + ": " + supplier, expected, supplier.get().peek(t -> counter.incrementAndGet()) - .collect(collector)); - if (!supplier.get().isParallel()) - assertEquals(message + ": " + supplier + ": consumed: ", expectedConsumedElements, counter.get()); - if (!skipIdentity) - assertEquals(message + ": " + supplier, expected, supplier.get().collect(withIdentity)); - } - } - - static void checkCollector(String message, R expected, Supplier> base, - Collector collector) { - // use checkShortCircuitCollector for CancellableCollector - assertNull(message, finished(collector)); - for (StreamExSupplier supplier : streamEx(base)) { - assertEquals(message + ": " + supplier, expected, supplier.get().collect(collector)); - } - } - - static void checkSpliterator(String msg, Supplier> supplier) { - List expected = new ArrayList<>(); - supplier.get().forEachRemaining(expected::add); - checkSpliterator(msg, expected, supplier); - } - - /* - * Tests whether spliterators produced by given supplier produce the - * expected result under various splittings - * - * This test is single-threaded. Its behavior is randomized, but random seed - * will be printed in case of failure, so the results could be reproduced - */ - static void checkSpliterator(String msg, List expected, Supplier> supplier) { - List seq = new ArrayList<>(); - - // Test characteristics - Spliterator forCharacteristics = supplier.get(); - if (forCharacteristics.hasCharacteristics(Spliterator.SORTED)) { - forCharacteristics.getComparator(); // must not fail - } - assertTrue(forCharacteristics.estimateSize() >= 0); - - // Test forEachRemaining - Spliterator sequential = supplier.get(); - sequential.forEachRemaining(seq::add); - assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t))); - sequential.forEachRemaining(t -> fail(msg + ": Advance called with " + t)); - assertEquals(msg, expected, seq); - - // Test tryAdvance - seq.clear(); - sequential = supplier.get(); - while (true) { - AtomicBoolean called = new AtomicBoolean(); - boolean res = sequential.tryAdvance(t -> { - seq.add(t); - called.set(true); - }); - if (res != called.get()) { - fail(msg - + (res ? ": Consumer not called, but spliterator returned true" - : ": Consumer called, but spliterator returned false")); - } - if (!res) - break; - } - assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t))); - assertEquals(msg, expected, seq); - - // Test TailSpliterator - if (sequential instanceof TailSpliterator) { - seq.clear(); - TailSpliterator.forEachWithTail(supplier.get(), seq::add); - assertEquals(msg, expected, seq); - seq.clear(); - sequential = supplier.get(); - while (sequential != null) { - sequential = TailSpliterator.tryAdvanceWithTail(sequential, seq::add); - } - } - assertEquals(msg, expected, seq); - - // Test advance+remaining - for (int i = 1; i < Math.min(4, expected.size() - 1); i++) { - seq.clear(); - sequential = supplier.get(); - for (int j = 0; j < i; j++) assertTrue(msg, sequential.tryAdvance(seq::add)); - sequential.forEachRemaining(seq::add); - assertEquals(msg, expected, seq); - } - - // Test trySplit - withRandom(r -> { - repeat(500, n -> { - Spliterator spliterator = supplier.get(); - List> spliterators = new ArrayList<>(); - spliterators.add(spliterator); - int p = r.nextInt(10) + 2; - for (int i = 0; i < p; i++) { - int idx = r.nextInt(spliterators.size()); - Spliterator split = spliterators.get(idx).trySplit(); - if (split != null) - spliterators.add(idx, split); - } - List order = IntStreamEx.ofIndices(spliterators).boxed().toList(); - Collections.shuffle(order, r); - List list = StreamEx.of(order).mapToEntry(idx -> { - Spliterator s = spliterators.get(idx); - Stream.Builder builder = Stream.builder(); - s.forEachRemaining(builder); - assertFalse(msg, s.tryAdvance(t -> fail(msg + ": Advance called with " + t))); - s.forEachRemaining(t -> fail(msg + ": Advance called with " + t)); - return builder.build(); - }).sortedBy(Entry::getKey).values().flatMap(Function.identity()).toList(); - assertEquals(msg, expected, list); - }); - repeat(500, n -> { - Spliterator spliterator = supplier.get(); - List> spliterators = new ArrayList<>(); - spliterators.add(spliterator); - int p = r.nextInt(30) + 2; - for (int i = 0; i < p; i++) { - int idx = r.nextInt(spliterators.size()); - Spliterator split = spliterators.get(idx).trySplit(); - if (split != null) - spliterators.add(idx, split); - } - List> results = StreamEx.>generate(ArrayList::new).limit(spliterators.size()) - .toList(); - int count = spliterators.size(); - while (count > 0) { - int i; - do { - i = r.nextInt(spliterators.size()); - spliterator = spliterators.get(i); - } while (spliterator == null); - if (!spliterator.tryAdvance(results.get(i)::add)) { - spliterators.set(i, null); - count--; - } - } - List list = StreamEx.of(results).flatMap(List::stream).toList(); - assertEquals(msg, expected, list); - }); - }); - } - - static void consumeElement(Spliterator spliterator, T element) { - boolean[] consumed = {false}; - assertTrue(spliterator.tryAdvance(x -> { - assertEquals(element, x); - consumed[0] = true; - })); - assertTrue(consumed[0]); - } - - static void consumeElement(Spliterator spliterator, Set remainingElements) { - boolean[] consumed = {false}; - assertTrue(spliterator.tryAdvance(x -> { - assertTrue(remainingElements.remove(x)); - consumed[0] = true; - })); - assertTrue(consumed[0]); - } - - static void checkIllegalStateException(Runnable r, String key, String value1, String value2) { - try { - r.run(); - fail("no exception"); - } catch (IllegalStateException ex) { - String exmsg = ex.getMessage(); - if (!exmsg.equals("Duplicate entry for key '" + key + "' (attempt to merge values '" + value1 + "' and '" - + value2 + "')") - && !exmsg.equals("Duplicate entry for key '" + key + "' (attempt to merge values '" + value2 - + "' and '" + value1 + "')") - && !exmsg.equals("java.lang.IllegalStateException: Duplicate entry for key '" + key - + "' (attempt to merge values '" + value1 + "' and '" + value2 + "')") - && !exmsg.equals("java.lang.IllegalStateException: Duplicate entry for key '" + key - + "' (attempt to merge values '" + value2 + "' and '" + value1 + "')")) - fail("wrong exception message: " + exmsg); - } - } - - @FunctionalInterface - interface Statement { - void evaluate() throws Throwable; - } - - static void assertThrows(Class expected, Statement statement) { - assertThrows(expected, msg -> true, statement); - } - - static void assertThrows(Class expected, Predicate checkExceptionAction, - Statement statement) { - try { - statement.evaluate(); - } catch (Throwable e) { - if (!expected.isAssignableFrom(e.getClass())) { - throw new AssertionError("Unexpected exception, " + - "expected<" + expected.getName() + "> " + - "but was<" + e.getClass().getName() + ">", e); - } - if (!checkExceptionAction.test(e.getMessage())) { - fail("Unexpected exception<" + e.getMessage() + ">"); - } - return; - } - fail("Expected exception: " + expected.getName()); - } - - static Spliterator emptySpliteratorWithExactSize(long exactSize) { - return new Spliterators.AbstractSpliterator(0, Spliterator.SIZED) { - - @Override - public long getExactSizeIfKnown() { - return exactSize; - } - - @Override - public boolean tryAdvance(Consumer ignored) { - return false; - } - }; - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.IntConsumer; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collector; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.Stream; + +import org.junit.ComparisonFailure; + +import static one.util.streamex.Internals.TailSpliterator; +import static one.util.streamex.Internals.finished; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * @author Tagir Valeev + */ +public class TestHelpers { + + enum Mode { + NORMAL, SPLITERATOR, PARALLEL, APPEND, PREPEND, RANDOM + } + + static class StreamSupplier { + final Mode mode; + final Supplier> base; + + public StreamSupplier(Supplier> base, Mode mode) { + this.base = base; + this.mode = mode; + } + + public Stream get() { + Stream res = base.get(); + switch (mode) { + case NORMAL: + case SPLITERATOR: + return res.sequential(); + case PARALLEL: + return res.parallel(); + case APPEND: + // using Stream.empty() or Arrays.asList() here is optimized out + // in append/prepend which is undesired + return StreamEx.of(res.parallel()).append(new ConcurrentLinkedQueue<>()); + case PREPEND: + return StreamEx.of(res.parallel()).prepend(new ConcurrentLinkedQueue<>()); + case RANDOM: + return StreamEx.of(new EmptyingSpliterator<>(res.parallel().spliterator())).parallel(); + default: + throw new InternalError("Unsupported mode: " + mode); + } + } + + @Override + public String toString() { + return mode.toString(); + } + } + + public static class StreamExSupplier extends StreamSupplier { + + public StreamExSupplier(Supplier> base, Mode mode) { + super(base, mode); + } + + @Override + public StreamEx get() { + if (mode == Mode.SPLITERATOR) + return StreamEx.of(base.get().spliterator()); + return StreamEx.of(super.get()); + } + } + + public static class EntryStreamSupplier extends StreamSupplier> { + + public EntryStreamSupplier(Supplier>> base, Mode mode) { + super(base, mode); + } + + @Override + public EntryStream get() { + return EntryStream.of(super.get()); + } + } + + public static class Point { + public final double x, y; + + public Point(double x, double y) { + this.x = x; + this.y = y; + } + + public double distance(Point o) { + return Math.sqrt((x - o.x) * (x - o.x) + (y - o.y) * (y - o.y)); + } + } + + public static List> streamEx(Supplier> base) { + return StreamEx.of(Mode.values()).map(mode -> new StreamExSupplier<>(base, mode)).toList(); + } + + /** + * Run the consumer once feeding it with RNG initialized with auto-generated seed + * adding the seed value to every failed assertion message + * + * @param cons consumer to run + */ + public static void withRandom(Consumer cons) { + long seed = ThreadLocalRandom.current().nextLong(); + withRandom(seed, cons); + } + + /** + * Run the consumer once feeding it with RNG initialized with given seed + * adding the seed value to every failed assertion message + * + * @param seed random seed to use + * @param cons consumer to run + */ + public static void withRandom(long seed, Consumer cons) { + Random random = new Random(seed); + withMessage("Using new Random(" + seed + ")", () -> cons.accept(random)); + } + + /** + * Run the runnable automatically adding given message to every failed assertion + * + * @param message message to prepend + * @param r runnable to run + */ + private static void withMessage(String message, Runnable r) { + try { + r.run(); + } catch (ComparisonFailure cmp) { + ComparisonFailure ex = new ComparisonFailure(message + ": " + cmp.getMessage(), cmp.getExpected(), cmp + .getActual()); + ex.setStackTrace(cmp.getStackTrace()); + throw ex; + } catch (AssertionError err) { + AssertionError ex = new AssertionError(message + ": " + err.getMessage(), err.getCause()); + ex.setStackTrace(err.getStackTrace()); + throw ex; + } catch (RuntimeException | Error err) { + throw new RuntimeException(message + ": " + err.getMessage(), err); + } + } + + public static void repeat(int times, IntConsumer consumer) { + for (int i = 1; i <= times; i++) { + int finalI = i; + withMessage("#" + i, () -> consumer.accept(finalI)); + } + } + + public static void streamEx(Supplier> base, Consumer> consumer) { + for (StreamExSupplier supplier : StreamEx.of(Mode.values()).map(mode -> new StreamExSupplier<>(base, mode))) { + withMessage(supplier.toString(), () -> consumer.accept(supplier)); + } + } + + public static void intStreamEx(Supplier base, Consumer consumer) { + streamEx(() -> base.get().boxed(), s -> consumer.accept(s.get().mapToInt(x -> x))); + } + + public static void longStreamEx(Supplier base, Consumer consumer) { + streamEx(() -> base.get().boxed(), s -> consumer.accept(s.get().mapToLong(x -> x))); + } + + public static void emptyStreamEx(Class clazz, Consumer> consumer) { + streamEx(Stream::empty, consumer); + } + + public static void entryStream(Supplier>> base, + Consumer> consumer) { + for (EntryStreamSupplier supplier : StreamEx.of(Mode.values()).map( + mode -> new EntryStreamSupplier<>(base, mode))) { + withMessage(supplier.toString(), () -> consumer.accept(supplier)); + } + } + + /** + * Spliterator which randomly inserts empty spliterators on splitting + * + * @author Tagir Valeev + * + * @param type of the elements + */ + private static class EmptyingSpliterator implements Spliterator { + private Spliterator source; + + public EmptyingSpliterator(Spliterator source) { + this.source = Objects.requireNonNull(source); + } + + @Override + public boolean tryAdvance(Consumer action) { + return source.tryAdvance(action); + } + + @Override + public void forEachRemaining(Consumer action) { + source.forEachRemaining(action); + } + + @Override + public Comparator getComparator() { + return source.getComparator(); + } + + @Override + public Spliterator trySplit() { + Spliterator source = this.source; + switch (ThreadLocalRandom.current().nextInt(3)) { + case 0: + return Spliterators.emptySpliterator(); + case 1: + this.source = Spliterators.emptySpliterator(); + return source; + default: + Spliterator split = source.trySplit(); + return split == null ? null : new EmptyingSpliterator<>(split); + } + } + + @Override + public long estimateSize() { + return source.estimateSize(); + } + + @Override + public int characteristics() { + return source.characteristics(); + } + } + + public static void checkCollectorEmpty(String message, R expected, Collector collector) { + if (finished(collector) != null) + checkShortCircuitCollector(message, expected, 0, Stream::empty, collector); + else + checkCollector(message, expected, Stream::empty, collector); + } + + public static void checkShortCircuitCollector(String message, R expected, + int expectedConsumedElements, Supplier> base, Collector collector) { + checkShortCircuitCollector(message, expected, expectedConsumedElements, base, collector, false); + } + + public static void checkShortCircuitCollector(String message, R expected, + int expectedConsumedElements, Supplier> base, Collector collector, boolean skipIdentity) { + assertNotNull(message, finished(collector)); + Collector withIdentity = Collectors.collectingAndThen(collector, Function.identity()); + for (StreamExSupplier supplier : streamEx(base)) { + AtomicInteger counter = new AtomicInteger(); + assertEquals(message + ": " + supplier, expected, supplier.get().peek(t -> counter.incrementAndGet()) + .collect(collector)); + if (!supplier.get().isParallel()) + assertEquals(message + ": " + supplier + ": consumed: ", expectedConsumedElements, counter.get()); + if (!skipIdentity) + assertEquals(message + ": " + supplier, expected, supplier.get().collect(withIdentity)); + } + } + + public static void checkCollector(String message, R expected, Supplier> base, + Collector collector) { + // use checkShortCircuitCollector for CancellableCollector + assertNull(message, finished(collector)); + for (StreamExSupplier supplier : streamEx(base)) { + assertEquals(message + ": " + supplier, expected, supplier.get().collect(collector)); + } + } + + public static void checkSpliterator(String msg, Supplier> supplier) { + List expected = new ArrayList<>(); + supplier.get().forEachRemaining(expected::add); + checkSpliterator(msg, expected, supplier); + } + + /* + * Tests whether spliterators produced by given supplier produce the + * expected result under various splittings + * + * This test is single-threaded. Its behavior is randomized, but random seed + * will be printed in case of failure, so the results could be reproduced + */ + public static void checkSpliterator(String msg, List expected, Supplier> supplier) { + List seq = new ArrayList<>(); + + // Test characteristics + Spliterator forCharacteristics = supplier.get(); + if (forCharacteristics.hasCharacteristics(Spliterator.SORTED)) { + forCharacteristics.getComparator(); // must not fail + } + assertTrue(forCharacteristics.estimateSize() >= 0); + + // Test forEachRemaining + Spliterator sequential = supplier.get(); + sequential.forEachRemaining(seq::add); + assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t))); + sequential.forEachRemaining(t -> fail(msg + ": Advance called with " + t)); + assertEquals(msg, expected, seq); + + // Test tryAdvance + seq.clear(); + sequential = supplier.get(); + while (true) { + AtomicBoolean called = new AtomicBoolean(); + boolean res = sequential.tryAdvance(t -> { + seq.add(t); + called.set(true); + }); + if (res != called.get()) { + fail(msg + + (res ? ": Consumer not called, but spliterator returned true" + : ": Consumer called, but spliterator returned false")); + } + if (!res) + break; + } + assertFalse(msg, sequential.tryAdvance(t -> fail(msg + ": Advance called with " + t))); + assertEquals(msg, expected, seq); + + // Test TailSpliterator + if (sequential instanceof TailSpliterator) { + seq.clear(); + TailSpliterator.forEachWithTail(supplier.get(), seq::add); + assertEquals(msg, expected, seq); + seq.clear(); + sequential = supplier.get(); + while (sequential != null) { + sequential = TailSpliterator.tryAdvanceWithTail(sequential, seq::add); + } + } + assertEquals(msg, expected, seq); + + // Test advance+remaining + for (int i = 1; i < Math.min(4, expected.size() - 1); i++) { + seq.clear(); + sequential = supplier.get(); + for (int j = 0; j < i; j++) assertTrue(msg, sequential.tryAdvance(seq::add)); + sequential.forEachRemaining(seq::add); + assertEquals(msg, expected, seq); + } + + // Test trySplit + withRandom(r -> { + repeat(500, n -> { + Spliterator spliterator = supplier.get(); + List> spliterators = new ArrayList<>(); + spliterators.add(spliterator); + int p = r.nextInt(10) + 2; + for (int i = 0; i < p; i++) { + int idx = r.nextInt(spliterators.size()); + Spliterator split = spliterators.get(idx).trySplit(); + if (split != null) + spliterators.add(idx, split); + } + List order = IntStreamEx.ofIndices(spliterators).boxed().toList(); + Collections.shuffle(order, r); + List list = StreamEx.of(order).mapToEntry(idx -> { + Spliterator s = spliterators.get(idx); + Stream.Builder builder = Stream.builder(); + s.forEachRemaining(builder); + assertFalse(msg, s.tryAdvance(t -> fail(msg + ": Advance called with " + t))); + s.forEachRemaining(t -> fail(msg + ": Advance called with " + t)); + return builder.build(); + }).sortedBy(Entry::getKey).values().flatMap(Function.identity()).toList(); + assertEquals(msg, expected, list); + }); + repeat(500, n -> { + Spliterator spliterator = supplier.get(); + List> spliterators = new ArrayList<>(); + spliterators.add(spliterator); + int p = r.nextInt(30) + 2; + for (int i = 0; i < p; i++) { + int idx = r.nextInt(spliterators.size()); + Spliterator split = spliterators.get(idx).trySplit(); + if (split != null) + spliterators.add(idx, split); + } + List> results = StreamEx.>generate(ArrayList::new).limit(spliterators.size()) + .toList(); + int count = spliterators.size(); + while (count > 0) { + int i; + do { + i = r.nextInt(spliterators.size()); + spliterator = spliterators.get(i); + } while (spliterator == null); + if (!spliterator.tryAdvance(results.get(i)::add)) { + spliterators.set(i, null); + count--; + } + } + List list = StreamEx.of(results).flatMap(List::stream).toList(); + assertEquals(msg, expected, list); + }); + }); + } + + public static void consumeElement(Spliterator spliterator, T element) { + boolean[] consumed = {false}; + assertTrue(spliterator.tryAdvance(x -> { + assertEquals(element, x); + consumed[0] = true; + })); + assertTrue(consumed[0]); + } + + public static void consumeElement(Spliterator spliterator, Set remainingElements) { + boolean[] consumed = {false}; + assertTrue(spliterator.tryAdvance(x -> { + assertTrue(remainingElements.remove(x)); + consumed[0] = true; + })); + assertTrue(consumed[0]); + } + + public static void checkIllegalStateException(Runnable r, String key, String value1, String value2) { + try { + r.run(); + fail("no exception"); + } catch (IllegalStateException ex) { + String exmsg = ex.getMessage(); + if (!exmsg.equals("Duplicate entry for key '" + key + "' (attempt to merge values '" + value1 + "' and '" + + value2 + "')") + && !exmsg.equals("Duplicate entry for key '" + key + "' (attempt to merge values '" + value2 + + "' and '" + value1 + "')") + && !exmsg.equals("java.lang.IllegalStateException: Duplicate entry for key '" + key + + "' (attempt to merge values '" + value1 + "' and '" + value2 + "')") + && !exmsg.equals("java.lang.IllegalStateException: Duplicate entry for key '" + key + + "' (attempt to merge values '" + value2 + "' and '" + value1 + "')")) + fail("wrong exception message: " + exmsg); + } + } + + @FunctionalInterface + public interface Statement { + void evaluate() throws Throwable; + } + + public static void assertStatementThrows(Class expected, + Predicate checkExceptionAction, + Statement statement) { + try { + statement.evaluate(); + } catch (Throwable e) { + if (!expected.isAssignableFrom(e.getClass())) { + throw new AssertionError("Unexpected exception, " + + "expected<" + expected.getName() + "> " + + "but was<" + e.getClass().getName() + ">", e); + } + if (!checkExceptionAction.test(e.getMessage())) { + fail("Unexpected exception<" + e.getMessage() + ">"); + } + return; + } + fail("Expected exception: " + expected.getName()); + } + + public static Spliterator emptySpliteratorWithExactSize(long exactSize) { + return new Spliterators.AbstractSpliterator(0, Spliterator.SIZED) { + + @Override + public long getExactSizeIfKnown() { + return exactSize; + } + + @Override + public boolean tryAdvance(Consumer ignored) { + return false; + } + }; + } + + public static void checkAsString(String expected, EntryStream stream) { + assertEquals(expected, stream.join("->").joining(";")); + } +} diff --git a/src/test/java/one/util/streamex/BaseStreamExTest.java b/src/test/java/one/util/streamex/api/BaseStreamExTest.java similarity index 90% rename from src/test/java/one/util/streamex/BaseStreamExTest.java rename to src/test/java/one/util/streamex/api/BaseStreamExTest.java index 1d9c9450..c0cfd455 100644 --- a/src/test/java/one/util/streamex/BaseStreamExTest.java +++ b/src/test/java/one/util/streamex/api/BaseStreamExTest.java @@ -1,124 +1,130 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Spliterator; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Function; -import java.util.stream.Stream; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class BaseStreamExTest { - @Test - public void testSpliterator() { - Spliterator spltr = Arrays.spliterator(new Integer[]{1, 2, 3}); - StreamEx s = StreamEx.of(spltr); - assertFalse(s.isParallel()); - assertSame(spltr, s.spliterator()); - } - - @Test(expected = IllegalStateException.class) - public void testSpliteratorConsumed() { - StreamEx s = StreamEx.of(1, 2, 3); - assertNotNull(s.spliterator()); - s.spliterator(); - } - - @Test(expected = IllegalStateException.class) - public void testStreamConsumed() { - StreamEx s = StreamEx.of(1, 2, 3); - assertNotNull(s.spliterator()); - s.count(); - } - - @Test - public void testClose() { - List closeHandlers = new ArrayList<>(); - StreamEx stream = StreamEx.of(Stream.of(1, 2, 3).onClose(() -> closeHandlers.add("Orig stream"))) - .onClose(() -> closeHandlers.add("StreamEx")) - .map(x -> x * 2) - .onClose(() -> closeHandlers.add("After map")) - .pairMap(Integer::sum) - .onClose(() -> closeHandlers.add("After pairMap")) - .append(4) - .onClose(() -> closeHandlers.add("After append")) - .prepend(Stream.of(5).onClose(() -> closeHandlers.add("Prepended Stream"))) - .prepend(StreamEx.of(6).onClose(() -> closeHandlers.add("Prepended StreamEx"))); - assertEquals(Arrays.asList(6, 5, 6, 10, 4), stream.toList()); - assertTrue(closeHandlers.isEmpty()); - stream.close(); - assertEquals(Arrays.asList("Orig stream", "StreamEx", "After map", "After pairMap", "After append", - "Prepended Stream", "Prepended StreamEx"), closeHandlers); - closeHandlers.clear(); - stream.close(); - assertTrue(closeHandlers.isEmpty()); - } - - @Test - public void testCloseException() { - AtomicBoolean flag = new AtomicBoolean(); - Function ex = str -> () -> { - throw new IllegalStateException(str); - }; - StreamEx stream = StreamEx.of(Stream.of(1, 2, 3).onClose(ex.apply("Orig stream"))) - .onClose(ex.apply("StreamEx")) - .map(x -> x * 2) - .onClose(() -> flag.set(true)) - .pairMap(Integer::sum) - .onClose(ex.apply("After pairMap")) - .append(4) - .onClose(ex.apply("After append")) - .prepend(Stream.of(5).onClose(ex.apply("Prepended Stream"))) - .prepend(StreamEx.of(6).onClose(ex.apply("Prepended StreamEx"))); - assertEquals(Arrays.asList(6, 5, 6, 10, 4), stream.toList()); - try { - stream.close(); - } catch (IllegalStateException e) { - assertEquals("Orig stream", e.getMessage()); - assertEquals(Arrays.asList("StreamEx", "After pairMap", "After append", "Prepended Stream", - "Prepended StreamEx"), StreamEx.of(e.getSuppressed()).map(IllegalStateException.class::cast).map( - Throwable::getMessage).toList()); - assertTrue(flag.get()); - return; - } - fail("No exception"); - } - - @Test - public void testChain() { - assertArrayEquals(new double[] { 2, 2, 6, 2, 6 }, IntStreamEx.of(3, 4, 5).chain(IntStreamEx::boxed).chain( - s -> s.flatMapToLong(LongStreamEx::range)).chain(s -> s.filter(n -> n % 2 != 0).asDoubleStream()).chain( - s -> s.map(x -> x * 2)).toArray(), 0.0); - } -} +/* + * Copyright 2015, 2019 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Spliterator; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.IntStreamEx; +import one.util.streamex.LongStreamEx; +import one.util.streamex.StreamEx; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class BaseStreamExTest { + @Test + public void testSpliterator() { + Spliterator spltr = Arrays.spliterator(new Integer[]{1, 2, 3}); + StreamEx s = StreamEx.of(spltr); + assertFalse(s.isParallel()); + assertSame(spltr, s.spliterator()); + } + + @Test(expected = IllegalStateException.class) + public void testSpliteratorConsumed() { + StreamEx s = StreamEx.of(1, 2, 3); + assertNotNull(s.spliterator()); + s.spliterator(); + } + + @Test(expected = IllegalStateException.class) + public void testStreamConsumed() { + StreamEx s = StreamEx.of(1, 2, 3); + assertNotNull(s.spliterator()); + s.count(); + } + + @Test + public void testClose() { + List closeHandlers = new ArrayList<>(); + StreamEx stream = StreamEx.of(Stream.of(1, 2, 3).onClose(() -> closeHandlers.add("Orig stream"))) + .onClose(() -> closeHandlers.add("StreamEx")) + .map(x -> x * 2) + .onClose(() -> closeHandlers.add("After map")) + .pairMap(Integer::sum) + .onClose(() -> closeHandlers.add("After pairMap")) + .append(4) + .onClose(() -> closeHandlers.add("After append")) + .prepend(Stream.of(5).onClose(() -> closeHandlers.add("Prepended Stream"))) + .prepend(StreamEx.of(6).onClose(() -> closeHandlers.add("Prepended StreamEx"))); + assertEquals(Arrays.asList(6, 5, 6, 10, 4), stream.toList()); + assertTrue(closeHandlers.isEmpty()); + stream.close(); + assertEquals(Arrays.asList("Orig stream", "StreamEx", "After map", "After pairMap", "After append", + "Prepended Stream", "Prepended StreamEx"), closeHandlers); + closeHandlers.clear(); + stream.close(); + assertTrue(closeHandlers.isEmpty()); + } + + @Test + public void testCloseException() { + AtomicBoolean flag = new AtomicBoolean(); + Function ex = str -> () -> { + throw new IllegalStateException(str); + }; + StreamEx stream = StreamEx.of(Stream.of(1, 2, 3).onClose(ex.apply("Orig stream"))) + .onClose(ex.apply("StreamEx")) + .map(x -> x * 2) + .onClose(() -> flag.set(true)) + .pairMap(Integer::sum) + .onClose(ex.apply("After pairMap")) + .append(4) + .onClose(ex.apply("After append")) + .prepend(Stream.of(5).onClose(ex.apply("Prepended Stream"))) + .prepend(StreamEx.of(6).onClose(ex.apply("Prepended StreamEx"))); + assertEquals(Arrays.asList(6, 5, 6, 10, 4), stream.toList()); + try { + stream.close(); + } catch (IllegalStateException e) { + assertEquals("Orig stream", e.getMessage()); + assertEquals(Arrays.asList("StreamEx", "After pairMap", "After append", "Prepended Stream", + "Prepended StreamEx"), StreamEx.of(e.getSuppressed()).map(IllegalStateException.class::cast).map( + Throwable::getMessage).toList()); + assertTrue(flag.get()); + return; + } + fail("No exception"); + } + + @Test + public void testChain() { + assertArrayEquals(new double[] { 2, 2, 6, 2, 6 }, + IntStreamEx.of(3, 4, 5).chain(IntStreamEx::boxed) + .chain(s -> s.flatMapToLong(LongStreamEx::range)) + .chain(s -> s.filter(n -> n % 2 != 0).asDoubleStream()) + .chain(s -> s.map(x -> x * 2)).toArray(), 0.0); + } +} diff --git a/src/test/java/one/util/streamex/CustomPoolTest.java b/src/test/java/one/util/streamex/api/CustomPoolTest.java similarity index 98% rename from src/test/java/one/util/streamex/CustomPoolTest.java rename to src/test/java/one/util/streamex/api/CustomPoolTest.java index 10949213..890c58a4 100644 --- a/src/test/java/one/util/streamex/CustomPoolTest.java +++ b/src/test/java/one/util/streamex/api/CustomPoolTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015, 2019 StreamEx contributors + * Copyright 2015, 2020 StreamEx contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package one.util.streamex; +package one.util.streamex.api; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; @@ -37,6 +37,13 @@ import org.junit.Test; import org.junit.runners.MethodSorters; +import one.util.streamex.DoubleStreamEx; +import one.util.streamex.EntryStream; +import one.util.streamex.IntStreamEx; +import one.util.streamex.LongStreamEx; +import one.util.streamex.MoreCollectors; +import one.util.streamex.StreamEx; + import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/src/test/java/one/util/streamex/DoubleCollectorTest.java b/src/test/java/one/util/streamex/api/DoubleCollectorTest.java similarity index 96% rename from src/test/java/one/util/streamex/DoubleCollectorTest.java rename to src/test/java/one/util/streamex/api/DoubleCollectorTest.java index cd955238..e2de795b 100644 --- a/src/test/java/one/util/streamex/DoubleCollectorTest.java +++ b/src/test/java/one/util/streamex/api/DoubleCollectorTest.java @@ -1,174 +1,180 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.util.Map; -import java.util.OptionalDouble; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class DoubleCollectorTest { - @Test - public void testJoining() { - String expected = IntStream.range(0, 10000).asDoubleStream().mapToObj(String::valueOf).collect( - Collectors.joining(", ")); - assertEquals(expected, IntStreamEx.range(10000).asDoubleStream().collect(DoubleCollector.joining(", "))); - assertEquals(expected, IntStreamEx.range(10000).asDoubleStream().parallel().collect( - DoubleCollector.joining(", "))); - String expected2 = IntStreamEx.range(0, 1000).asDoubleStream().boxed().toList().toString(); - assertEquals(expected2, IntStreamEx.range(1000).asDoubleStream().collect( - DoubleCollector.joining(", ", "[", "]"))); - assertEquals(expected2, IntStreamEx.range(1000).asDoubleStream().parallel().collect( - DoubleCollector.joining(", ", "[", "]"))); - } - - @Test - public void testCounting() { - assertEquals(5000L, (long) IntStreamEx.range(10000).asDoubleStream().atLeast(5000).collect( - DoubleCollector.counting())); - assertEquals(5000L, (long) IntStreamEx.range(10000).asDoubleStream().parallel().atLeast(5000).collect( - DoubleCollector.counting())); - assertEquals(5000, (int) IntStreamEx.range(10000).asDoubleStream().atLeast(5000).collect( - DoubleCollector.countingInt())); - assertEquals(5000, (int) IntStreamEx.range(10000).asDoubleStream().parallel().atLeast(5000).collect( - DoubleCollector.countingInt())); - } - - @Test - public void testSumming() { - assertEquals(3725, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect(DoubleCollector.summing()), 0.0); - assertEquals(3725, IntStreamEx.range(100).asDoubleStream().parallel().atLeast(50).collect( - DoubleCollector.summing()), 0.0); - } - - @Test - public void testMin() { - assertEquals(50, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect(DoubleCollector.min()) - .getAsDouble(), 0.0); - assertEquals(50, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect( - DoubleCollector.min().andThen(OptionalDouble::getAsDouble)), 0.0); - assertFalse(IntStreamEx.range(100).asDoubleStream().atLeast(200).collect(DoubleCollector.min()).isPresent()); - } - - @Test - public void testMax() { - assertEquals(99, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect(DoubleCollector.max()) - .getAsDouble(), 0.0); - assertEquals(99, IntStreamEx.range(100).asDoubleStream().parallel().atLeast(50).collect(DoubleCollector.max()) - .getAsDouble(), 0.0); - assertFalse(IntStreamEx.range(100).asDoubleStream().atLeast(200).collect(DoubleCollector.max()).isPresent()); - } - - @Test - public void testToArray() { - assertArrayEquals(new double[] { 0, 1, 2, 3, 4 }, IntStreamEx.of(0, 1, 2, 3, 4).asDoubleStream().collect( - DoubleCollector.toArray()), 0.0); - assertArrayEquals(IntStreamEx.range(1000).asDoubleStream().toFloatArray(), IntStreamEx.range(1000).parallel() - .asDoubleStream().collect(DoubleCollector.toFloatArray()), 0.0f); - } - - @Test - public void testPartitioning() { - double[] expectedEven = IntStream.range(0, 1000).asDoubleStream().map(i -> i * 2).toArray(); - double[] expectedOdd = IntStream.range(0, 1000).asDoubleStream().map(i -> i * 2 + 1).toArray(); - Map oddEven = IntStreamEx.range(2000).asDoubleStream().collect( - DoubleCollector.partitioningBy(i -> i % 2 == 0)); - assertArrayEquals(expectedEven, oddEven.get(true), 0.0); - assertArrayEquals(expectedOdd, oddEven.get(false), 0.0); - oddEven = IntStreamEx.range(2000).asDoubleStream().parallel().collect( - DoubleCollector.partitioningBy(i -> i % 2 == 0)); - assertArrayEquals(expectedEven, oddEven.get(true), 0.0); - assertArrayEquals(expectedOdd, oddEven.get(false), 0.0); - } - - @Test - public void testGroupingBy() { - Map collected = IntStreamEx.range(2000).asDoubleStream().collect( - DoubleCollector.groupingBy(i -> i % 3)); - for (double i = 0; i < 3; i++) { - double rem = i; - assertArrayEquals(IntStream.range(0, 2000).asDoubleStream().filter(a -> a % 3 == rem).toArray(), collected - .get(i), 0.0); - } - collected = IntStreamEx.range(2000).asDoubleStream().parallel().collect(DoubleCollector.groupingBy(i -> i % 3)); - for (double i = 0; i < 3; i++) { - double rem = i; - assertArrayEquals(IntStream.range(0, 2000).asDoubleStream().filter(a -> a % 3 == rem).toArray(), collected - .get(i), 0.0); - } - } - - @Test - public void testAsCollector() { - assertEquals(499.5, IntStream.range(0, 1000).asDoubleStream().boxed().collect(DoubleCollector.summarizing()) - .getAverage(), 0.000001); - assertEquals(499.5, IntStream.range(0, 1000).parallel().asDoubleStream().boxed().collect( - DoubleCollector.summarizing()).getAverage(), 0.000001); - } - - @Test - public void testAdaptor() { - assertEquals(499.5, IntStreamEx.range(1000).asDoubleStream().collect( - DoubleCollector.of(DoubleCollector.summarizing())).getAverage(), 0.000001); - assertEquals(499.5, IntStreamEx.range(1000).parallel().asDoubleStream().collect( - DoubleCollector.of(Collectors.summarizingDouble(Double::doubleValue))).getAverage(), 0.000001); - } - - @Test - public void testReducing() { - assertEquals(7.0, DoubleStreamEx.of(1.0, 2.0, 3.5).collect(DoubleCollector.reducing(1.0, (a, b) -> a * b)), 0.0); - assertEquals(7.0, DoubleStreamEx.of(1.0, 2.0, 3.5).parallel().collect( - DoubleCollector.reducing(1.0, (a, b) -> a * b)), 0.0); - } - - @Test - public void testMapping() { - assertEquals(10100.0, IntStreamEx.rangeClosed(0, 100).asDoubleStream().collect( - DoubleCollector.mapping(x -> x * 2, DoubleCollector.summing())), 0.0); - - assertArrayEquals(LongStreamEx.of(1, 1, 2, 3).toArray(), DoubleStreamEx.of(0.8, 1.3, 1.7, 2.9).collect( - DoubleCollector.mappingToObj(Math::round, LongCollector.toArray()))); - } - - @Test - public void testAveraging() { - assertFalse(DoubleStreamEx.empty().collect(DoubleCollector.averaging()).isPresent()); - assertEquals(1.0, - DoubleStreamEx.of(0.0, 0.5, 1.0, 1.5, 2.0).collect(DoubleCollector.averaging()).getAsDouble(), 0.0); - } - - @Test - public void testToBooleanArray() { - assertArrayEquals(new boolean[0], DoubleStreamEx.empty().collect(DoubleCollector.toBooleanArray(x -> true))); - boolean[] expected = new boolean[] { true, false, false, true }; - assertArrayEquals(expected, DoubleStreamEx.of(1.0, 1.5, 2.7, 3.0).collect( - DoubleCollector.toBooleanArray(x -> Math.floor(x) == x))); - assertArrayEquals(expected, DoubleStreamEx.of(1.0, 1.5, 2.7, 3.0).parallel().collect( - DoubleCollector.toBooleanArray(x -> Math.floor(x) == x))); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.util.Map; +import java.util.OptionalDouble; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.DoubleCollector; +import one.util.streamex.DoubleStreamEx; +import one.util.streamex.IntStreamEx; +import one.util.streamex.LongCollector; +import one.util.streamex.LongStreamEx; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class DoubleCollectorTest { + @Test + public void testJoining() { + String expected = IntStream.range(0, 10000).asDoubleStream().mapToObj(String::valueOf).collect( + Collectors.joining(", ")); + assertEquals(expected, IntStreamEx.range(10000).asDoubleStream().collect(DoubleCollector.joining(", "))); + assertEquals(expected, IntStreamEx.range(10000).asDoubleStream().parallel().collect( + DoubleCollector.joining(", "))); + String expected2 = IntStreamEx.range(0, 1000).asDoubleStream().boxed().toList().toString(); + assertEquals(expected2, IntStreamEx.range(1000).asDoubleStream().collect( + DoubleCollector.joining(", ", "[", "]"))); + assertEquals(expected2, IntStreamEx.range(1000).asDoubleStream().parallel().collect( + DoubleCollector.joining(", ", "[", "]"))); + } + + @Test + public void testCounting() { + assertEquals(5000L, (long) IntStreamEx.range(10000).asDoubleStream().atLeast(5000).collect( + DoubleCollector.counting())); + assertEquals(5000L, (long) IntStreamEx.range(10000).asDoubleStream().parallel().atLeast(5000).collect( + DoubleCollector.counting())); + assertEquals(5000, (int) IntStreamEx.range(10000).asDoubleStream().atLeast(5000).collect( + DoubleCollector.countingInt())); + assertEquals(5000, (int) IntStreamEx.range(10000).asDoubleStream().parallel().atLeast(5000).collect( + DoubleCollector.countingInt())); + } + + @Test + public void testSumming() { + assertEquals(3725, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect(DoubleCollector.summing()), 0.0); + assertEquals(3725, IntStreamEx.range(100).asDoubleStream().parallel().atLeast(50).collect( + DoubleCollector.summing()), 0.0); + } + + @Test + public void testMin() { + assertEquals(50, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect(DoubleCollector.min()) + .getAsDouble(), 0.0); + assertEquals(50, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect( + DoubleCollector.min().andThen(OptionalDouble::getAsDouble)), 0.0); + assertFalse(IntStreamEx.range(100).asDoubleStream().atLeast(200).collect(DoubleCollector.min()).isPresent()); + } + + @Test + public void testMax() { + assertEquals(99, IntStreamEx.range(100).asDoubleStream().atLeast(50).collect(DoubleCollector.max()) + .getAsDouble(), 0.0); + assertEquals(99, IntStreamEx.range(100).asDoubleStream().parallel().atLeast(50).collect(DoubleCollector.max()) + .getAsDouble(), 0.0); + assertFalse(IntStreamEx.range(100).asDoubleStream().atLeast(200).collect(DoubleCollector.max()).isPresent()); + } + + @Test + public void testToArray() { + assertArrayEquals(new double[] { 0, 1, 2, 3, 4 }, IntStreamEx.of(0, 1, 2, 3, 4).asDoubleStream().collect( + DoubleCollector.toArray()), 0.0); + assertArrayEquals(IntStreamEx.range(1000).asDoubleStream().toFloatArray(), IntStreamEx.range(1000).parallel() + .asDoubleStream().collect(DoubleCollector.toFloatArray()), 0.0f); + } + + @Test + public void testPartitioning() { + double[] expectedEven = IntStream.range(0, 1000).asDoubleStream().map(i -> i * 2).toArray(); + double[] expectedOdd = IntStream.range(0, 1000).asDoubleStream().map(i -> i * 2 + 1).toArray(); + Map oddEven = IntStreamEx.range(2000).asDoubleStream().collect( + DoubleCollector.partitioningBy(i -> i % 2 == 0)); + assertArrayEquals(expectedEven, oddEven.get(true), 0.0); + assertArrayEquals(expectedOdd, oddEven.get(false), 0.0); + oddEven = IntStreamEx.range(2000).asDoubleStream().parallel().collect( + DoubleCollector.partitioningBy(i -> i % 2 == 0)); + assertArrayEquals(expectedEven, oddEven.get(true), 0.0); + assertArrayEquals(expectedOdd, oddEven.get(false), 0.0); + } + + @Test + public void testGroupingBy() { + Map collected = IntStreamEx.range(2000).asDoubleStream().collect( + DoubleCollector.groupingBy(i -> i % 3)); + for (double i = 0; i < 3; i++) { + double rem = i; + assertArrayEquals(IntStream.range(0, 2000).asDoubleStream().filter(a -> a % 3 == rem).toArray(), collected + .get(i), 0.0); + } + collected = IntStreamEx.range(2000).asDoubleStream().parallel().collect(DoubleCollector.groupingBy(i -> i % 3)); + for (double i = 0; i < 3; i++) { + double rem = i; + assertArrayEquals(IntStream.range(0, 2000).asDoubleStream().filter(a -> a % 3 == rem).toArray(), collected + .get(i), 0.0); + } + } + + @Test + public void testAsCollector() { + assertEquals(499.5, IntStream.range(0, 1000).asDoubleStream().boxed().collect(DoubleCollector.summarizing()) + .getAverage(), 0.000001); + assertEquals(499.5, IntStream.range(0, 1000).parallel().asDoubleStream().boxed().collect( + DoubleCollector.summarizing()).getAverage(), 0.000001); + } + + @Test + public void testAdaptor() { + assertEquals(499.5, IntStreamEx.range(1000).asDoubleStream().collect( + DoubleCollector.of(DoubleCollector.summarizing())).getAverage(), 0.000001); + assertEquals(499.5, IntStreamEx.range(1000).parallel().asDoubleStream().collect( + DoubleCollector.of(Collectors.summarizingDouble(Double::doubleValue))).getAverage(), 0.000001); + } + + @Test + public void testReducing() { + assertEquals(7.0, DoubleStreamEx.of(1.0, 2.0, 3.5).collect(DoubleCollector.reducing(1.0, (a, b) -> a * b)), 0.0); + assertEquals(7.0, DoubleStreamEx.of(1.0, 2.0, 3.5).parallel().collect( + DoubleCollector.reducing(1.0, (a, b) -> a * b)), 0.0); + } + + @Test + public void testMapping() { + assertEquals(10100.0, IntStreamEx.rangeClosed(0, 100).asDoubleStream().collect( + DoubleCollector.mapping(x -> x * 2, DoubleCollector.summing())), 0.0); + + assertArrayEquals(LongStreamEx.of(1, 1, 2, 3).toArray(), DoubleStreamEx.of(0.8, 1.3, 1.7, 2.9).collect( + DoubleCollector.mappingToObj(Math::round, LongCollector.toArray()))); + } + + @Test + public void testAveraging() { + assertFalse(DoubleStreamEx.empty().collect(DoubleCollector.averaging()).isPresent()); + assertEquals(1.0, + DoubleStreamEx.of(0.0, 0.5, 1.0, 1.5, 2.0).collect(DoubleCollector.averaging()).getAsDouble(), 0.0); + } + + @Test + public void testToBooleanArray() { + assertArrayEquals(new boolean[0], DoubleStreamEx.empty().collect(DoubleCollector.toBooleanArray(x -> true))); + boolean[] expected = new boolean[] { true, false, false, true }; + assertArrayEquals(expected, DoubleStreamEx.of(1.0, 1.5, 2.7, 3.0).collect( + DoubleCollector.toBooleanArray(x -> Math.floor(x) == x))); + assertArrayEquals(expected, DoubleStreamEx.of(1.0, 1.5, 2.7, 3.0).parallel().collect( + DoubleCollector.toBooleanArray(x -> Math.floor(x) == x))); + } +} diff --git a/src/test/java/one/util/streamex/DoubleStreamExTest.java b/src/test/java/one/util/streamex/api/DoubleStreamExTest.java similarity index 97% rename from src/test/java/one/util/streamex/DoubleStreamExTest.java rename to src/test/java/one/util/streamex/api/DoubleStreamExTest.java index 7022296a..ce569b07 100644 --- a/src/test/java/one/util/streamex/DoubleStreamExTest.java +++ b/src/test/java/one/util/streamex/api/DoubleStreamExTest.java @@ -1,537 +1,542 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.nio.DoubleBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.OptionalDouble; -import java.util.PrimitiveIterator.OfDouble; -import java.util.Random; -import java.util.Scanner; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.DoubleBinaryOperator; -import java.util.function.DoubleFunction; -import java.util.function.DoubleToIntFunction; -import java.util.function.DoubleToLongFunction; -import java.util.function.DoubleUnaryOperator; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.DoubleStream; -import java.util.stream.DoubleStream.Builder; -import java.util.stream.LongStream; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static one.util.streamex.TestHelpers.checkSpliterator; -import static one.util.streamex.TestHelpers.streamEx; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class DoubleStreamExTest { - @Test - public void testCreate() { - assertArrayEquals(new double[] {}, DoubleStreamEx.empty().toArray(), 0.0); - // double check is intended - assertArrayEquals(new double[] {}, DoubleStreamEx.empty().toArray(), 0.0); - assertArrayEquals(new double[] { 1 }, DoubleStreamEx.of(1).toArray(), 0.0); - assertArrayEquals(new double[] { 1 }, DoubleStreamEx.of(OptionalDouble.of(1)).toArray(), 0.0); - assertArrayEquals(new double[] {}, DoubleStreamEx.of(OptionalDouble.empty()).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(1, 2, 3).toArray(), 0.0); - assertArrayEquals(new double[] { 4, 6 }, DoubleStreamEx.of(new double[] { 2, 4, 6, 8, 10 }, 1, 3).toArray(), - 0.0); - assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(1.0f, 2.0f, 3.0f).toArray(), 0.0); - assertArrayEquals(new double[] { 4, 6 }, DoubleStreamEx.of(new float[] { 2.0f, 4.0f, 6.0f, 8.0f, 10.0f }, 1, 3) - .toArray(), 0.0); - assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(DoubleStream.of(1, 2, 3)).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(Arrays.asList(1.0, 2.0, 3.0)).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 2, 4, 8, 16 }, DoubleStreamEx.iterate(1, x -> x * 2).limit(5).toArray(), - 0.0); - assertArrayEquals(new double[] { 1, 1, 1, 1 }, DoubleStreamEx.generate(() -> 1).limit(4).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 1, 1, 1 }, DoubleStreamEx.constant(1.0, 4).toArray(), 0.0); - assertEquals(10, DoubleStreamEx.of(new Random(), 10).count()); - assertArrayEquals(DoubleStreamEx.of(new Random(1), 10).toArray(), DoubleStreamEx.of(new Random(1)).limit(10) - .toArray(), 0.0); - assertTrue(DoubleStreamEx.of(new Random(), 100, 1, 10).allMatch(x -> x >= 1 && x < 10)); - assertArrayEquals(DoubleStreamEx.of(new Random(1), 100, 1, 10).toArray(), DoubleStreamEx.of(new Random(1), 1, - 10).limit(100).toArray(), 0.0); - - DoubleStream stream = DoubleStreamEx.of(1, 2, 3); - assertSame(stream, DoubleStreamEx.of(stream)); - - assertArrayEquals(new double[] { 1, 5, 3 }, DoubleStreamEx.of( - Spliterators.spliterator(new double[] { 1, 5, 3 }, 0)).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 5, 3 }, DoubleStreamEx.of( - Spliterators.iterator(Spliterators.spliterator(new double[] { 1, 5, 3 }, 0))).toArray(), 0.0); - assertArrayEquals(new double[0], DoubleStreamEx - .of(Spliterators.iterator(Spliterators.emptyDoubleSpliterator())).parallel().toArray(), 0.0); - - assertArrayEquals(new double[] { 2, 4, 6 }, DoubleStreamEx.of(new Double[] { 2.0, 4.0, 6.0 }).toArray(), 0.0); - } - - @Test - public void testOfDoubleBuffer() { - double[] data = LongStreamEx.range(100).asDoubleStream().toArray(); - assertArrayEquals(data, DoubleStreamEx.of(DoubleBuffer.wrap(data)).toArray(), 0.0); - assertArrayEquals(LongStreamEx.range(50, 70).asDoubleStream().toArray(), DoubleStreamEx.of(DoubleBuffer.wrap( - data, 50, 20)).toArray(), 0.0); - assertArrayEquals(data, DoubleStreamEx.of(DoubleBuffer.wrap(data)).parallel().toArray(), 0.0); - assertArrayEquals(LongStreamEx.range(50, 70).asDoubleStream().toArray(), DoubleStreamEx.of(DoubleBuffer.wrap( - data, 50, 20)).parallel().toArray(), 0.0); - } - - @Test - public void testIterate() { - assertArrayEquals(new double[] { 1, 2, 4, 8, 16 }, DoubleStreamEx.iterate(1, x -> x * 2).limit(5).toArray(), - 0.0); - assertArrayEquals(new double[] { 1, 2, 4, 8, 16, 32, 64 }, DoubleStreamEx.iterate(1, x -> x < 100, x -> x * 2) - .toArray(), 0.0); - assertEquals(0, DoubleStreamEx.iterate(0, x -> x < 0, x -> 1 / x).count()); - assertFalse(DoubleStreamEx.iterate(1, x -> x < 100, x -> x * 2).findFirst(x -> x == 10).isPresent()); - checkSpliterator("iterate", () -> DoubleStreamEx.iterate(1, x -> x < 100, x -> x * 2).spliterator()); - } - - @Test - public void testBasics() { - assertFalse(DoubleStreamEx.of(1).isParallel()); - assertTrue(DoubleStreamEx.of(1).parallel().isParallel()); - assertFalse(DoubleStreamEx.of(1).parallel().sequential().isParallel()); - AtomicInteger i = new AtomicInteger(); - try (DoubleStreamEx s = DoubleStreamEx.of(1).onClose(i::incrementAndGet)) { - assertEquals(1, s.count()); - } - assertEquals(1, i.get()); - assertEquals(6, IntStreamEx.range(0, 4).asDoubleStream().sum(), 0); - assertEquals(3, IntStreamEx.range(0, 4).asDoubleStream().max().getAsDouble(), 0); - assertEquals(0, IntStreamEx.range(0, 4).asDoubleStream().min().getAsDouble(), 0); - assertEquals(1.5, IntStreamEx.range(0, 4).asDoubleStream().average().getAsDouble(), 0.000001); - assertEquals(4, IntStreamEx.range(0, 4).asDoubleStream().summaryStatistics().getCount()); - assertArrayEquals(new double[] { 1, 2, 3 }, - IntStreamEx.range(0, 5).asDoubleStream().skip(1).limit(3).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(3, 1, 2).sorted().toArray(), 0.0); - assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(1, 2, 1, 3, 2).distinct().toArray(), 0.0); - assertArrayEquals(new int[] { 2, 4, 6 }, IntStreamEx.range(1, 4).asDoubleStream().mapToInt(x -> (int) x * 2) - .toArray()); - assertArrayEquals(new long[] { 2, 4, 6 }, IntStreamEx.range(1, 4).asDoubleStream().mapToLong(x -> (long) x * 2) - .toArray()); - assertArrayEquals(new double[] { 2, 4, 6 }, IntStreamEx.range(1, 4).asDoubleStream().map(x -> x * 2).toArray(), - 0.0); - assertArrayEquals(new double[] { 1, 3 }, IntStreamEx.range(0, 5).asDoubleStream().filter(x -> x % 2 == 1) - .toArray(), 0.0); - assertEquals(6.0, DoubleStreamEx.of(1.0, 2.0, 3.0).reduce(Double::sum).getAsDouble(), 0.0); - assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(1, Long.MAX_VALUE).asDoubleStream().spliterator() - .getExactSizeIfKnown()); - - assertArrayEquals(new double[] { 4, 2, 0, -2, -4 }, DoubleStreamEx.zip(new double[] { 5, 4, 3, 2, 1 }, - new double[] { 1, 2, 3, 4, 5 }, (a, b) -> a - b).toArray(), 0.0); - assertEquals("1.0; 0.5; 0.25; 0.125", DoubleStreamEx.of(1.0, 0.5, 0.25, 0.125).mapToObj(String::valueOf) - .joining("; ")); - List list = new ArrayList<>(); - DoubleStreamEx.of(1.0, 0.5, 0.25, 0.125).forEach(list::add); - assertEquals(Arrays.asList(1.0, 0.5, 0.25, 0.125), list); - list = new ArrayList<>(); - DoubleStreamEx.of(1.0, 0.5, 0.25, 0.125).parallel().forEachOrdered(list::add); - assertEquals(Arrays.asList(1.0, 0.5, 0.25, 0.125), list); - - assertFalse(DoubleStreamEx.of(1.0, 2.0, 2.5).anyMatch(x -> x < 0.0)); - assertTrue(DoubleStreamEx.of(1.0, 2.0, 2.5).anyMatch(x -> x >= 2.5)); - assertTrue(DoubleStreamEx.of(1.0, 2.0, 2.5).noneMatch(x -> x < 0.0)); - assertFalse(DoubleStreamEx.of(1.0, 2.0, 2.5).noneMatch(x -> x >= 2.5)); - assertEquals(5.0, DoubleStreamEx.of(1.0, 2.0, 2.5).reduce(1, (a, b) -> a * b), 0.0); - - assertTrue(DoubleStreamEx.of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)); - assertFalse(DoubleStreamEx.of(1, 2, 3).unordered().spliterator().hasCharacteristics(Spliterator.ORDERED)); - - OfDouble iterator = DoubleStreamEx.of(1.0, 2.0, 3.0).iterator(); - assertEquals(1.0, iterator.next(), 0.0); - assertEquals(2.0, iterator.next(), 0.0); - assertEquals(3.0, iterator.next(), 0.0); - assertFalse(iterator.hasNext()); - } - - @Test - public void testForEach() { - streamEx(() -> StreamEx.of(1, 2, 3), s -> { - AtomicInteger count = new AtomicInteger(0); - s.get().mapToDouble(Integer::intValue).forEach(v -> count.addAndGet((int) v)); - assertEquals(6, count.get()); - s.get().mapToDouble(Integer::intValue).pairMap((a, b) -> b - a).forEach(v -> count.addAndGet((int) v)); - assertEquals(8, count.get()); - }); - } - - @Test - public void testFlatMap() { - assertArrayEquals(new int[] { 1, 5, 2, 3, 3, 2, 0, 9 }, DoubleStreamEx.of(1.5, 2.3, 3.2, 0.9).flatMapToInt( - x -> IntStreamEx.of((int) Math.floor(x), (int) (Math.round(10 * (x - Math.floor(x)))))).toArray()); - assertEquals("1:.:5:2:2:.:3:3:.:2:0:.:9", DoubleStreamEx.of(1.5, 22.3, 3.2, 0.9).flatMapToObj( - x -> StreamEx.split(String.valueOf(x), "")).joining(":")); - - assertArrayEquals(new double[] { 0.0, 0.0, 1.0, 0.0, 1.0, 2.0 }, DoubleStreamEx.of(1, 2, 3).flatMap( - x -> IntStreamEx.range((int) x).asDoubleStream()).toArray(), 0.0); - - assertArrayEquals(new long[] { 0x3FF0000000000000L, 0x3FF0000000000000L, 0x4000000000000000L, - 0x4000000000000000L, 0x7FF8000000000000L, 0x7FF8000000000000L }, DoubleStreamEx.of(1, 2, Double.NaN) - .flatMapToLong(x -> LongStream.of(Double.doubleToLongBits(x), Double.doubleToRawLongBits(x))).toArray()); - } - - @Test - public void testPrepend() { - assertArrayEquals(new double[] { -1, 0, 1, 2, 3 }, DoubleStreamEx.of(1, 2, 3).prepend(-1, 0).toArray(), 0.0); - assertArrayEquals(new double[] { -1, 0, 1, 2, 3 }, DoubleStreamEx.of(1, 2, 3).prepend(DoubleStream.of(-1, 0)) - .toArray(), 0.0); - DoubleStreamEx s = DoubleStreamEx.of(1, 2, 3); - assertSame(s, s.prepend()); - } - - @Test - public void testAppend() { - assertArrayEquals(new double[] { 1, 2, 3, 4, 5 }, DoubleStreamEx.of(1, 2, 3).append(4, 5).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 2, 3, 4, 5 }, DoubleStreamEx.of(1, 2, 3).append(DoubleStream.of(4, 5)) - .toArray(), 0.0); - DoubleStreamEx s = DoubleStreamEx.of(1, 2, 3); - assertSame(s, s.append()); - } - - @Test - public void testRanges() { - assertArrayEquals(new double[] { 5, 4, Double.POSITIVE_INFINITY }, DoubleStreamEx.of(1, 5, 3, 4, -1, - Double.POSITIVE_INFINITY).greater(3).toArray(), 0.0); - assertArrayEquals(new double[] {}, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY).greater( - Double.POSITIVE_INFINITY).toArray(), 0.0); - assertArrayEquals(new double[] { 5, 3, 4, Double.POSITIVE_INFINITY }, DoubleStreamEx.of(1, 5, 3, 4, -1, - Double.POSITIVE_INFINITY).atLeast(3).toArray(), 0.0); - assertArrayEquals(new double[] { Double.POSITIVE_INFINITY }, DoubleStreamEx.of(1, 5, 3, 4, -1, - Double.POSITIVE_INFINITY).atLeast(Double.POSITIVE_INFINITY).toArray(), 0.0); - assertArrayEquals(new double[] { 1, -1 }, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY).less(3) - .toArray(), 0.0); - assertArrayEquals(new double[] { 1, 3, -1 }, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY) - .atMost(3).toArray(), 0.0); - assertArrayEquals(new double[] { 1, 3, 4, -1 }, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY) - .atMost(4).toArray(), 0.0); - } - - @Test - public void testFind() { - assertEquals(6.0, LongStreamEx.range(1, 10).asDoubleStream().findFirst(i -> i > 5).getAsDouble(), 0.0); - assertFalse(LongStreamEx.range(1, 10).asDoubleStream().findAny(i -> i > 10).isPresent()); - } - - @Test - public void testRemove() { - assertArrayEquals(new double[] { 1, 2 }, DoubleStreamEx.of(1, 2, 3).remove(x -> x > 2).toArray(), 0.0); - } - - @Test - public void testSort() { - assertArrayEquals(new double[] { 3, 2, 1 }, DoubleStreamEx.of(1, 2, 3).sortedByDouble(x -> -x).toArray(), 0.0); - assertArrayEquals(new double[] { Double.NaN, Double.NaN, Double.POSITIVE_INFINITY, Double.MAX_VALUE, 1000, 1, - Double.MIN_VALUE, 0, -0.0, -Double.MIN_VALUE * 3, -10, -Double.MAX_VALUE / 1.1, -Double.MAX_VALUE, - Double.NEGATIVE_INFINITY }, DoubleStreamEx.of(0, 1, -Double.MIN_VALUE * 3, 1000, -10, - -Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN, Double.NEGATIVE_INFINITY, Double.NaN, - Double.MAX_VALUE, -0.0, Double.MIN_VALUE, -Double.MAX_VALUE / 1.1).reverseSorted().toArray(), 0.0); - assertArrayEquals(new double[] { 1, 10, 2, 21, 9 }, DoubleStreamEx.of(1, 10, 2, 9, 21) - .sortedBy(String::valueOf).toArray(), 0.0); - - assertArrayEquals(new double[] { 0.4, 1.5, 1.3, 2.3, 2.1, 2.0, 3.7 }, DoubleStreamEx.of(1.5, 2.3, 1.3, 2.1, - 3.7, 0.4, 2.0).sortedByInt(x -> (int) x).toArray(), 0.0); - - assertArrayEquals(new double[] { 0.4, 1.5, 1.3, 2.3, 2.1, 2.0, 3.7 }, DoubleStreamEx.of(1.5, 2.3, 1.3, 2.1, - 3.7, 0.4, 2.0).sortedByLong(x -> (long) x).toArray(), 0.0); - double nonCanonicalNan = Double.longBitsToDouble(0xfff8000000000001L); - double nonCanonicalNan2 = Double.longBitsToDouble(0x7ff8000000000000L); - assertTrue(Double.isNaN(nonCanonicalNan)); - assertTrue(Double.isNaN(nonCanonicalNan2)); - double[] data = {Double.NEGATIVE_INFINITY, 0.0, 1.0, Double.POSITIVE_INFINITY, Double.NaN, nonCanonicalNan, - nonCanonicalNan2}; - double[] reverseData = {nonCanonicalNan, nonCanonicalNan2, Double.NaN, Double.POSITIVE_INFINITY, 1.0, 0.0, - Double.NEGATIVE_INFINITY}; - assertArrayEquals(DoubleStreamEx.of(data).mapToLong(Double::doubleToRawLongBits).toArray(), - DoubleStreamEx.of(data).sorted().mapToLong(Double::doubleToRawLongBits).toArray()); - assertArrayEquals(DoubleStreamEx.of(reverseData).mapToLong(Double::doubleToRawLongBits).toArray(), - DoubleStreamEx.of(data).reverseSorted().mapToLong(Double::doubleToRawLongBits).toArray()); - } - - @SafeVarargs - private static void checkEmpty(Function... fns) { - int i = 0; - for (Function fn : fns) { - assertFalse("#" + i, fn.apply(DoubleStreamEx.empty()).isPresent()); - assertFalse("#" + i, fn.apply(DoubleStreamEx.of(1, 2, 3, 4).greater(5).parallel()).isPresent()); - assertEquals("#" + i, 10, fn.apply(DoubleStreamEx.of(1, 1, 1, 1, 10, 10, 10, 10).greater(5).parallel()) - .getAsDouble(), 0.0); - i++; - } - } - - @Test - public void testMinMax() { - checkEmpty(s -> s.maxBy(Double::valueOf), s -> s.maxByInt(x -> (int) x), s -> s.maxByLong(x -> (long) x), - s -> s.maxByDouble(x -> x), s -> s.minBy(Double::valueOf), s -> s.minByInt(x -> (int) x), s -> s - .minByLong(x -> (long) x), s -> s.minByDouble(x -> x)); - assertEquals(9, IntStreamEx.range(5, 12).asDoubleStream().max( - Comparator.comparing(String::valueOf)).getAsDouble(), 0.0); - assertEquals(10, IntStreamEx.range(5, 12).asDoubleStream().min( - Comparator.comparing(String::valueOf)).getAsDouble(), 0.0); - assertEquals(9, IntStreamEx.range(5, 12).asDoubleStream().maxBy(String::valueOf).getAsDouble(), 0.0); - assertEquals(10, IntStreamEx.range(5, 12).asDoubleStream().minBy(String::valueOf).getAsDouble(), 0.0); - assertEquals(5, IntStreamEx.range(5, 12).asDoubleStream().maxByDouble(x -> 1.0 / x).getAsDouble(), 0.0); - assertEquals(11, IntStreamEx.range(5, 12).asDoubleStream().minByDouble(x -> 1.0 / x).getAsDouble(), 0.0); - assertEquals(29.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).maxByInt(x -> (int) (x % 10 * 10 + x / 10)) - .getAsDouble(), 0.0); - assertEquals(31.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).minByInt(x -> (int) (x % 10 * 10 + x / 10)) - .getAsDouble(), 0.0); - assertEquals(29.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).maxByLong(x -> (long) (x % 10 * 10 + x / 10)) - .getAsDouble(), 0.0); - assertEquals(31.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).minByLong(x -> (long) (x % 10 * 10 + x / 10)) - .getAsDouble(), 0.0); - - Supplier s = () -> DoubleStreamEx.of(1, 50, 120, 35, 130, 12, 0); - DoubleToIntFunction intKey = x -> String.valueOf(x).length(); - DoubleToLongFunction longKey = x -> String.valueOf(x).length(); - DoubleUnaryOperator doubleKey = x -> String.valueOf(x).length(); - DoubleFunction objKey = x -> String.valueOf(x).length(); - List> minFns = Arrays.asList(is -> is.minByInt(intKey), is -> is - .minByLong(longKey), is -> is.minByDouble(doubleKey), is -> is.minBy(objKey)); - List> maxFns = Arrays.asList(is -> is.maxByInt(intKey), is -> is - .maxByLong(longKey), is -> is.maxByDouble(doubleKey), is -> is.maxBy(objKey)); - minFns.forEach(fn -> assertEquals(1, fn.apply(s.get()).getAsDouble(), 0.0)); - minFns.forEach(fn -> assertEquals(1, fn.apply(s.get().parallel()).getAsDouble(), 0.0)); - maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get()).getAsDouble(), 0.0)); - maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get().parallel()).getAsDouble(), 0.0)); - } - - @Test - public void testPairMap() { - assertEquals(0, DoubleStreamEx.of().pairMap(Double::sum).count()); - assertEquals(0, DoubleStreamEx.of(1.0).pairMap(Double::sum).count()); - int[] data = new Random(1).ints(1000, 1, 1000).toArray(); - double[] expected = new double[data.length - 1]; - for (int i = 0; i < expected.length; i++) - expected[i] = (data[i + 1] - data[i]) * 1.23; - double[] result = IntStreamEx.of(data).parallel().asDoubleStream().pairMap((a, b) -> (b - a) * 1.23).toArray(); - assertArrayEquals(expected, result, 0.0); - result = IntStreamEx.of(data).asDoubleStream().pairMap((a, b) -> (b - a) * 1.23).toArray(); - assertArrayEquals(expected, result, 0.0); - assertEquals(984.0, IntStreamEx.of(data).asDoubleStream().parallel().pairMap((a, b) -> Math.abs(a - b)).max() - .getAsDouble(), 0.0); - assertArrayEquals(new double[] { 1.0, 1.0 }, DoubleStreamEx.of(1.0, 2.0, 3.0).append().parallel().pairMap( - (a, b) -> b - a).toArray(), 0.0); - - assertArrayEquals(LongStreamEx.range(1, 100).asDoubleStream().toArray(), LongStreamEx.range(100).map( - i -> i * (i + 1) / 2).append(LongStream.empty()).asDoubleStream().parallel().pairMap((a, b) -> b - a) - .toArray(), 0.0); - assertArrayEquals(LongStreamEx.range(1, 100).asDoubleStream().toArray(), LongStreamEx.range(100).map( - i -> i * (i + 1) / 2).prepend(LongStream.empty()).asDoubleStream().parallel().pairMap((a, b) -> b - a) - .toArray(), 0.0); - - assertEquals(1, LongStreamEx.range(1000).mapToDouble(x -> x * x).pairMap((a, b) -> b - a).pairMap( - (a, b) -> b - a).distinct().count()); - - assertFalse(LongStreamEx.range(1000).asDoubleStream().greater(2000).parallel().pairMap((a, b) -> a).findFirst() - .isPresent()); - } - - @Test - public void testToFloatArray() { - float[] expected = new float[10000]; - for (int i = 0; i < expected.length; i++) - expected[i] = i; - assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().toFloatArray(), 0.0f); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().parallel().toFloatArray(), 0.0f); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().greater(-1).toFloatArray(), 0.0f); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().parallel().greater(-1).toFloatArray(), - 0.0f); - // Test when resize of internal buffer is not required on addAll (buffer size = 128) - assertArrayEquals(Arrays.copyOf(expected, 100), - IntStreamEx.range(0, 100).asDoubleStream().parallel().toFloatArray(), 0.0f); - } - - @Test - public void testJoining() { - assertEquals("0.4,5.0,3.6,4.8", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).joining(",")); - assertEquals("0.4,5.0,3.6,4.8", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).parallel().joining(",")); - assertEquals("[0.4,5.0,3.6,4.8]", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).joining(",", "[", "]")); - assertEquals("[0.4,5.0,3.6,4.8]", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).parallel().joining(",", "[", "]")); - } - - @Test - public void testMapToEntry() { - Map> map = DoubleStreamEx.of(0.3, 0.5, 1.3, 0.7, 1.9, 2.1).mapToEntry(x -> (int) x, - x -> x).grouping(); - assertEquals(Arrays.asList(0.3, 0.5, 0.7), map.get(0)); - assertEquals(Arrays.asList(1.3, 1.9), map.get(1)); - assertEquals(Arrays.asList(2.1), map.get(2)); - } - - @Test - public void testTakeWhile() { - assertArrayEquals(LongStreamEx.range(100).asDoubleStream().toArray(), DoubleStreamEx.iterate(0, i -> i + 1) - .takeWhile(i -> i < 100).toArray(), 0.0); - assertEquals(0, DoubleStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 0).count()); - assertEquals(1, DoubleStreamEx.of(1, 3, 2).takeWhile(i -> i < 3).count()); - assertEquals(3, DoubleStreamEx.of(1, 2, 3).takeWhile(i -> i < 100).count()); - } - - @Test - public void testTakeWhileInclusive() { - assertArrayEquals(LongStreamEx.range(101).asDoubleStream().toArray(), DoubleStreamEx.iterate(0, i -> i + 1) - .takeWhileInclusive(i -> i < 100).toArray(), 0.0); - assertEquals(1, DoubleStreamEx.iterate(0, i -> i + 1).takeWhileInclusive(i -> i < 0).count()); - assertEquals(2, DoubleStreamEx.of(1, 3, 2).takeWhileInclusive(i -> i < 3).count()); - assertEquals(3, DoubleStreamEx.of(1, 2, 3).takeWhileInclusive(i -> i < 100).count()); - } - - @Test - public void testDropWhile() { - assertArrayEquals(new double[] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, LongStreamEx.range(100).asDoubleStream() - .dropWhile(i -> i % 10 < 5).limit(10).toArray(), 0.0); - assertEquals(100, LongStreamEx.range(100).asDoubleStream().sorted().dropWhile(i -> i % 10 < 0).count()); - assertEquals(0, LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 10).count()); - assertEquals(OptionalDouble.of(0), LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 0).findFirst()); - assertEquals(OptionalDouble.empty(), LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 10).findFirst()); - - java.util.Spliterator.OfDouble spltr = LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 1).spliterator(); - assertTrue(spltr.tryAdvance((double x) -> assertEquals(1, x, 0.0))); - Builder builder = DoubleStream.builder(); - spltr.forEachRemaining(builder); - assertArrayEquals(LongStreamEx.range(2, 100).asDoubleStream().toArray(), builder.build().toArray(), 0.0); - } - - @Test - public void testIndexOf() { - assertEquals(11, LongStreamEx.range(50, 100).asDoubleStream().indexOf(x -> x > 60).getAsLong()); - assertFalse(LongStreamEx.range(50, 100).asDoubleStream().indexOf(x -> x < 0).isPresent()); - assertEquals(11, LongStreamEx.range(50, 100).asDoubleStream().parallel().indexOf(x -> x > 60).getAsLong()); - assertFalse(LongStreamEx.range(50, 100).asDoubleStream().parallel().indexOf(x -> x < 0).isPresent()); - } - - @Test - public void testFoldLeft() { - // non-associative - DoubleBinaryOperator accumulator = (x, y) -> (x + y) * (x + y); - assertEquals(2322576, DoubleStreamEx.constant(3, 4).foldLeft(accumulator).orElse(-1), 0.0); - assertEquals(2322576, DoubleStreamEx.constant(3, 4).parallel().foldLeft(accumulator).orElse(-1), 0.0); - assertFalse(DoubleStreamEx.empty().foldLeft(accumulator).isPresent()); - assertEquals(144, DoubleStreamEx.of(1, 2, 3).foldLeft(0.0, accumulator), 144); - assertEquals(144, DoubleStreamEx.of(1, 2, 3).parallel().foldLeft(0.0, accumulator), 144); - } - - @Test - public void testMapFirstLast() { - assertArrayEquals(new double[] { -1, 2, 3, 4, 7 }, DoubleStreamEx.of(1, 2, 3, 4, 5).mapFirst(x -> x - 2.0) - .mapLast(x -> x + 2.0).toArray(), 0.0); - } - - @Test - public void testPeekFirst() { - double[] input = {1, 10, 100, 1000}; - - AtomicReference firstElement = new AtomicReference<>(); - assertArrayEquals(new double[] {10, 100, 1000}, DoubleStreamEx.of(input).peekFirst(firstElement::set).skip(1).toArray(), 0.0); - assertEquals(1, firstElement.get(), 0.0); - - assertArrayEquals(new double[] {10, 100, 1000}, DoubleStreamEx.of(input).skip(1).peekFirst(firstElement::set).toArray(), 0.0); - assertEquals(10, firstElement.get(), 0.0); - - firstElement.set(-1.0); - assertArrayEquals(new double[] {}, DoubleStreamEx.of(input).skip(4).peekFirst(firstElement::set).toArray(), 0.0); - assertEquals(-1, firstElement.get(), 0.0); - } - - @Test - public void testPeekLast() { - double[] input = {1, 10, 100, 1000}; - AtomicReference lastElement = new AtomicReference<>(); - assertArrayEquals(new double[] {1, 10, 100}, DoubleStreamEx.of(input).peekLast(lastElement::set).limit(3).toArray(), 0.0); - assertNull(lastElement.get()); - - assertArrayEquals(new double[] { 1, 10, 100 }, DoubleStreamEx.of(input).less(1000).peekLast(lastElement::set) - .limit(3).toArray(), 0.0); - assertEquals(100, lastElement.get(), 0.0); - - assertArrayEquals(input, DoubleStreamEx.of(input).peekLast(lastElement::set).limit(4).toArray(), 0.0); - assertEquals(1000, lastElement.get(), 0.0); - - assertArrayEquals(new double[] {1, 10, 100}, DoubleStreamEx.of(input).limit(3).peekLast(lastElement::set).toArray(), 0.0); - assertEquals(100, lastElement.get(), 0.0); - } - - @Test - public void testScanLeft() { - assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() - .scanLeft(Double::sum), 0.0); - assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() - .parallel().scanLeft(Double::sum), 0.0); - assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() - .filter(x -> true).scanLeft(Double::sum), 0.0); - assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() - .filter(x -> true).parallel().scanLeft(Double::sum), 0.0); - assertArrayEquals(new double[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).asDoubleStream() - .scanLeft(1, (a, b) -> a * b), 0.0); - assertArrayEquals(new double[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).asDoubleStream() - .parallel().scanLeft(1, (a, b) -> a * b), 0.0); - } - - // Reads numbers from scanner stopping when non-number is encountered - // leaving scanner in known state - private static DoubleStreamEx scannerDoubles(Scanner sc) { - return DoubleStreamEx.produce(action -> { - if (sc.hasNextDouble()) - action.accept(sc.nextDouble()); - return sc.hasNextDouble(); - }); - } - - @Test - public void testProduce() { - Scanner sc = new Scanner("1.0 2.5 3 -4.6 test"); - sc.useLocale(Locale.ENGLISH); - assertArrayEquals(new double[] {1, 2.5, 3, -4.6}, scannerDoubles(sc).stream().toArray(), 0.0); - assertEquals("test", sc.next()); - } - - @Test - public void testPrefix() { - assertArrayEquals(new double[] { 1, 3, 6, 10, 20 }, DoubleStreamEx.of(1, 2, 3, 4, 10).prefix(Double::sum).toArray(), 0.0); - assertEquals(OptionalDouble.of(10), DoubleStreamEx.of(1, 2, 3, 4, 10).prefix(Double::sum).findFirst(x -> x > 7)); - assertEquals(OptionalDouble.empty(), DoubleStreamEx.of(1, 2, 3, 4, 10).prefix(Double::sum).findFirst(x -> x > 20)); - } - - @Test - public void testIntersperse() { - assertArrayEquals(new double[] { 1, 0, 10, 0, 100, 0, 1000 }, DoubleStreamEx.of(1, 10, 100, 1000).intersperse(0) - .toArray(), 0.0); - assertEquals(0L, IntStreamEx.empty().intersperse(1).count()); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.nio.DoubleBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.OptionalDouble; +import java.util.PrimitiveIterator.OfDouble; +import java.util.Random; +import java.util.Scanner; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.DoubleBinaryOperator; +import java.util.function.DoubleFunction; +import java.util.function.DoubleToIntFunction; +import java.util.function.DoubleToLongFunction; +import java.util.function.DoubleUnaryOperator; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.DoubleStream; +import java.util.stream.DoubleStream.Builder; +import java.util.stream.LongStream; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.DoubleStreamEx; +import one.util.streamex.IntStreamEx; +import one.util.streamex.LongStreamEx; +import one.util.streamex.StreamEx; + +import static one.util.streamex.TestHelpers.checkSpliterator; +import static one.util.streamex.TestHelpers.streamEx; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class DoubleStreamExTest { + @Test + public void testCreate() { + assertArrayEquals(new double[] {}, DoubleStreamEx.empty().toArray(), 0.0); + // double check is intended + assertArrayEquals(new double[] {}, DoubleStreamEx.empty().toArray(), 0.0); + assertArrayEquals(new double[] { 1 }, DoubleStreamEx.of(1).toArray(), 0.0); + assertArrayEquals(new double[] { 1 }, DoubleStreamEx.of(OptionalDouble.of(1)).toArray(), 0.0); + assertArrayEquals(new double[] {}, DoubleStreamEx.of(OptionalDouble.empty()).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(1, 2, 3).toArray(), 0.0); + assertArrayEquals(new double[] { 4, 6 }, DoubleStreamEx.of(new double[] { 2, 4, 6, 8, 10 }, 1, 3).toArray(), + 0.0); + assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(1.0f, 2.0f, 3.0f).toArray(), 0.0); + assertArrayEquals(new double[] { 4, 6 }, DoubleStreamEx.of(new float[] { 2.0f, 4.0f, 6.0f, 8.0f, 10.0f }, 1, 3) + .toArray(), 0.0); + assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(DoubleStream.of(1, 2, 3)).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(Arrays.asList(1.0, 2.0, 3.0)).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 2, 4, 8, 16 }, DoubleStreamEx.iterate(1, x -> x * 2).limit(5).toArray(), + 0.0); + assertArrayEquals(new double[] { 1, 1, 1, 1 }, DoubleStreamEx.generate(() -> 1).limit(4).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 1, 1, 1 }, DoubleStreamEx.constant(1.0, 4).toArray(), 0.0); + assertEquals(10, DoubleStreamEx.of(new Random(), 10).count()); + assertArrayEquals(DoubleStreamEx.of(new Random(1), 10).toArray(), DoubleStreamEx.of(new Random(1)).limit(10) + .toArray(), 0.0); + assertTrue(DoubleStreamEx.of(new Random(), 100, 1, 10).allMatch(x -> x >= 1 && x < 10)); + assertArrayEquals(DoubleStreamEx.of(new Random(1), 100, 1, 10).toArray(), DoubleStreamEx.of(new Random(1), 1, + 10).limit(100).toArray(), 0.0); + + DoubleStream stream = DoubleStreamEx.of(1, 2, 3); + assertSame(stream, DoubleStreamEx.of(stream)); + + assertArrayEquals(new double[] { 1, 5, 3 }, DoubleStreamEx.of( + Spliterators.spliterator(new double[] { 1, 5, 3 }, 0)).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 5, 3 }, DoubleStreamEx.of( + Spliterators.iterator(Spliterators.spliterator(new double[] { 1, 5, 3 }, 0))).toArray(), 0.0); + assertArrayEquals(new double[0], DoubleStreamEx + .of(Spliterators.iterator(Spliterators.emptyDoubleSpliterator())).parallel().toArray(), 0.0); + + assertArrayEquals(new double[] { 2, 4, 6 }, DoubleStreamEx.of(new Double[] { 2.0, 4.0, 6.0 }).toArray(), 0.0); + } + + @Test + public void testOfDoubleBuffer() { + double[] data = LongStreamEx.range(100).asDoubleStream().toArray(); + assertArrayEquals(data, DoubleStreamEx.of(DoubleBuffer.wrap(data)).toArray(), 0.0); + assertArrayEquals(LongStreamEx.range(50, 70).asDoubleStream().toArray(), DoubleStreamEx.of(DoubleBuffer.wrap( + data, 50, 20)).toArray(), 0.0); + assertArrayEquals(data, DoubleStreamEx.of(DoubleBuffer.wrap(data)).parallel().toArray(), 0.0); + assertArrayEquals(LongStreamEx.range(50, 70).asDoubleStream().toArray(), DoubleStreamEx.of(DoubleBuffer.wrap( + data, 50, 20)).parallel().toArray(), 0.0); + } + + @Test + public void testIterate() { + assertArrayEquals(new double[] { 1, 2, 4, 8, 16 }, DoubleStreamEx.iterate(1, x -> x * 2).limit(5).toArray(), + 0.0); + assertArrayEquals(new double[] { 1, 2, 4, 8, 16, 32, 64 }, DoubleStreamEx.iterate(1, x -> x < 100, x -> x * 2) + .toArray(), 0.0); + assertEquals(0, DoubleStreamEx.iterate(0, x -> x < 0, x -> 1 / x).count()); + assertFalse(DoubleStreamEx.iterate(1, x -> x < 100, x -> x * 2).findFirst(x -> x == 10).isPresent()); + checkSpliterator("iterate", () -> DoubleStreamEx.iterate(1, x -> x < 100, x -> x * 2).spliterator()); + } + + @Test + public void testBasics() { + assertFalse(DoubleStreamEx.of(1).isParallel()); + assertTrue(DoubleStreamEx.of(1).parallel().isParallel()); + assertFalse(DoubleStreamEx.of(1).parallel().sequential().isParallel()); + AtomicInteger i = new AtomicInteger(); + try (DoubleStreamEx s = DoubleStreamEx.of(1).onClose(i::incrementAndGet)) { + assertEquals(1, s.count()); + } + assertEquals(1, i.get()); + assertEquals(6, IntStreamEx.range(0, 4).asDoubleStream().sum(), 0); + assertEquals(3, IntStreamEx.range(0, 4).asDoubleStream().max().getAsDouble(), 0); + assertEquals(0, IntStreamEx.range(0, 4).asDoubleStream().min().getAsDouble(), 0); + assertEquals(1.5, IntStreamEx.range(0, 4).asDoubleStream().average().getAsDouble(), 0.000001); + assertEquals(4, IntStreamEx.range(0, 4).asDoubleStream().summaryStatistics().getCount()); + assertArrayEquals(new double[] { 1, 2, 3 }, + IntStreamEx.range(0, 5).asDoubleStream().skip(1).limit(3).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(3, 1, 2).sorted().toArray(), 0.0); + assertArrayEquals(new double[] { 1, 2, 3 }, DoubleStreamEx.of(1, 2, 1, 3, 2).distinct().toArray(), 0.0); + assertArrayEquals(new int[] { 2, 4, 6 }, IntStreamEx.range(1, 4).asDoubleStream().mapToInt(x -> (int) x * 2) + .toArray()); + assertArrayEquals(new long[] { 2, 4, 6 }, IntStreamEx.range(1, 4).asDoubleStream().mapToLong(x -> (long) x * 2) + .toArray()); + assertArrayEquals(new double[] { 2, 4, 6 }, IntStreamEx.range(1, 4).asDoubleStream().map(x -> x * 2).toArray(), + 0.0); + assertArrayEquals(new double[] { 1, 3 }, IntStreamEx.range(0, 5).asDoubleStream().filter(x -> x % 2 == 1) + .toArray(), 0.0); + assertEquals(6.0, DoubleStreamEx.of(1.0, 2.0, 3.0).reduce(Double::sum).getAsDouble(), 0.0); + assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(1, Long.MAX_VALUE).asDoubleStream().spliterator() + .getExactSizeIfKnown()); + + assertArrayEquals(new double[] { 4, 2, 0, -2, -4 }, DoubleStreamEx.zip(new double[] { 5, 4, 3, 2, 1 }, + new double[] { 1, 2, 3, 4, 5 }, (a, b) -> a - b).toArray(), 0.0); + assertEquals("1.0; 0.5; 0.25; 0.125", DoubleStreamEx.of(1.0, 0.5, 0.25, 0.125).mapToObj(String::valueOf) + .joining("; ")); + List list = new ArrayList<>(); + DoubleStreamEx.of(1.0, 0.5, 0.25, 0.125).forEach(list::add); + assertEquals(Arrays.asList(1.0, 0.5, 0.25, 0.125), list); + list = new ArrayList<>(); + DoubleStreamEx.of(1.0, 0.5, 0.25, 0.125).parallel().forEachOrdered(list::add); + assertEquals(Arrays.asList(1.0, 0.5, 0.25, 0.125), list); + + assertFalse(DoubleStreamEx.of(1.0, 2.0, 2.5).anyMatch(x -> x < 0.0)); + assertTrue(DoubleStreamEx.of(1.0, 2.0, 2.5).anyMatch(x -> x >= 2.5)); + assertTrue(DoubleStreamEx.of(1.0, 2.0, 2.5).noneMatch(x -> x < 0.0)); + assertFalse(DoubleStreamEx.of(1.0, 2.0, 2.5).noneMatch(x -> x >= 2.5)); + assertEquals(5.0, DoubleStreamEx.of(1.0, 2.0, 2.5).reduce(1, (a, b) -> a * b), 0.0); + + assertTrue(DoubleStreamEx.of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)); + assertFalse(DoubleStreamEx.of(1, 2, 3).unordered().spliterator().hasCharacteristics(Spliterator.ORDERED)); + + OfDouble iterator = DoubleStreamEx.of(1.0, 2.0, 3.0).iterator(); + assertEquals(1.0, iterator.next(), 0.0); + assertEquals(2.0, iterator.next(), 0.0); + assertEquals(3.0, iterator.next(), 0.0); + assertFalse(iterator.hasNext()); + } + + @Test + public void testForEach() { + streamEx(() -> StreamEx.of(1, 2, 3), s -> { + AtomicInteger count = new AtomicInteger(0); + s.get().mapToDouble(Integer::intValue).forEach(v -> count.addAndGet((int) v)); + assertEquals(6, count.get()); + s.get().mapToDouble(Integer::intValue).pairMap((a, b) -> b - a).forEach(v -> count.addAndGet((int) v)); + assertEquals(8, count.get()); + }); + } + + @Test + public void testFlatMap() { + assertArrayEquals(new int[] { 1, 5, 2, 3, 3, 2, 0, 9 }, DoubleStreamEx.of(1.5, 2.3, 3.2, 0.9).flatMapToInt( + x -> IntStreamEx.of((int) Math.floor(x), (int) (Math.round(10 * (x - Math.floor(x)))))).toArray()); + assertEquals("1:.:5:2:2:.:3:3:.:2:0:.:9", DoubleStreamEx.of(1.5, 22.3, 3.2, 0.9).flatMapToObj( + x -> StreamEx.split(String.valueOf(x), "")).joining(":")); + + assertArrayEquals(new double[] { 0.0, 0.0, 1.0, 0.0, 1.0, 2.0 }, DoubleStreamEx.of(1, 2, 3).flatMap( + x -> IntStreamEx.range((int) x).asDoubleStream()).toArray(), 0.0); + + assertArrayEquals(new long[] { 0x3FF0000000000000L, 0x3FF0000000000000L, 0x4000000000000000L, + 0x4000000000000000L, 0x7FF8000000000000L, 0x7FF8000000000000L }, DoubleStreamEx.of(1, 2, Double.NaN) + .flatMapToLong(x -> LongStream.of(Double.doubleToLongBits(x), Double.doubleToRawLongBits(x))).toArray()); + } + + @Test + public void testPrepend() { + assertArrayEquals(new double[] { -1, 0, 1, 2, 3 }, DoubleStreamEx.of(1, 2, 3).prepend(-1, 0).toArray(), 0.0); + assertArrayEquals(new double[] { -1, 0, 1, 2, 3 }, DoubleStreamEx.of(1, 2, 3).prepend(DoubleStream.of(-1, 0)) + .toArray(), 0.0); + DoubleStreamEx s = DoubleStreamEx.of(1, 2, 3); + assertSame(s, s.prepend()); + } + + @Test + public void testAppend() { + assertArrayEquals(new double[] { 1, 2, 3, 4, 5 }, DoubleStreamEx.of(1, 2, 3).append(4, 5).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 2, 3, 4, 5 }, DoubleStreamEx.of(1, 2, 3).append(DoubleStream.of(4, 5)) + .toArray(), 0.0); + DoubleStreamEx s = DoubleStreamEx.of(1, 2, 3); + assertSame(s, s.append()); + } + + @Test + public void testRanges() { + assertArrayEquals(new double[] { 5, 4, Double.POSITIVE_INFINITY }, DoubleStreamEx.of(1, 5, 3, 4, -1, + Double.POSITIVE_INFINITY).greater(3).toArray(), 0.0); + assertArrayEquals(new double[] {}, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY).greater( + Double.POSITIVE_INFINITY).toArray(), 0.0); + assertArrayEquals(new double[] { 5, 3, 4, Double.POSITIVE_INFINITY }, DoubleStreamEx.of(1, 5, 3, 4, -1, + Double.POSITIVE_INFINITY).atLeast(3).toArray(), 0.0); + assertArrayEquals(new double[] { Double.POSITIVE_INFINITY }, DoubleStreamEx.of(1, 5, 3, 4, -1, + Double.POSITIVE_INFINITY).atLeast(Double.POSITIVE_INFINITY).toArray(), 0.0); + assertArrayEquals(new double[] { 1, -1 }, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY).less(3) + .toArray(), 0.0); + assertArrayEquals(new double[] { 1, 3, -1 }, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY) + .atMost(3).toArray(), 0.0); + assertArrayEquals(new double[] { 1, 3, 4, -1 }, DoubleStreamEx.of(1, 5, 3, 4, -1, Double.POSITIVE_INFINITY) + .atMost(4).toArray(), 0.0); + } + + @Test + public void testFind() { + assertEquals(6.0, LongStreamEx.range(1, 10).asDoubleStream().findFirst(i -> i > 5).getAsDouble(), 0.0); + assertFalse(LongStreamEx.range(1, 10).asDoubleStream().findAny(i -> i > 10).isPresent()); + } + + @Test + public void testRemove() { + assertArrayEquals(new double[] { 1, 2 }, DoubleStreamEx.of(1, 2, 3).remove(x -> x > 2).toArray(), 0.0); + } + + @Test + public void testSort() { + assertArrayEquals(new double[] { 3, 2, 1 }, DoubleStreamEx.of(1, 2, 3).sortedByDouble(x -> -x).toArray(), 0.0); + assertArrayEquals(new double[] { Double.NaN, Double.NaN, Double.POSITIVE_INFINITY, Double.MAX_VALUE, 1000, 1, + Double.MIN_VALUE, 0, -0.0, -Double.MIN_VALUE * 3, -10, -Double.MAX_VALUE / 1.1, -Double.MAX_VALUE, + Double.NEGATIVE_INFINITY }, DoubleStreamEx.of(0, 1, -Double.MIN_VALUE * 3, 1000, -10, + -Double.MAX_VALUE, Double.POSITIVE_INFINITY, Double.NaN, Double.NEGATIVE_INFINITY, Double.NaN, + Double.MAX_VALUE, -0.0, Double.MIN_VALUE, -Double.MAX_VALUE / 1.1).reverseSorted().toArray(), 0.0); + assertArrayEquals(new double[] { 1, 10, 2, 21, 9 }, DoubleStreamEx.of(1, 10, 2, 9, 21) + .sortedBy(String::valueOf).toArray(), 0.0); + + assertArrayEquals(new double[] { 0.4, 1.5, 1.3, 2.3, 2.1, 2.0, 3.7 }, DoubleStreamEx.of(1.5, 2.3, 1.3, 2.1, + 3.7, 0.4, 2.0).sortedByInt(x -> (int) x).toArray(), 0.0); + + assertArrayEquals(new double[] { 0.4, 1.5, 1.3, 2.3, 2.1, 2.0, 3.7 }, DoubleStreamEx.of(1.5, 2.3, 1.3, 2.1, + 3.7, 0.4, 2.0).sortedByLong(x -> (long) x).toArray(), 0.0); + double nonCanonicalNan = Double.longBitsToDouble(0xfff8000000000001L); + double nonCanonicalNan2 = Double.longBitsToDouble(0x7ff8000000000000L); + assertTrue(Double.isNaN(nonCanonicalNan)); + assertTrue(Double.isNaN(nonCanonicalNan2)); + double[] data = {Double.NEGATIVE_INFINITY, 0.0, 1.0, Double.POSITIVE_INFINITY, Double.NaN, nonCanonicalNan, + nonCanonicalNan2}; + double[] reverseData = {nonCanonicalNan, nonCanonicalNan2, Double.NaN, Double.POSITIVE_INFINITY, 1.0, 0.0, + Double.NEGATIVE_INFINITY}; + assertArrayEquals(DoubleStreamEx.of(data).mapToLong(Double::doubleToRawLongBits).toArray(), + DoubleStreamEx.of(data).sorted().mapToLong(Double::doubleToRawLongBits).toArray()); + assertArrayEquals(DoubleStreamEx.of(reverseData).mapToLong(Double::doubleToRawLongBits).toArray(), + DoubleStreamEx.of(data).reverseSorted().mapToLong(Double::doubleToRawLongBits).toArray()); + } + + @SafeVarargs + private static void checkEmpty(Function... fns) { + int i = 0; + for (Function fn : fns) { + assertFalse("#" + i, fn.apply(DoubleStreamEx.empty()).isPresent()); + assertFalse("#" + i, fn.apply(DoubleStreamEx.of(1, 2, 3, 4).greater(5).parallel()).isPresent()); + assertEquals("#" + i, 10, fn.apply(DoubleStreamEx.of(1, 1, 1, 1, 10, 10, 10, 10).greater(5).parallel()) + .getAsDouble(), 0.0); + i++; + } + } + + @Test + public void testMinMax() { + checkEmpty(s -> s.maxBy(Double::valueOf), s -> s.maxByInt(x -> (int) x), s -> s.maxByLong(x -> (long) x), + s -> s.maxByDouble(x -> x), s -> s.minBy(Double::valueOf), s -> s.minByInt(x -> (int) x), s -> s + .minByLong(x -> (long) x), s -> s.minByDouble(x -> x)); + assertEquals(9, IntStreamEx.range(5, 12).asDoubleStream().max( + Comparator.comparing(String::valueOf)).getAsDouble(), 0.0); + assertEquals(10, IntStreamEx.range(5, 12).asDoubleStream().min( + Comparator.comparing(String::valueOf)).getAsDouble(), 0.0); + assertEquals(9, IntStreamEx.range(5, 12).asDoubleStream().maxBy(String::valueOf).getAsDouble(), 0.0); + assertEquals(10, IntStreamEx.range(5, 12).asDoubleStream().minBy(String::valueOf).getAsDouble(), 0.0); + assertEquals(5, IntStreamEx.range(5, 12).asDoubleStream().maxByDouble(x -> 1.0 / x).getAsDouble(), 0.0); + assertEquals(11, IntStreamEx.range(5, 12).asDoubleStream().minByDouble(x -> 1.0 / x).getAsDouble(), 0.0); + assertEquals(29.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).maxByInt(x -> (int) (x % 10 * 10 + x / 10)) + .getAsDouble(), 0.0); + assertEquals(31.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).minByInt(x -> (int) (x % 10 * 10 + x / 10)) + .getAsDouble(), 0.0); + assertEquals(29.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).maxByLong(x -> (long) (x % 10 * 10 + x / 10)) + .getAsDouble(), 0.0); + assertEquals(31.0, DoubleStreamEx.of(15, 8, 31, 47, 19, 29).minByLong(x -> (long) (x % 10 * 10 + x / 10)) + .getAsDouble(), 0.0); + + Supplier s = () -> DoubleStreamEx.of(1, 50, 120, 35, 130, 12, 0); + DoubleToIntFunction intKey = x -> String.valueOf(x).length(); + DoubleToLongFunction longKey = x -> String.valueOf(x).length(); + DoubleUnaryOperator doubleKey = x -> String.valueOf(x).length(); + DoubleFunction objKey = x -> String.valueOf(x).length(); + List> minFns = Arrays.asList(is -> is.minByInt(intKey), is -> is + .minByLong(longKey), is -> is.minByDouble(doubleKey), is -> is.minBy(objKey)); + List> maxFns = Arrays.asList(is -> is.maxByInt(intKey), is -> is + .maxByLong(longKey), is -> is.maxByDouble(doubleKey), is -> is.maxBy(objKey)); + minFns.forEach(fn -> assertEquals(1, fn.apply(s.get()).getAsDouble(), 0.0)); + minFns.forEach(fn -> assertEquals(1, fn.apply(s.get().parallel()).getAsDouble(), 0.0)); + maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get()).getAsDouble(), 0.0)); + maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get().parallel()).getAsDouble(), 0.0)); + } + + @Test + public void testPairMap() { + assertEquals(0, DoubleStreamEx.of().pairMap(Double::sum).count()); + assertEquals(0, DoubleStreamEx.of(1.0).pairMap(Double::sum).count()); + int[] data = new Random(1).ints(1000, 1, 1000).toArray(); + double[] expected = new double[data.length - 1]; + for (int i = 0; i < expected.length; i++) + expected[i] = (data[i + 1] - data[i]) * 1.23; + double[] result = IntStreamEx.of(data).parallel().asDoubleStream().pairMap((a, b) -> (b - a) * 1.23).toArray(); + assertArrayEquals(expected, result, 0.0); + result = IntStreamEx.of(data).asDoubleStream().pairMap((a, b) -> (b - a) * 1.23).toArray(); + assertArrayEquals(expected, result, 0.0); + assertEquals(984.0, IntStreamEx.of(data).asDoubleStream().parallel().pairMap((a, b) -> Math.abs(a - b)).max() + .getAsDouble(), 0.0); + assertArrayEquals(new double[] { 1.0, 1.0 }, DoubleStreamEx.of(1.0, 2.0, 3.0).append().parallel().pairMap( + (a, b) -> b - a).toArray(), 0.0); + + assertArrayEquals(LongStreamEx.range(1, 100).asDoubleStream().toArray(), LongStreamEx.range(100).map( + i -> i * (i + 1) / 2).append(LongStream.empty()).asDoubleStream().parallel().pairMap((a, b) -> b - a) + .toArray(), 0.0); + assertArrayEquals(LongStreamEx.range(1, 100).asDoubleStream().toArray(), LongStreamEx.range(100).map( + i -> i * (i + 1) / 2).prepend(LongStream.empty()).asDoubleStream().parallel().pairMap((a, b) -> b - a) + .toArray(), 0.0); + + assertEquals(1, LongStreamEx.range(1000).mapToDouble(x -> x * x).pairMap((a, b) -> b - a).pairMap( + (a, b) -> b - a).distinct().count()); + + assertFalse(LongStreamEx.range(1000).asDoubleStream().greater(2000).parallel().pairMap((a, b) -> a).findFirst() + .isPresent()); + } + + @Test + public void testToFloatArray() { + float[] expected = new float[10000]; + for (int i = 0; i < expected.length; i++) + expected[i] = i; + assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().toFloatArray(), 0.0f); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().parallel().toFloatArray(), 0.0f); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().greater(-1).toFloatArray(), 0.0f); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).asDoubleStream().parallel().greater(-1).toFloatArray(), + 0.0f); + // Test when resize of internal buffer is not required on addAll (buffer size = 128) + assertArrayEquals(Arrays.copyOf(expected, 100), + IntStreamEx.range(0, 100).asDoubleStream().parallel().toFloatArray(), 0.0f); + } + + @Test + public void testJoining() { + assertEquals("0.4,5.0,3.6,4.8", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).joining(",")); + assertEquals("0.4,5.0,3.6,4.8", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).parallel().joining(",")); + assertEquals("[0.4,5.0,3.6,4.8]", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).joining(",", "[", "]")); + assertEquals("[0.4,5.0,3.6,4.8]", DoubleStreamEx.of(0.4, 5.0, 3.6, 4.8).parallel().joining(",", "[", "]")); + } + + @Test + public void testMapToEntry() { + Map> map = DoubleStreamEx.of(0.3, 0.5, 1.3, 0.7, 1.9, 2.1).mapToEntry(x -> (int) x, + x -> x).grouping(); + assertEquals(Arrays.asList(0.3, 0.5, 0.7), map.get(0)); + assertEquals(Arrays.asList(1.3, 1.9), map.get(1)); + assertEquals(Arrays.asList(2.1), map.get(2)); + } + + @Test + public void testTakeWhile() { + assertArrayEquals(LongStreamEx.range(100).asDoubleStream().toArray(), DoubleStreamEx.iterate(0, i -> i + 1) + .takeWhile(i -> i < 100).toArray(), 0.0); + assertEquals(0, DoubleStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 0).count()); + assertEquals(1, DoubleStreamEx.of(1, 3, 2).takeWhile(i -> i < 3).count()); + assertEquals(3, DoubleStreamEx.of(1, 2, 3).takeWhile(i -> i < 100).count()); + } + + @Test + public void testTakeWhileInclusive() { + assertArrayEquals(LongStreamEx.range(101).asDoubleStream().toArray(), DoubleStreamEx.iterate(0, i -> i + 1) + .takeWhileInclusive(i -> i < 100).toArray(), 0.0); + assertEquals(1, DoubleStreamEx.iterate(0, i -> i + 1).takeWhileInclusive(i -> i < 0).count()); + assertEquals(2, DoubleStreamEx.of(1, 3, 2).takeWhileInclusive(i -> i < 3).count()); + assertEquals(3, DoubleStreamEx.of(1, 2, 3).takeWhileInclusive(i -> i < 100).count()); + } + + @Test + public void testDropWhile() { + assertArrayEquals(new double[] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, LongStreamEx.range(100).asDoubleStream() + .dropWhile(i -> i % 10 < 5).limit(10).toArray(), 0.0); + assertEquals(100, LongStreamEx.range(100).asDoubleStream().sorted().dropWhile(i -> i % 10 < 0).count()); + assertEquals(0, LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 10).count()); + assertEquals(OptionalDouble.of(0), LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 0).findFirst()); + assertEquals(OptionalDouble.empty(), LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 10).findFirst()); + + java.util.Spliterator.OfDouble spltr = LongStreamEx.range(100).asDoubleStream().dropWhile(i -> i % 10 < 1).spliterator(); + assertTrue(spltr.tryAdvance((double x) -> assertEquals(1, x, 0.0))); + Builder builder = DoubleStream.builder(); + spltr.forEachRemaining(builder); + assertArrayEquals(LongStreamEx.range(2, 100).asDoubleStream().toArray(), builder.build().toArray(), 0.0); + } + + @Test + public void testIndexOf() { + assertEquals(11, LongStreamEx.range(50, 100).asDoubleStream().indexOf(x -> x > 60).getAsLong()); + assertFalse(LongStreamEx.range(50, 100).asDoubleStream().indexOf(x -> x < 0).isPresent()); + assertEquals(11, LongStreamEx.range(50, 100).asDoubleStream().parallel().indexOf(x -> x > 60).getAsLong()); + assertFalse(LongStreamEx.range(50, 100).asDoubleStream().parallel().indexOf(x -> x < 0).isPresent()); + } + + @Test + public void testFoldLeft() { + // non-associative + DoubleBinaryOperator accumulator = (x, y) -> (x + y) * (x + y); + assertEquals(2322576, DoubleStreamEx.constant(3, 4).foldLeft(accumulator).orElse(-1), 0.0); + assertEquals(2322576, DoubleStreamEx.constant(3, 4).parallel().foldLeft(accumulator).orElse(-1), 0.0); + assertFalse(DoubleStreamEx.empty().foldLeft(accumulator).isPresent()); + assertEquals(144, DoubleStreamEx.of(1, 2, 3).foldLeft(0.0, accumulator), 144); + assertEquals(144, DoubleStreamEx.of(1, 2, 3).parallel().foldLeft(0.0, accumulator), 144); + } + + @Test + public void testMapFirstLast() { + assertArrayEquals(new double[] { -1, 2, 3, 4, 7 }, DoubleStreamEx.of(1, 2, 3, 4, 5).mapFirst(x -> x - 2.0) + .mapLast(x -> x + 2.0).toArray(), 0.0); + } + + @Test + public void testPeekFirst() { + double[] input = {1, 10, 100, 1000}; + + AtomicReference firstElement = new AtomicReference<>(); + assertArrayEquals(new double[] {10, 100, 1000}, DoubleStreamEx.of(input).peekFirst(firstElement::set).skip(1).toArray(), 0.0); + assertEquals(1, firstElement.get(), 0.0); + + assertArrayEquals(new double[] {10, 100, 1000}, DoubleStreamEx.of(input).skip(1).peekFirst(firstElement::set).toArray(), 0.0); + assertEquals(10, firstElement.get(), 0.0); + + firstElement.set(-1.0); + assertArrayEquals(new double[] {}, DoubleStreamEx.of(input).skip(4).peekFirst(firstElement::set).toArray(), 0.0); + assertEquals(-1, firstElement.get(), 0.0); + } + + @Test + public void testPeekLast() { + double[] input = {1, 10, 100, 1000}; + AtomicReference lastElement = new AtomicReference<>(); + assertArrayEquals(new double[] {1, 10, 100}, DoubleStreamEx.of(input).peekLast(lastElement::set).limit(3).toArray(), 0.0); + assertNull(lastElement.get()); + + assertArrayEquals(new double[] { 1, 10, 100 }, DoubleStreamEx.of(input).less(1000).peekLast(lastElement::set) + .limit(3).toArray(), 0.0); + assertEquals(100, lastElement.get(), 0.0); + + assertArrayEquals(input, DoubleStreamEx.of(input).peekLast(lastElement::set).limit(4).toArray(), 0.0); + assertEquals(1000, lastElement.get(), 0.0); + + assertArrayEquals(new double[] {1, 10, 100}, DoubleStreamEx.of(input).limit(3).peekLast(lastElement::set).toArray(), 0.0); + assertEquals(100, lastElement.get(), 0.0); + } + + @Test + public void testScanLeft() { + assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() + .scanLeft(Double::sum), 0.0); + assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() + .parallel().scanLeft(Double::sum), 0.0); + assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() + .filter(x -> true).scanLeft(Double::sum), 0.0); + assertArrayEquals(new double[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).asDoubleStream() + .filter(x -> true).parallel().scanLeft(Double::sum), 0.0); + assertArrayEquals(new double[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).asDoubleStream() + .scanLeft(1, (a, b) -> a * b), 0.0); + assertArrayEquals(new double[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).asDoubleStream() + .parallel().scanLeft(1, (a, b) -> a * b), 0.0); + } + + // Reads numbers from scanner stopping when non-number is encountered + // leaving scanner in known state + private static DoubleStreamEx scannerDoubles(Scanner sc) { + return DoubleStreamEx.produce(action -> { + if (sc.hasNextDouble()) + action.accept(sc.nextDouble()); + return sc.hasNextDouble(); + }); + } + + @Test + public void testProduce() { + Scanner sc = new Scanner("1.0 2.5 3 -4.6 test"); + sc.useLocale(Locale.ENGLISH); + assertArrayEquals(new double[] {1, 2.5, 3, -4.6}, scannerDoubles(sc).toArray(), 0.0); + assertEquals("test", sc.next()); + } + + @Test + public void testPrefix() { + assertArrayEquals(new double[] { 1, 3, 6, 10, 20 }, DoubleStreamEx.of(1, 2, 3, 4, 10).prefix(Double::sum).toArray(), 0.0); + assertEquals(OptionalDouble.of(10), DoubleStreamEx.of(1, 2, 3, 4, 10).prefix(Double::sum).findFirst(x -> x > 7)); + assertEquals(OptionalDouble.empty(), DoubleStreamEx.of(1, 2, 3, 4, 10).prefix(Double::sum).findFirst(x -> x > 20)); + } + + @Test + public void testIntersperse() { + assertArrayEquals(new double[] { 1, 0, 10, 0, 100, 0, 1000 }, DoubleStreamEx.of(1, 10, 100, 1000).intersperse(0) + .toArray(), 0.0); + assertEquals(0L, IntStreamEx.empty().intersperse(1).count()); + } +} diff --git a/src/test/java/one/util/streamex/EmitterTest.java b/src/test/java/one/util/streamex/api/EmitterTest.java similarity index 85% rename from src/test/java/one/util/streamex/EmitterTest.java rename to src/test/java/one/util/streamex/api/EmitterTest.java index fc37aa1e..7f33dbb9 100644 --- a/src/test/java/one/util/streamex/EmitterTest.java +++ b/src/test/java/one/util/streamex/api/EmitterTest.java @@ -1,181 +1,191 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.math.BigInteger; -import java.util.Iterator; -import java.util.function.BinaryOperator; -import java.util.function.LongPredicate; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import one.util.streamex.DoubleStreamEx.DoubleEmitter; -import one.util.streamex.IntStreamEx.IntEmitter; -import one.util.streamex.LongStreamEx.LongEmitter; -import one.util.streamex.StreamEx.Emitter; - -import static java.util.Arrays.asList; -import static one.util.streamex.TestHelpers.checkSpliterator; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class EmitterTest { - // Like Java-9 Stream.iterate(seed, test, op) - public static Emitter iterate(T seed, Predicate test, UnaryOperator op) { - return test.test(seed) ? action -> { - action.accept(seed); - return iterate(op.apply(seed), test, op); - } : null; - } - - // Collatz sequence starting from given number - public static Emitter collatz(int start) { - return action -> { - action.accept(start); - return start == 1 ? null : collatz(start % 2 == 0 ? start / 2 : start * 3 + 1); - }; - } - - public static IntEmitter collatzInt(int start) { - return action -> { - action.accept(start); - return start == 1 ? null : collatzInt(start % 2 == 0 ? start / 2 : start * 3 + 1); - }; - } - - public static LongEmitter collatzLong(long start) { - return action -> { - action.accept(start); - return start == 1 ? null : collatzLong(start % 2 == 0 ? start / 2 : start * 3 + 1); - }; - } - - // Stream of Fibonacci numbers - public static StreamEx fibonacci() { - return fibonacci(BigInteger.ONE, BigInteger.ZERO).stream(); - } - - private static Emitter fibonacci(BigInteger first, BigInteger second) { - return action -> { - BigInteger next = first.add(second); - action.accept(next); - return fibonacci(second, next); - }; - } - - // Perform scanLeft on the iterator - public static Emitter scanLeft(Iterator iter, T initial, BinaryOperator reducer) { - return action -> { - if (!iter.hasNext()) - return null; - T sum = reducer.apply(initial, iter.next()); - action.accept(sum); - return scanLeft(iter, sum, reducer); - }; - } - - public static Emitter flatTest(int start) { - return action -> { - for (int i = 0; i < start; i++) - action.accept(start); - return start == 0 ? null : flatTest(start - 1); - }; - } - - public static IntEmitter flatTestInt(int start) { - return action -> { - for (int i = 0; i < start; i++) - action.accept(start); - return start == 0 ? null : flatTestInt(start - 1); - }; - } - - public static LongEmitter flatTestLong(int start) { - return action -> { - for (int i = 0; i < start; i++) - action.accept(start); - return start == 0 ? null : flatTestLong(start - 1); - }; - } - - public static DoubleEmitter flatTestDouble(int start) { - return action -> { - for (int i = 0; i < start; i++) - action.accept(start); - return start == 0 ? null : flatTestDouble(start - 1); - }; - } - - public static LongStreamEx primes() { - return ((LongEmitter) (action -> { - action.accept(2); - return primes(3, x -> x % 2 != 0); - })).stream(); - } - - private static LongEmitter primes(long start, LongPredicate isPrime) { - return action -> { - long nextPrime = LongStreamEx.range(start, Long.MAX_VALUE, 2).findFirst(isPrime).getAsLong(); - action.accept(nextPrime); - return primes(nextPrime + 2, isPrime.and(x -> x % nextPrime != 0)); - }; - } - - @Test - public void testEmitter() { - assertEquals(asList(17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1), collatz(17).stream().toList()); - checkSpliterator("collatz", asList(17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1), collatz(17)::spliterator); - assertArrayEquals(new int[] {17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1}, collatzInt(17).stream().toArray()); - checkSpliterator("collatzInt", asList(17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1), collatzInt(17)::spliterator); - assertArrayEquals(new long[] {17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1}, collatzLong(17).stream().toArray()); - checkSpliterator("collatzLong", asList(17L, 52L, 26L, 13L, 40L, 20L, 10L, 5L, 16L, 8L, 4L, 2L, 1L), - collatzLong(17)::spliterator); - assertTrue(collatz(17).stream().has(1)); - assertTrue(collatzInt(17).stream().has(1)); - assertFalse(collatzLong(17).stream().has(0)); - assertEquals(asList(1, 2, 3, 4, 5, 6, 7, 8, 9), iterate(1, x -> x < 10, x -> x + 1).stream().toList()); - - // Extracting to variables is necessary to work-around javac <8u40 bug - String expected = "354224848179261915075"; - String actual = fibonacci().skip(99).findFirst().get().toString(); - assertEquals(expected, actual); - assertEquals(asList(1, 1, 2, 3, 5, 8, 13, 21, 34, 55), fibonacci().map(BigInteger::intValueExact).limit(10) - .toList()); - - assertEquals(asList("aa", "aabbb", "aabbbc"), scanLeft(asList("aa", "bbb", "c").iterator(), "", String::concat) - .stream().toList()); - - assertEquals(asList(4, 4, 4, 4, 3, 3, 3, 2, 2, 1), flatTest(4).stream().toList()); - assertEquals(asList(4, 4, 4, 4, 3, 3, 3, 2, 2), flatTest(4).stream().limit(9).toList()); - - checkSpliterator("flatTest", asList(4, 4, 4, 4, 3, 3, 3, 2, 2, 1), flatTest(4)::spliterator); - checkSpliterator("flatTest", asList(4, 4, 4, 4, 3, 3, 3, 2, 2, 1), flatTestInt(4)::spliterator); - checkSpliterator("flatTest", asList(4L, 4L, 4L, 4L, 3L, 3L, 3L, 2L, 2L, 1L), flatTestLong(4)::spliterator); - checkSpliterator("flatTest", asList(4.0, 4.0, 4.0, 4.0, 3.0, 3.0, 3.0, 2.0, 2.0, 1.0), flatTestDouble(4)::spliterator); - - assertEquals(7919L, primes().skip(999).findFirst().getAsLong()); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.math.BigInteger; +import java.util.Iterator; +import java.util.function.BinaryOperator; +import java.util.function.LongPredicate; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.DoubleStreamEx.DoubleEmitter; +import one.util.streamex.IntStreamEx.IntEmitter; +import one.util.streamex.LongStreamEx; +import one.util.streamex.LongStreamEx.LongEmitter; +import one.util.streamex.StreamEx; +import one.util.streamex.StreamEx.Emitter; +import one.util.streamex.TestHelpers; + +import static java.util.Arrays.asList; +import static one.util.streamex.TestHelpers.checkSpliterator; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class EmitterTest { + // Like Java-9 Stream.iterate(seed, test, op) + public static Emitter iterate(T seed, Predicate test, UnaryOperator op) { + return test.test(seed) ? action -> { + action.accept(seed); + return iterate(op.apply(seed), test, op); + } : null; + } + + // Collatz sequence starting from given number + public static Emitter collatz(int start) { + return action -> { + action.accept(start); + return start == 1 ? null : collatz(start % 2 == 0 ? start / 2 : start * 3 + 1); + }; + } + + public static IntEmitter collatzInt(int start) { + return action -> { + action.accept(start); + return start == 1 ? null : collatzInt(start % 2 == 0 ? start / 2 : start * 3 + 1); + }; + } + + public static LongEmitter collatzLong(long start) { + return action -> { + action.accept(start); + return start == 1 ? null : collatzLong(start % 2 == 0 ? start / 2 : start * 3 + 1); + }; + } + + // Stream of Fibonacci numbers + public static StreamEx fibonacci() { + return fibonacci(BigInteger.ONE, BigInteger.ZERO).stream(); + } + + private static Emitter fibonacci(BigInteger first, BigInteger second) { + return action -> { + BigInteger next = first.add(second); + action.accept(next); + return fibonacci(second, next); + }; + } + + // Perform scanLeft on the iterator + public static Emitter scanLeft(Iterator iter, T initial, BinaryOperator reducer) { + return action -> { + if (!iter.hasNext()) + return null; + T sum = reducer.apply(initial, iter.next()); + action.accept(sum); + return scanLeft(iter, sum, reducer); + }; + } + + public static Emitter flatTest(int start) { + return action -> { + for (int i = 0; i < start; i++) + action.accept(start); + return start == 0 ? null : flatTest(start - 1); + }; + } + + public static IntEmitter flatTestInt(int start) { + return action -> { + for (int i = 0; i < start; i++) + action.accept(start); + return start == 0 ? null : flatTestInt(start - 1); + }; + } + + public static LongEmitter flatTestLong(int start) { + return action -> { + for (int i = 0; i < start; i++) + action.accept(start); + return start == 0 ? null : flatTestLong(start - 1); + }; + } + + public static DoubleEmitter flatTestDouble(int start) { + return action -> { + for (int i = 0; i < start; i++) + action.accept(start); + return start == 0 ? null : flatTestDouble(start - 1); + }; + } + + public static LongStreamEx primes() { + return ((LongEmitter) (action -> { + action.accept(2); + return primes(3, x -> x % 2 != 0); + })).stream(); + } + + private static LongEmitter primes(long start, LongPredicate isPrime) { + return action -> { + long nextPrime = LongStreamEx.range(start, Long.MAX_VALUE, 2).findFirst(isPrime).getAsLong(); + action.accept(nextPrime); + return primes(nextPrime + 2, isPrime.and(x -> x % nextPrime != 0)); + }; + } + + @Test + public void testEmitter() { + assertEquals(asList(17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1), collatz(17).stream().toList()); + checkSpliterator("collatz", asList(17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1), collatz(17)::spliterator); + assertArrayEquals(new int[] { 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1 }, + collatzInt(17).stream().toArray()); + checkSpliterator("collatzInt", asList(17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1), + collatzInt(17)::spliterator); + assertArrayEquals(new long[] { 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1 }, + collatzLong(17).stream().toArray()); + checkSpliterator("collatzLong", asList(17L, 52L, 26L, 13L, 40L, 20L, 10L, 5L, 16L, 8L, 4L, 2L, 1L), + collatzLong(17)::spliterator); + assertTrue(collatz(17).stream().has(1)); + assertTrue(collatzInt(17).stream().has(1)); + assertFalse(collatzLong(17).stream().has(0)); + assertEquals(asList(1, 2, 3, 4, 5, 6, 7, 8, 9), iterate(1, x -> x < 10, x -> x + 1).stream().toList()); + + // Extracting to variables is necessary to work-around javac <8u40 bug + String expected = "354224848179261915075"; + String actual = fibonacci().skip(99).findFirst().get().toString(); + assertEquals(expected, actual); + assertEquals(asList(1, 1, 2, 3, 5, 8, 13, 21, 34, 55), fibonacci().map(BigInteger::intValueExact).limit(10) + .toList()); + + assertEquals(asList("aa", "aabbb", "aabbbc"), scanLeft(asList("aa", "bbb", "c").iterator(), "", String::concat) + .stream().toList()); + + assertEquals(asList(4, 4, 4, 4, 3, 3, 3, 2, 2, 1), flatTest(4).stream().toList()); + assertEquals(asList(4, 4, 4, 4, 3, 3, 3, 2, 2), flatTest(4).stream().limit(9).toList()); + + TestHelpers.checkSpliterator("flatTest", asList(4, 4, 4, 4, 3, 3, 3, 2, 2, 1), + flatTest(4)::spliterator); + TestHelpers.checkSpliterator("flatTest", asList(4, 4, 4, 4, 3, 3, 3, 2, 2, 1), + flatTestInt(4)::spliterator); + TestHelpers.checkSpliterator("flatTest", asList(4L, 4L, 4L, 4L, 3L, 3L, 3L, 2L, 2L, 1L), + flatTestLong(4)::spliterator); + TestHelpers.checkSpliterator("flatTest", asList(4.0, 4.0, 4.0, 4.0, 3.0, 3.0, 3.0, 2.0, 2.0, 1.0), + flatTestDouble(4)::spliterator); + + assertEquals(7919L, primes().skip(999).findFirst().getAsLong()); + } +} diff --git a/src/test/java/one/util/streamex/EntryStreamTest.java b/src/test/java/one/util/streamex/api/EntryStreamTest.java similarity index 98% rename from src/test/java/one/util/streamex/EntryStreamTest.java rename to src/test/java/one/util/streamex/api/EntryStreamTest.java index 80e33644..0f7f2f37 100644 --- a/src/test/java/one/util/streamex/EntryStreamTest.java +++ b/src/test/java/one/util/streamex/api/EntryStreamTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015, 2019 StreamEx contributors + * Copyright 2015, 2020 StreamEx contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package one.util.streamex; +package one.util.streamex.api; import java.util.AbstractMap; import java.util.AbstractMap.SimpleEntry; @@ -47,11 +47,15 @@ import org.junit.Test; import org.junit.runners.MethodSorters; -import one.util.streamex.StreamExTest.Point; +import one.util.streamex.EntryStream; +import one.util.streamex.IntStreamEx; +import one.util.streamex.MoreCollectors; +import one.util.streamex.StreamEx; +import one.util.streamex.TestHelpers.Point; import static java.util.Arrays.asList; import static one.util.streamex.TestHelpers.StreamExSupplier; -import static one.util.streamex.TestHelpers.assertThrows; +import static one.util.streamex.TestHelpers.checkAsString; import static one.util.streamex.TestHelpers.checkIllegalStateException; import static one.util.streamex.TestHelpers.entryStream; import static one.util.streamex.TestHelpers.repeat; @@ -63,6 +67,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -71,10 +76,6 @@ */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class EntryStreamTest { - private static void checkAsString(String expected, EntryStream stream) { - assertEquals(expected, stream.join("->").joining(";")); - } - private static Map createMap() { Map data = new LinkedHashMap<>(); data.put("a", 1); @@ -85,11 +86,14 @@ private static Map createMap() { @Test public void testCreate() { + // double test is intended to caugh the bug in `EntryStream.emtpy()` related to sharing object assertEquals(0, EntryStream.empty().count()); assertEquals(0, EntryStream.empty().count()); + Map data = createMap(); assertEquals(data, EntryStream.of(data).toMap()); assertEquals(data, EntryStream.of(data.entrySet().stream()).toMap()); + Map expected = new HashMap<>(); expected.put("aaa", 3); expected.put("bbb", 3); @@ -102,10 +106,6 @@ public void testCreate() { assertEquals(expected, StreamEx.of(Collections.singletonMap("aaa", 3), Collections.singletonMap("bbb", 3), Collections.singletonMap("c", 1), Collections.emptyMap()).flatMapToEntry(m -> m).toMap()); - EntryStream stream = EntryStream.of(data); - assertSame(stream.stream(), EntryStream.of(stream).stream()); - assertSame(stream.stream(), EntryStream.of(StreamEx.of(EntryStream.of(stream))).stream()); - assertEquals(Collections.singletonMap("aaa", 3), EntryStream.of( Collections.singletonMap("aaa", 3).entrySet().spliterator()).toMap()); assertEquals(Collections.singletonMap("aaa", 3), EntryStream.of( @@ -192,7 +192,6 @@ public void testWithIndex() { assertNotEquals(entry, new Object()); assertEquals(new AbstractMap.SimpleImmutableEntry<>(0, "a"), entry); assertEquals(entry, new AbstractMap.SimpleImmutableEntry<>(0, "a")); - assertThrows(UnsupportedOperationException.class, () -> EntryStream.of(Collections.singletonList("1")).forEach(e -> e.setValue("2"))); } diff --git a/src/test/java/one/util/streamex/IntCollectorTest.java b/src/test/java/one/util/streamex/api/IntCollectorTest.java similarity index 97% rename from src/test/java/one/util/streamex/IntCollectorTest.java rename to src/test/java/one/util/streamex/api/IntCollectorTest.java index ab3ed184..84c2d026 100644 --- a/src/test/java/one/util/streamex/IntCollectorTest.java +++ b/src/test/java/one/util/streamex/api/IntCollectorTest.java @@ -1,245 +1,249 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.util.BitSet; -import java.util.IntSummaryStatistics; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static one.util.streamex.TestHelpers.withRandom; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class IntCollectorTest { - @Test - public void testJoining() { - String expected = IntStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining(", ")); - assertEquals(expected, IntStreamEx.range(10000).collect(IntCollector.joining(", "))); - assertEquals(expected, IntStreamEx.range(10000).parallel().collect(IntCollector.joining(", "))); - String expected2 = IntStreamEx.range(0, 1000).boxed().toList().toString(); - assertEquals(expected2, IntStreamEx.range(1000).collect(IntCollector.joining(", ", "[", "]"))); - assertEquals(expected2, IntStreamEx.range(1000).parallel().collect(IntCollector.joining(", ", "[", "]"))); - } - - @Test - public void testCounting() { - assertEquals(5000L, (long) IntStreamEx.range(10000).atLeast(5000).collect(IntCollector.counting())); - assertEquals(5000L, (long) IntStreamEx.range(10000).parallel().atLeast(5000).collect(IntCollector.counting())); - assertEquals(5000, (int) IntStreamEx.range(10000).atLeast(5000).collect(IntCollector.countingInt())); - assertEquals(5000, (int) IntStreamEx.range(10000).parallel().atLeast(5000).collect(IntCollector.countingInt())); - } - - @Test - public void testReducing() { - assertEquals(120, (int) IntStreamEx.rangeClosed(1, 5).collect(IntCollector.reducing(1, (a, b) -> a * b))); - assertEquals(120, (int) IntStreamEx.rangeClosed(1, 5).parallel().collect( - IntCollector.reducing(1, (a, b) -> a * b))); - } - - @Test - public void testCollectingAndThen() { - assertEquals(9, (int) IntStreamEx.rangeClosed(1, 5).collect(IntCollector.joining(",").andThen(String::length))); - } - - @Test - public void testSumming() { - assertEquals(3725, (int) IntStreamEx.range(100).atLeast(50).collect(IntCollector.summing())); - assertEquals(3725, (int) IntStreamEx.range(100).parallel().atLeast(50).collect(IntCollector.summing())); - - withRandom(r -> { - int[] input = IntStreamEx.of(r, 10000, 1, 1000).toArray(); - Map expected = IntStream.of(input).boxed().collect( - Collectors.partitioningBy(i -> i % 2 == 0, Collectors.summingInt(Integer::intValue))); - Map sumEvenOdd = IntStreamEx.of(input).collect( - IntCollector.partitioningBy(i -> i % 2 == 0, IntCollector.summing())); - assertEquals(expected, sumEvenOdd); - sumEvenOdd = IntStreamEx.of(input).parallel().collect( - IntCollector.partitioningBy(i -> i % 2 == 0, IntCollector.summing())); - assertEquals(expected, sumEvenOdd); - }); - } - - @Test - public void testMin() { - assertEquals(50, IntStreamEx.range(100).atLeast(50).collect(IntCollector.min()).getAsInt()); - assertFalse(IntStreamEx.range(100).atLeast(200).collect(IntCollector.min()).isPresent()); - } - - @Test - public void testMax() { - assertEquals(99, IntStreamEx.range(100).atLeast(50).collect(IntCollector.max()).getAsInt()); - assertEquals(99, IntStreamEx.range(100).parallel().atLeast(50).collect(IntCollector.max()).getAsInt()); - assertFalse(IntStreamEx.range(100).atLeast(200).collect(IntCollector.max()).isPresent()); - } - - @Test - public void testSummarizing() { - withRandom(r -> { - int[] data = IntStreamEx.of(r, 1000, 1, Integer.MAX_VALUE).toArray(); - IntSummaryStatistics expected = IntStream.of(data).summaryStatistics(); - IntSummaryStatistics statistics = IntStreamEx.of(data).collect(IntCollector.summarizing()); - assertEquals(expected.getCount(), statistics.getCount()); - assertEquals(expected.getSum(), statistics.getSum()); - assertEquals(expected.getMax(), statistics.getMax()); - assertEquals(expected.getMin(), statistics.getMin()); - statistics = IntStreamEx.of(data).parallel().collect(IntCollector.summarizing()); - assertEquals(expected.getCount(), statistics.getCount()); - assertEquals(expected.getSum(), statistics.getSum()); - assertEquals(expected.getMax(), statistics.getMax()); - assertEquals(expected.getMin(), statistics.getMin()); - }); - } - - @Test - public void testToArray() { - assertArrayEquals(new int[] { 0, 1, 2, 3, 4 }, IntStreamEx.of(0, 1, 2, 3, 4).collect(IntCollector.toArray())); - assertArrayEquals(IntStreamEx.range(1000).toByteArray(), IntStreamEx.range(1000).collect( - IntCollector.toByteArray())); - assertArrayEquals(IntStreamEx.range(1000).toCharArray(), IntStreamEx.range(1000).collect( - IntCollector.toCharArray())); - assertArrayEquals(IntStreamEx.range(1000).toShortArray(), IntStreamEx.range(1000).collect( - IntCollector.toShortArray())); - } - - @SuppressWarnings("SuspiciousMethodCalls") - @Test - public void testPartitioning() { - int[] expectedEven = IntStream.range(0, 1000).map(i -> i * 2).toArray(); - int[] expectedOdd = IntStream.range(0, 1000).map(i -> i * 2 + 1).toArray(); - Map oddEven = IntStreamEx.range(2000).collect(IntCollector.partitioningBy(i -> i % 2 == 0)); - assertTrue(oddEven.containsKey(true)); - assertTrue(oddEven.containsKey(false)); - assertFalse(oddEven.containsKey(null)); - assertFalse(oddEven.containsKey(0)); - assertArrayEquals(expectedEven, oddEven.get(true)); - assertArrayEquals(expectedOdd, oddEven.get(false)); - assertNull(oddEven.get(null)); - assertNull(oddEven.get(0)); - assertEquals(2, oddEven.entrySet().size()); - oddEven = IntStreamEx.range(2000).parallel().collect(IntCollector.partitioningBy(i -> i % 2 == 0)); - assertArrayEquals(expectedEven, oddEven.get(true)); - assertArrayEquals(expectedOdd, oddEven.get(false)); - - IntCollector> partitionMapToArray = IntCollector.partitioningBy(i -> i % 2 == 0, - IntCollector.mapping(i -> i / 2, IntCollector.toArray())); - oddEven = IntStreamEx.range(2000).collect(partitionMapToArray); - int[] ints = IntStreamEx.range(1000).toArray(); - assertArrayEquals(ints, oddEven.get(true)); - assertArrayEquals(ints, oddEven.get(false)); - - Map sums = IntStreamEx.rangeClosed(0, 100).collect( - IntCollector.partitioningBy(i -> i % 2 == 0, IntCollector.summarizing())); - assertEquals(2500, sums.get(false).getSum()); - assertEquals(2550, sums.get(true).getSum()); - } - - @Test - public void testSumBySign() { - withRandom(r -> { - int[] input = r.ints(2000, -1000, 1000).toArray(); - Map sums = IntStreamEx.of(input).collect( - IntCollector.partitioningBy(i -> i > 0, IntCollector.summing())); - Map sumsBoxed = IntStream.of(input).boxed().collect( - Collectors.partitioningBy(i -> i > 0, Collectors.summingInt(Integer::intValue))); - assertEquals(sumsBoxed, sums); - }); - } - - @Test - public void testGroupingBy() { - Map collected = IntStreamEx.range(2000).collect(IntCollector.groupingBy(i -> i % 3)); - for (int i = 0; i < 3; i++) { - int rem = i; - assertArrayEquals(IntStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); - } - collected = IntStreamEx.range(2000).parallel().collect(IntCollector.groupingBy(i -> i % 3)); - for (int i = 0; i < 3; i++) { - int rem = i; - assertArrayEquals(IntStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); - } - - Map mapBitSet = IntStreamEx.range(10).collect( - IntCollector.groupingBy(i -> i % 3, IntCollector.toBitSet())); - assertEquals("{0, 3, 6, 9}", mapBitSet.get(0).toString()); - assertEquals("{1, 4, 7}", mapBitSet.get(1).toString()); - assertEquals("{2, 5, 8}", mapBitSet.get(2).toString()); - } - - @Test - public void testByDigit() { - withRandom(r -> { - int[] input = r.ints(2000, -1000, 1000).toArray(); - IntCollector>> collector = IntCollector.groupingBy(i -> i % 10, IntCollector - .of(Collectors.toList())); - Map> groups = IntStreamEx.of(input).collect(collector); - Map> groupsBoxed = IntStream.of(input).boxed().collect( - Collectors.groupingBy(i -> i % 10)); - assertEquals(groupsBoxed, groups); - }); - } - - @Test - public void testAsCollector() { - assertEquals(499500, (int) IntStream.range(0, 1000).boxed().collect(IntCollector.summing())); - assertEquals(499500, (int) IntStream.range(0, 1000).boxed().parallel().collect(IntCollector.summing())); - assertEquals(1000, (long) IntStream.range(0, 1000).boxed().collect(IntCollector.counting())); - } - - @Test - public void testAdaptor() { - assertEquals(499500, (int) IntStreamEx.range(0, 1000).collect(IntCollector.of(IntCollector.summing()))); - assertEquals(499500, (int) IntStreamEx.range(0, 1000).collect( - IntCollector.of(Collectors.summingInt(Integer::intValue)))); - } - - @Test - public void testMapping() { - assertArrayEquals(IntStreamEx.range(1000).asDoubleStream().toArray(), IntStreamEx.range(1000).collect( - IntCollector.mappingToObj(i -> (double) i, DoubleCollector.toArray())), 0.0); - } - - @Test - public void testAveraging() { - assertFalse(IntStreamEx.empty().collect(IntCollector.averaging()).isPresent()); - assertEquals(Integer.MAX_VALUE, IntStreamEx.of(Integer.MAX_VALUE, Integer.MAX_VALUE).collect( - IntCollector.averaging()).getAsDouble(), 1); - assertEquals(Integer.MAX_VALUE, IntStreamEx.of(Integer.MAX_VALUE, Integer.MAX_VALUE).parallel().collect( - IntCollector.averaging()).getAsDouble(), 1); - } - - @Test - public void testToBooleanArray() { - assertArrayEquals(new boolean[0], IntStreamEx.empty().collect(IntCollector.toBooleanArray(x -> true))); - boolean[] expected = new boolean[] { true, false, false, true }; - assertArrayEquals(expected, IntStreamEx.of(-1, 2, 3, -4).collect(IntCollector.toBooleanArray(x -> x < 0))); - assertArrayEquals(expected, IntStreamEx.of(-1, 2, 3, -4).parallel().collect( - IntCollector.toBooleanArray(x -> x < 0))); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.util.BitSet; +import java.util.IntSummaryStatistics; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.DoubleCollector; +import one.util.streamex.IntCollector; +import one.util.streamex.IntStreamEx; + +import static one.util.streamex.TestHelpers.withRandom; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class IntCollectorTest { + @Test + public void testJoining() { + String expected = IntStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining(", ")); + assertEquals(expected, IntStreamEx.range(10000).collect(IntCollector.joining(", "))); + assertEquals(expected, IntStreamEx.range(10000).parallel().collect(IntCollector.joining(", "))); + String expected2 = IntStreamEx.range(0, 1000).boxed().toList().toString(); + assertEquals(expected2, IntStreamEx.range(1000).collect(IntCollector.joining(", ", "[", "]"))); + assertEquals(expected2, IntStreamEx.range(1000).parallel().collect(IntCollector.joining(", ", "[", "]"))); + } + + @Test + public void testCounting() { + assertEquals(5000L, (long) IntStreamEx.range(10000).atLeast(5000).collect(IntCollector.counting())); + assertEquals(5000L, (long) IntStreamEx.range(10000).parallel().atLeast(5000).collect(IntCollector.counting())); + assertEquals(5000, (int) IntStreamEx.range(10000).atLeast(5000).collect(IntCollector.countingInt())); + assertEquals(5000, (int) IntStreamEx.range(10000).parallel().atLeast(5000).collect(IntCollector.countingInt())); + } + + @Test + public void testReducing() { + assertEquals(120, (int) IntStreamEx.rangeClosed(1, 5).collect(IntCollector.reducing(1, (a, b) -> a * b))); + assertEquals(120, (int) IntStreamEx.rangeClosed(1, 5).parallel().collect( + IntCollector.reducing(1, (a, b) -> a * b))); + } + + @Test + public void testCollectingAndThen() { + assertEquals(9, (int) IntStreamEx.rangeClosed(1, 5).collect(IntCollector.joining(",").andThen(String::length))); + } + + @Test + public void testSumming() { + assertEquals(3725, (int) IntStreamEx.range(100).atLeast(50).collect(IntCollector.summing())); + assertEquals(3725, (int) IntStreamEx.range(100).parallel().atLeast(50).collect(IntCollector.summing())); + + withRandom(r -> { + int[] input = IntStreamEx.of(r, 10000, 1, 1000).toArray(); + Map expected = IntStream.of(input).boxed().collect( + Collectors.partitioningBy(i -> i % 2 == 0, Collectors.summingInt(Integer::intValue))); + Map sumEvenOdd = IntStreamEx.of(input).collect( + IntCollector.partitioningBy(i -> i % 2 == 0, IntCollector.summing())); + assertEquals(expected, sumEvenOdd); + sumEvenOdd = IntStreamEx.of(input).parallel().collect( + IntCollector.partitioningBy(i -> i % 2 == 0, IntCollector.summing())); + assertEquals(expected, sumEvenOdd); + }); + } + + @Test + public void testMin() { + assertEquals(50, IntStreamEx.range(100).atLeast(50).collect(IntCollector.min()).getAsInt()); + assertFalse(IntStreamEx.range(100).atLeast(200).collect(IntCollector.min()).isPresent()); + } + + @Test + public void testMax() { + assertEquals(99, IntStreamEx.range(100).atLeast(50).collect(IntCollector.max()).getAsInt()); + assertEquals(99, IntStreamEx.range(100).parallel().atLeast(50).collect(IntCollector.max()).getAsInt()); + assertFalse(IntStreamEx.range(100).atLeast(200).collect(IntCollector.max()).isPresent()); + } + + @Test + public void testSummarizing() { + withRandom(r -> { + int[] data = IntStreamEx.of(r, 1000, 1, Integer.MAX_VALUE).toArray(); + IntSummaryStatistics expected = IntStream.of(data).summaryStatistics(); + IntSummaryStatistics statistics = IntStreamEx.of(data).collect(IntCollector.summarizing()); + assertEquals(expected.getCount(), statistics.getCount()); + assertEquals(expected.getSum(), statistics.getSum()); + assertEquals(expected.getMax(), statistics.getMax()); + assertEquals(expected.getMin(), statistics.getMin()); + statistics = IntStreamEx.of(data).parallel().collect(IntCollector.summarizing()); + assertEquals(expected.getCount(), statistics.getCount()); + assertEquals(expected.getSum(), statistics.getSum()); + assertEquals(expected.getMax(), statistics.getMax()); + assertEquals(expected.getMin(), statistics.getMin()); + }); + } + + @Test + public void testToArray() { + assertArrayEquals(new int[] { 0, 1, 2, 3, 4 }, IntStreamEx.of(0, 1, 2, 3, 4).collect(IntCollector.toArray())); + assertArrayEquals(IntStreamEx.range(1000).toByteArray(), IntStreamEx.range(1000).collect( + IntCollector.toByteArray())); + assertArrayEquals(IntStreamEx.range(1000).toCharArray(), IntStreamEx.range(1000).collect( + IntCollector.toCharArray())); + assertArrayEquals(IntStreamEx.range(1000).toShortArray(), IntStreamEx.range(1000).collect( + IntCollector.toShortArray())); + } + + @SuppressWarnings("SuspiciousMethodCalls") + @Test + public void testPartitioning() { + int[] expectedEven = IntStream.range(0, 1000).map(i -> i * 2).toArray(); + int[] expectedOdd = IntStream.range(0, 1000).map(i -> i * 2 + 1).toArray(); + Map oddEven = IntStreamEx.range(2000).collect(IntCollector.partitioningBy(i -> i % 2 == 0)); + assertTrue(oddEven.containsKey(true)); + assertTrue(oddEven.containsKey(false)); + assertFalse(oddEven.containsKey(null)); + assertFalse(oddEven.containsKey(0)); + assertArrayEquals(expectedEven, oddEven.get(true)); + assertArrayEquals(expectedOdd, oddEven.get(false)); + assertNull(oddEven.get(null)); + assertNull(oddEven.get(0)); + assertEquals(2, oddEven.entrySet().size()); + oddEven = IntStreamEx.range(2000).parallel().collect(IntCollector.partitioningBy(i -> i % 2 == 0)); + assertArrayEquals(expectedEven, oddEven.get(true)); + assertArrayEquals(expectedOdd, oddEven.get(false)); + + IntCollector> partitionMapToArray = IntCollector.partitioningBy(i -> i % 2 == 0, + IntCollector.mapping(i -> i / 2, IntCollector.toArray())); + oddEven = IntStreamEx.range(2000).collect(partitionMapToArray); + int[] ints = IntStreamEx.range(1000).toArray(); + assertArrayEquals(ints, oddEven.get(true)); + assertArrayEquals(ints, oddEven.get(false)); + + Map sums = IntStreamEx.rangeClosed(0, 100).collect( + IntCollector.partitioningBy(i -> i % 2 == 0, IntCollector.summarizing())); + assertEquals(2500, sums.get(false).getSum()); + assertEquals(2550, sums.get(true).getSum()); + } + + @Test + public void testSumBySign() { + withRandom(r -> { + int[] input = r.ints(2000, -1000, 1000).toArray(); + Map sums = IntStreamEx.of(input).collect( + IntCollector.partitioningBy(i -> i > 0, IntCollector.summing())); + Map sumsBoxed = IntStream.of(input).boxed().collect( + Collectors.partitioningBy(i -> i > 0, Collectors.summingInt(Integer::intValue))); + assertEquals(sumsBoxed, sums); + }); + } + + @Test + public void testGroupingBy() { + Map collected = IntStreamEx.range(2000).collect(IntCollector.groupingBy(i -> i % 3)); + for (int i = 0; i < 3; i++) { + int rem = i; + assertArrayEquals(IntStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); + } + collected = IntStreamEx.range(2000).parallel().collect(IntCollector.groupingBy(i -> i % 3)); + for (int i = 0; i < 3; i++) { + int rem = i; + assertArrayEquals(IntStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); + } + + Map mapBitSet = IntStreamEx.range(10).collect( + IntCollector.groupingBy(i -> i % 3, IntCollector.toBitSet())); + assertEquals("{0, 3, 6, 9}", mapBitSet.get(0).toString()); + assertEquals("{1, 4, 7}", mapBitSet.get(1).toString()); + assertEquals("{2, 5, 8}", mapBitSet.get(2).toString()); + } + + @Test + public void testByDigit() { + withRandom(r -> { + int[] input = r.ints(2000, -1000, 1000).toArray(); + IntCollector>> collector = IntCollector.groupingBy(i -> i % 10, IntCollector + .of(Collectors.toList())); + Map> groups = IntStreamEx.of(input).collect(collector); + Map> groupsBoxed = IntStream.of(input).boxed().collect( + Collectors.groupingBy(i -> i % 10)); + assertEquals(groupsBoxed, groups); + }); + } + + @Test + public void testAsCollector() { + assertEquals(499500, (int) IntStream.range(0, 1000).boxed().collect(IntCollector.summing())); + assertEquals(499500, (int) IntStream.range(0, 1000).boxed().parallel().collect(IntCollector.summing())); + assertEquals(1000, (long) IntStream.range(0, 1000).boxed().collect(IntCollector.counting())); + } + + @Test + public void testAdaptor() { + assertEquals(499500, (int) IntStreamEx.range(0, 1000).collect(IntCollector.of(IntCollector.summing()))); + assertEquals(499500, (int) IntStreamEx.range(0, 1000).collect( + IntCollector.of(Collectors.summingInt(Integer::intValue)))); + } + + @Test + public void testMapping() { + assertArrayEquals(IntStreamEx.range(1000).asDoubleStream().toArray(), IntStreamEx.range(1000).collect( + IntCollector.mappingToObj(i -> (double) i, DoubleCollector.toArray())), 0.0); + } + + @Test + public void testAveraging() { + assertFalse(IntStreamEx.empty().collect(IntCollector.averaging()).isPresent()); + assertEquals(Integer.MAX_VALUE, IntStreamEx.of(Integer.MAX_VALUE, Integer.MAX_VALUE).collect( + IntCollector.averaging()).getAsDouble(), 1); + assertEquals(Integer.MAX_VALUE, IntStreamEx.of(Integer.MAX_VALUE, Integer.MAX_VALUE).parallel().collect( + IntCollector.averaging()).getAsDouble(), 1); + } + + @Test + public void testToBooleanArray() { + assertArrayEquals(new boolean[0], IntStreamEx.empty().collect(IntCollector.toBooleanArray(x -> true))); + boolean[] expected = new boolean[] { true, false, false, true }; + assertArrayEquals(expected, IntStreamEx.of(-1, 2, 3, -4).collect(IntCollector.toBooleanArray(x -> x < 0))); + assertArrayEquals(expected, IntStreamEx.of(-1, 2, 3, -4).parallel().collect( + IntCollector.toBooleanArray(x -> x < 0))); + } +} diff --git a/src/test/java/one/util/streamex/IntStreamExTest.java b/src/test/java/one/util/streamex/api/IntStreamExTest.java similarity index 97% rename from src/test/java/one/util/streamex/IntStreamExTest.java rename to src/test/java/one/util/streamex/api/IntStreamExTest.java index 1739e906..25eb38b0 100644 --- a/src/test/java/one/util/streamex/IntStreamExTest.java +++ b/src/test/java/one/util/streamex/api/IntStreamExTest.java @@ -1,802 +1,805 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.BitSet; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.OptionalInt; -import java.util.PrimitiveIterator.OfInt; -import java.util.Random; -import java.util.Scanner; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; -import java.util.function.IntBinaryOperator; -import java.util.function.IntFunction; -import java.util.function.IntToDoubleFunction; -import java.util.function.IntToLongFunction; -import java.util.function.IntUnaryOperator; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.IntStream.Builder; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static one.util.streamex.TestHelpers.assertThrows; -import static one.util.streamex.TestHelpers.checkSpliterator; -import static one.util.streamex.TestHelpers.intStreamEx; -import static one.util.streamex.TestHelpers.streamEx; -import static one.util.streamex.TestHelpers.withRandom; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class IntStreamExTest { - private static final byte[] EVEN_BYTES = new byte[] { 2, 4, 6, 8, 10 }; - - @Test - public void testCreate() { - assertArrayEquals(new int[] {}, IntStreamEx.empty().toArray()); - // double test is intended - assertArrayEquals(new int[] {}, IntStreamEx.empty().toArray()); - assertArrayEquals(new int[] { 1 }, IntStreamEx.of(1).toArray()); - assertArrayEquals(new int[] { 1 }, IntStreamEx.of(OptionalInt.of(1)).toArray()); - assertArrayEquals(new int[] {}, IntStreamEx.of(OptionalInt.empty()).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 3).toArray()); - assertArrayEquals(new int[] { 4, 6 }, IntStreamEx.of(new int[] { 2, 4, 6, 8, 10 }, 1, 3).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(new byte[] { 1, 2, 3 }).toArray()); - assertArrayEquals(new int[] { 4, 6 }, IntStreamEx.of(EVEN_BYTES, 1, 3).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(new short[] { 1, 2, 3 }).toArray()); - assertArrayEquals(new int[] { 4, 6 }, IntStreamEx.of(new short[] { 2, 4, 6, 8, 10 }, 1, 3).toArray()); - assertArrayEquals(new int[] { 'a', 'b', 'c' }, IntStreamEx.of('a', 'b', 'c').toArray()); - assertArrayEquals(new int[] { '1', 'b' }, IntStreamEx.of(new char[] { 'a', '1', 'b', '2', 'c', '3' }, 1, 3) - .toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(IntStream.of(1, 2, 3)).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(Arrays.asList(1, 2, 3)).toArray()); - assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.range(3).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.range(1, 4).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.rangeClosed(1, 3).toArray()); - assertArrayEquals(new int[] { 1, 1, 1, 1 }, IntStreamEx.generate(() -> 1).limit(4).toArray()); - assertArrayEquals(new int[] { 1, 1, 1, 1 }, IntStreamEx.constant(1, 4).toArray()); - assertArrayEquals(new int[] { 'a', 'b', 'c' }, IntStreamEx.ofChars("abc").toArray()); - assertEquals(10, IntStreamEx.of(new Random(), 10).count()); - assertTrue(IntStreamEx.of(new Random(), 100, 1, 10).allMatch(x -> x >= 1 && x < 10)); - assertArrayEquals(IntStreamEx.of(new Random(1), 100, 1, 10).toArray(), IntStreamEx.of(new Random(1), 1, 10) - .limit(100).toArray()); - - IntStream stream = IntStreamEx.of(1, 2, 3); - assertSame(stream, IntStreamEx.of(stream)); - - assertArrayEquals(new int[] { 4, 2, 0, -2, -4 }, IntStreamEx.zip(new int[] { 5, 4, 3, 2, 1 }, - new int[] { 1, 2, 3, 4, 5 }, (a, b) -> a - b).toArray()); - - assertArrayEquals(new int[] { 1, 5, 3 }, IntStreamEx.of(Spliterators.spliterator(new int[] { 1, 5, 3 }, 0)) - .toArray()); - assertArrayEquals(new int[] { 1, 5, 3 }, IntStreamEx.of( - Spliterators.iterator(Spliterators.spliterator(new int[] { 1, 5, 3 }, 0))).toArray()); - assertArrayEquals(new int[0], IntStreamEx.of(Spliterators.iterator(Spliterators.emptyIntSpliterator())) - .parallel().toArray()); - - BitSet bs = new BitSet(); - bs.set(1); - bs.set(3); - bs.set(5); - assertArrayEquals(new int[] { 1, 3, 5 }, IntStreamEx.of(bs).toArray()); - - assertArrayEquals(new int[] { 2, 4, 6 }, IntStreamEx.of(new Integer[] { 2, 4, 6 }).toArray()); - } - - @Test - public void testOfIntBuffer() { - int[] data = IntStreamEx.range(100).toArray(); - assertArrayEquals(data, IntStreamEx.of(IntBuffer.wrap(data)).toArray()); - assertArrayEquals(IntStreamEx.range(50, 70).toArray(), IntStreamEx.of(IntBuffer.wrap(data, 50, 20)).toArray()); - assertArrayEquals(data, IntStreamEx.of(IntBuffer.wrap(data)).parallel().toArray()); - assertArrayEquals(IntStreamEx.range(50, 70).toArray(), IntStreamEx.of(IntBuffer.wrap(data, 50, 20)).parallel() - .toArray()); - } - - @Test - public void testIterate() { - assertArrayEquals(new int[] { 1, 2, 4, 8, 16 }, IntStreamEx.iterate(1, x -> x * 2).limit(5).toArray()); - assertArrayEquals(new int[] { 1, 2, 4, 8, 16, 32, 64 }, IntStreamEx.iterate(1, x -> x < 100, x -> x * 2).toArray()); - assertEquals(0, IntStreamEx.iterate(0, x -> x < 0, x -> 1 / x).count()); - assertFalse(IntStreamEx.iterate(1, x -> x < 100, x -> x * 2).has(10)); - checkSpliterator("iterate", () -> IntStreamEx.iterate(1, x -> x < 100, x -> x * 2).spliterator()); - } - - @Test - public void testInts() { - assertEquals(Integer.MAX_VALUE, IntStreamEx.ints().spliterator().getExactSizeIfKnown()); - assertArrayEquals(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, IntStreamEx.ints().limit(10).toArray()); - } - - @Test - public void testRangeStep() { - assertArrayEquals(new int[] { 0 }, IntStreamEx.range(0, 1000, 100000).toArray()); - assertArrayEquals(new int[] { 0 }, IntStreamEx.range(0, 1000, 1000).toArray()); - assertArrayEquals(new int[] { 0, Integer.MAX_VALUE - 1 }, IntStreamEx.range(0, Integer.MAX_VALUE, - Integer.MAX_VALUE - 1).toArray()); - assertArrayEquals(new int[] { Integer.MIN_VALUE, -1, Integer.MAX_VALUE - 1 }, IntStreamEx.range( - Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).toArray()); - assertArrayEquals(new int[] { Integer.MIN_VALUE, -1 }, IntStreamEx.range(Integer.MIN_VALUE, - Integer.MAX_VALUE - 1, Integer.MAX_VALUE).toArray()); - assertArrayEquals(new int[] { Integer.MAX_VALUE, -1 }, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE, - Integer.MIN_VALUE).toArray()); - assertArrayEquals(new int[] { Integer.MAX_VALUE }, IntStreamEx.range(Integer.MAX_VALUE, 0, Integer.MIN_VALUE) - .toArray()); - assertArrayEquals(new int[] { 1, Integer.MIN_VALUE + 1 }, IntStreamEx.range(1, Integer.MIN_VALUE, - Integer.MIN_VALUE).toArray()); - assertArrayEquals(new int[] { 0 }, IntStreamEx.range(0, Integer.MIN_VALUE, Integer.MIN_VALUE).toArray()); - assertArrayEquals(new int[] { 0, 2, 4, 6, 8 }, IntStreamEx.range(0, 9, 2).toArray()); - assertArrayEquals(new int[] { 0, 2, 4, 6 }, IntStreamEx.range(0, 8, 2).toArray()); - assertArrayEquals(new int[] { 0, -2, -4, -6, -8 }, IntStreamEx.range(0, -9, -2).toArray()); - assertArrayEquals(new int[] { 0, -2, -4, -6 }, IntStreamEx.range(0, -8, -2).toArray()); - assertArrayEquals(new int[] { 5, 4, 3, 2, 1, 0 }, IntStreamEx.range(5, -1, -1).toArray()); - assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE, 2).spliterator() - .getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE, IntStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE - 1, 2).spliterator() - .getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE, -2).spliterator() - .getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE + 1, -2).spliterator() - .getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE * 2L + 1L, IntStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE, 1) - .spliterator().getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE * 2L + 1L, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE, -1) - .spliterator().getExactSizeIfKnown()); - assertEquals(0, IntStreamEx.range(0, -1000, 1).count()); - assertEquals(0, IntStreamEx.range(0, 1000, -1).count()); - assertEquals(0, IntStreamEx.range(0, 0, -1).count()); - assertEquals(0, IntStreamEx.range(0, 0, 1).count()); - assertEquals(0, IntStreamEx.range(0, -1000, 2).count()); - assertEquals(0, IntStreamEx.range(0, 1000, -2).count()); - assertEquals(0, IntStreamEx.range(0, 0, -2).count()); - assertEquals(0, IntStreamEx.range(0, 0, 2).count()); - - assertEquals(0, IntStreamEx.range(0, Integer.MIN_VALUE, 2).spliterator().getExactSizeIfKnown()); - assertEquals(0, IntStreamEx.range(0, Integer.MAX_VALUE, -2).spliterator().getExactSizeIfKnown()); - - assertThrows(IllegalArgumentException.class, () -> IntStreamEx.range(0, 1000, 0)); - } - - @Test - public void testRangeClosedStep() { - assertArrayEquals(new int[] { 0 }, IntStreamEx.rangeClosed(0, 1000, 100000).toArray()); - assertArrayEquals(new int[] { 0, 1000 }, IntStreamEx.rangeClosed(0, 1000, 1000).toArray()); - assertArrayEquals(new int[] { 0, Integer.MAX_VALUE - 1 }, IntStreamEx.rangeClosed(0, Integer.MAX_VALUE, - Integer.MAX_VALUE - 1).toArray()); - assertArrayEquals(new int[] { 0, Integer.MAX_VALUE }, IntStreamEx.rangeClosed(0, Integer.MAX_VALUE, - Integer.MAX_VALUE).toArray()); - assertArrayEquals(new int[] { Integer.MIN_VALUE, -1, Integer.MAX_VALUE - 1 }, IntStreamEx.rangeClosed( - Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).toArray()); - assertArrayEquals(new int[] { Integer.MIN_VALUE, -1, Integer.MAX_VALUE - 1 }, IntStreamEx.rangeClosed( - Integer.MIN_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE).toArray()); - assertArrayEquals(new int[] { Integer.MAX_VALUE, -1 }, IntStreamEx.rangeClosed(Integer.MAX_VALUE, - Integer.MIN_VALUE, Integer.MIN_VALUE).toArray()); - assertArrayEquals(new int[] { Integer.MAX_VALUE }, IntStreamEx.rangeClosed(Integer.MAX_VALUE, 0, - Integer.MIN_VALUE).toArray()); - assertArrayEquals(new int[] { 0, Integer.MIN_VALUE }, IntStreamEx.rangeClosed(0, Integer.MIN_VALUE, - Integer.MIN_VALUE).toArray()); - assertArrayEquals(new int[] { 0, 2, 4, 6, 8 }, IntStreamEx.rangeClosed(0, 9, 2).toArray()); - assertArrayEquals(new int[] { 0, 2, 4, 6, 8 }, IntStreamEx.rangeClosed(0, 8, 2).toArray()); - assertArrayEquals(new int[] { 0, 2, 4, 6 }, IntStreamEx.rangeClosed(0, 7, 2).toArray()); - assertArrayEquals(new int[] { 0, -2, -4, -6, -8 }, IntStreamEx.rangeClosed(0, -9, -2).toArray()); - assertArrayEquals(new int[] { 0, -2, -4, -6, -8 }, IntStreamEx.rangeClosed(0, -8, -2).toArray()); - assertArrayEquals(new int[] { 0, -2, -4, -6 }, IntStreamEx.rangeClosed(0, -7, -2).toArray()); - assertArrayEquals(new int[] { 5, 4, 3, 2, 1, 0 }, IntStreamEx.rangeClosed(5, 0, -1).toArray()); - assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE, 2) - .spliterator().getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE - 1, 2) - .spliterator().getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE - 2, 2) - .spliterator().getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MAX_VALUE, Integer.MIN_VALUE, -2) - .spliterator().getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MAX_VALUE, Integer.MIN_VALUE + 1, -2) - .spliterator().getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE * 2L + 2L, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE, 1) - .spliterator().getExactSizeIfKnown()); - assertEquals(Integer.MAX_VALUE * 2L + 2L, IntStreamEx.rangeClosed(Integer.MAX_VALUE, Integer.MIN_VALUE, -1) - .spliterator().getExactSizeIfKnown()); - assertEquals(0, IntStreamEx.rangeClosed(0, -1000, 1).count()); - assertEquals(0, IntStreamEx.rangeClosed(0, 1000, -1).count()); - assertEquals(0, IntStreamEx.rangeClosed(0, 1, -1).count()); - assertEquals(0, IntStreamEx.rangeClosed(0, -1, 1).count()); - assertEquals(0, IntStreamEx.rangeClosed(0, -1000, 2).count()); - assertEquals(0, IntStreamEx.rangeClosed(0, 1000, -2).count()); - assertEquals(0, IntStreamEx.rangeClosed(0, 1, -2).count()); - assertEquals(0, IntStreamEx.rangeClosed(0, -1, 2).count()); - assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, 1).toArray()); - assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, 2).toArray()); - assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 11, 2).toArray()); - assertArrayEquals(new int[] {}, IntStreamEx.rangeClosed(11, 10, 2).toArray()); - assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, -1).toArray()); - assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, -2).toArray()); - assertArrayEquals(new int[] {}, IntStreamEx.rangeClosed(10, 11, -2).toArray()); - assertArrayEquals(new int[] {11}, IntStreamEx.rangeClosed(11, 10, -2).toArray()); - - assertThrows(ArrayIndexOutOfBoundsException.class, () -> IntStreamEx.of(EVEN_BYTES, -1, 3).findAny()); - assertThrows(ArrayIndexOutOfBoundsException.class, () -> IntStreamEx.of(EVEN_BYTES, 3, 1).findAny()); - assertThrows(ArrayIndexOutOfBoundsException.class, () -> IntStreamEx.of(EVEN_BYTES, 3, 6).findAny()); - } - - @Test - public void testArrayLengthOk() { - assertEquals(10, IntStreamEx.of(EVEN_BYTES, 3, 5).skip(1).findFirst().getAsInt()); - } - - @Test - public void testOfIndices() { - assertArrayEquals(new int[] {}, IntStreamEx.ofIndices(new int[0]).toArray()); - assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new int[] { 5, -100, 1 }).toArray()); - assertArrayEquals(new int[] { 0, 2 }, IntStreamEx.ofIndices(new int[] { 5, -100, 1 }, i -> i > 0).toArray()); - assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new long[] { 5, -100, 1 }).toArray()); - assertArrayEquals(new int[] { 0, 2 }, IntStreamEx.ofIndices(new long[] { 5, -100, 1 }, i -> i > 0).toArray()); - assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new double[] { 5, -100, 1 }).toArray()); - assertArrayEquals(new int[] { 0, 2 }, IntStreamEx.ofIndices(new double[] { 5, -100, 1 }, i -> i > 0).toArray()); - assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new String[] { "a", "b", "c" }).toArray()); - assertArrayEquals(new int[] { 1 }, IntStreamEx.ofIndices(new String[] { "a", "", "c" }, String::isEmpty) - .toArray()); - assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(Arrays.asList("a", "b", "c")).toArray()); - assertArrayEquals(new int[] { 1 }, IntStreamEx.ofIndices(Arrays.asList("a", "", "c"), String::isEmpty) - .toArray()); - } - - @Test - public void testBasics() { - assertFalse(IntStreamEx.of(1).isParallel()); - assertTrue(IntStreamEx.of(1).parallel().isParallel()); - assertFalse(IntStreamEx.of(1).parallel().sequential().isParallel()); - AtomicInteger i = new AtomicInteger(); - try (IntStreamEx s = IntStreamEx.of(1).onClose(i::incrementAndGet)) { - assertEquals(1, s.count()); - } - assertEquals(1, i.get()); - assertEquals(6, IntStreamEx.range(0, 4).sum()); - assertEquals(3, IntStreamEx.range(0, 4).max().getAsInt()); - assertEquals(0, IntStreamEx.range(0, 4).min().getAsInt()); - assertEquals(1.5, IntStreamEx.range(0, 4).average().getAsDouble(), 0.000001); - assertEquals(4, IntStreamEx.range(0, 4).summaryStatistics().getCount()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.range(0, 5).skip(1).limit(3).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(3, 1, 2).sorted().toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 1, 3, 2).distinct().toArray()); - assertArrayEquals(new int[] { 2, 4, 6 }, IntStreamEx.range(1, 4).map(x -> x * 2).toArray()); - assertArrayEquals(new long[] { 2, 4, 6 }, IntStreamEx.range(1, 4).mapToLong(x -> x * 2).toArray()); - assertArrayEquals(new double[] { 2, 4, 6 }, IntStreamEx.range(1, 4).mapToDouble(x -> x * 2).toArray(), 0.0); - assertArrayEquals(new int[] { 1, 3 }, IntStreamEx.range(0, 5).filter(x -> x % 2 == 1).toArray()); - assertEquals(6, IntStreamEx.of(1, 2, 3).reduce(Integer::sum).getAsInt()); - assertEquals(Integer.MAX_VALUE, IntStreamEx.rangeClosed(1, Integer.MAX_VALUE).spliterator() - .getExactSizeIfKnown()); - - assertTrue(IntStreamEx.of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)); - assertFalse(IntStreamEx.of(1, 2, 3).unordered().spliterator().hasCharacteristics(Spliterator.ORDERED)); - - OfInt iterator = IntStreamEx.of(1, 2, 3).iterator(); - assertEquals(1, iterator.nextInt()); - assertEquals(2, iterator.nextInt()); - assertEquals(3, iterator.nextInt()); - assertFalse(iterator.hasNext()); - - List list = new ArrayList<>(); - IntStreamEx.range(10).parallel().forEachOrdered(list::add); - assertEquals(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), list); - - assertTrue(IntStreamEx.empty().noneMatch(x -> true)); - assertFalse(IntStreamEx.of(1).noneMatch(x -> true)); - assertTrue(IntStreamEx.of(1).noneMatch(x -> false)); - } - - @Test - public void testForEach() { - streamEx(() -> StreamEx.of(1, 2, 3), s -> { - AtomicInteger count = new AtomicInteger(0); - s.get().mapToInt(Integer::intValue).forEach(count::addAndGet); - assertEquals(6, count.get()); - s.get().mapToInt(Integer::intValue).pairMap((a, b) -> b - a).forEach(count::addAndGet); - assertEquals(8, count.get()); - }); - } - - @Test - public void testFlatMap() { - long[][] vals = { { 1, 2, 3 }, { 2, 3, 4 }, { 5, 4, Long.MAX_VALUE, Long.MIN_VALUE } }; - assertArrayEquals(new long[] { 1, 2, 3, 2, 3, 4, 5, 4, Long.MAX_VALUE, Long.MIN_VALUE }, IntStreamEx.ofIndices( - vals).flatMapToLong(idx -> Arrays.stream(vals[idx])).toArray()); - String expected = IntStream.range(0, 200).boxed().flatMap( - i -> IntStream.range(0, i).mapToObj(j -> i + ":" + j)).collect(Collectors.joining("/")); - String res = IntStreamEx.range(200).flatMapToObj(i -> IntStreamEx.range(i).mapToObj(j -> i + ":" + j)).joining( - "/"); - String parallel = IntStreamEx.range(200).parallel().flatMapToObj( - i -> IntStreamEx.range(i).mapToObj(j -> i + ":" + j)).joining("/"); - assertEquals(expected, res); - assertEquals(expected, parallel); - - double[] fractions = IntStreamEx.range(1, 5).flatMapToDouble( - i -> IntStreamEx.range(1, i).mapToDouble(j -> ((double) j) / i)).toArray(); - assertArrayEquals(new double[] { 1 / 2.0, 1 / 3.0, 2 / 3.0, 1 / 4.0, 2 / 4.0, 3 / 4.0 }, fractions, 0.000001); - - assertArrayEquals(new int[] { 0, 0, 1, 0, 1, 2 }, IntStreamEx.of(1, 2, 3).flatMap(IntStreamEx::range).toArray()); - } - - @Test - public void testElements() { - assertEquals(Arrays.asList("f", "d", "b"), IntStreamEx.of(5, 3, 1).elements("abcdef".split("")).toList()); - assertEquals(Arrays.asList("f", "d", "b"), IntStreamEx.of(5, 3, 1).elements( - Arrays.asList("a", "b", "c", "d", "e", "f")).toList()); - assertArrayEquals(new int[] { 10, 6, 2 }, IntStreamEx.of(5, 3, 1).elements(new int[] { 0, 2, 4, 6, 8, 10 }) - .toArray()); - assertArrayEquals(new long[] { 10, 6, 2 }, IntStreamEx.of(5, 3, 1).elements(new long[] { 0, 2, 4, 6, 8, 10 }) - .toArray()); - assertArrayEquals(new double[] { 10, 6, 2 }, IntStreamEx.of(5, 3, 1).elements( - new double[] { 0, 2, 4, 6, 8, 10 }).toArray(), 0.0); - } - - @Test - public void testPrepend() { - assertArrayEquals(new int[] { -1, 0, 1, 2, 3 }, IntStreamEx.of(1, 2, 3).prepend(-1, 0).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 3).prepend().toArray()); - assertArrayEquals(new int[] { 10, 11, 0, 1, 2, 3 }, IntStreamEx.range(0, 4).prepend(IntStreamEx.range(10, 12)) - .toArray()); - } - - @Test - public void testAppend() { - assertArrayEquals(new int[] { 1, 2, 3, 4, 5 }, IntStreamEx.of(1, 2, 3).append(4, 5).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 3).append().toArray()); - assertArrayEquals(new int[] { 0, 1, 2, 3, 10, 11 }, IntStreamEx.range(0, 4).append(IntStreamEx.range(10, 12)) - .toArray()); - } - - @Test - public void testHas() { - assertTrue(IntStreamEx.range(1, 4).has(3)); - assertFalse(IntStreamEx.range(1, 4).has(4)); - } - - @Test - public void testWithout() { - assertArrayEquals(new int[] { 1, 2 }, IntStreamEx.range(1, 4).without(3).toArray()); - assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.range(1, 4).without(5).toArray()); - IntStreamEx ise = IntStreamEx.range(5); - assertSame(ise, ise.without()); - assertArrayEquals(new int[] { 0, 1, 3, 4 }, IntStreamEx.range(5).without(new int[] { 2 }).toArray()); - assertArrayEquals(new int[] { 0 }, IntStreamEx.range(5).without(1, 2, 3, 4, 5, 6).toArray()); - } - - @Test - public void testRanges() { - assertArrayEquals(new int[] { 5, 4, Integer.MAX_VALUE }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE) - .greater(3).toArray()); - assertArrayEquals(new int[] { 5, 3, 4, Integer.MAX_VALUE }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE) - .atLeast(3).toArray()); - assertArrayEquals(new int[] { 1, -1 }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE).less(3).toArray()); - assertArrayEquals(new int[] { 1, 3, -1 }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE).atMost(3).toArray()); - assertArrayEquals(new int[] { 1, 3, 4, -1 }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE).atMost(4).toArray()); - } - - @Test - public void testToBitSet() { - assertEquals("{0, 1, 2, 3, 4}", IntStreamEx.range(5).toBitSet().toString()); - assertEquals("{0, 2, 3, 4, 10}", IntStreamEx.of(0, 2, 0, 3, 0, 4, 0, 10).parallel().toBitSet().toString()); - } - - @Test - public void testAs() { - assertEquals(4, IntStreamEx.range(0, 5).asLongStream().findAny(x -> x > 3).getAsLong()); - assertEquals(4.0, IntStreamEx.range(0, 5).asDoubleStream().findAny(x -> x > 3).getAsDouble(), 0.0); - } - - @Test - public void testFind() { - assertEquals(6, IntStreamEx.range(1, 10).findFirst(i -> i > 5).getAsInt()); - assertFalse(IntStreamEx.range(1, 10).findAny(i -> i > 10).isPresent()); - } - - @Test - public void testRemove() { - assertArrayEquals(new int[] { 1, 2 }, IntStreamEx.of(1, 2, 3).remove(x -> x > 2).toArray()); - } - - @Test - public void testSort() { - assertArrayEquals(new int[] { 0, 3, 6, 1, 4, 7, 2, 5, 8 }, IntStreamEx.range(0, 9).sortedByInt( - i -> i % 3 * 3 + i / 3).toArray()); - assertArrayEquals(new int[] { 0, 3, 6, 1, 4, 7, 2, 5, 8 }, IntStreamEx.range(0, 9).sortedByLong( - i -> (long) i % 3 * Integer.MAX_VALUE + i / 3).toArray()); - assertArrayEquals(new int[] { 8, 7, 6, 5, 4, 3, 2, 1 }, IntStreamEx.range(1, 9).sortedByDouble(i -> 1.0 / i) - .toArray()); - assertArrayEquals(new int[] { 10, 11, 5, 6, 7, 8, 9 }, IntStreamEx.range(5, 12).sortedBy(String::valueOf) - .toArray()); - assertArrayEquals(new int[] { Integer.MAX_VALUE, 1000, 1, 0, -10, Integer.MIN_VALUE }, IntStreamEx.of(0, 1, - 1000, -10, Integer.MIN_VALUE, Integer.MAX_VALUE).reverseSorted().toArray()); - } - - @Test - public void testToString() { - assertEquals("LOWERCASE", IntStreamEx.ofChars("lowercase").map(c -> Character.toUpperCase((char) c)) - .charsToString()); - assertEquals("LOWERCASE", IntStreamEx.ofCodePoints("lowercase").map(Character::toUpperCase) - .codePointsToString()); - } - - @SafeVarargs - private static void checkEmpty(Function... fns) { - int i = 0; - for (Function fn : fns) { - assertFalse("#" + i, fn.apply(IntStreamEx.empty()).isPresent()); - assertFalse("#" + i, fn.apply(IntStreamEx.of(1, 2, 3, 4).greater(5).parallel()).isPresent()); - assertEquals("#" + i, 10, fn.apply(IntStreamEx.of(1, 1, 1, 1, 10, 10, 10, 10).greater(5).parallel()) - .getAsInt()); - i++; - } - } - - @Test - public void testMinMax() { - checkEmpty(s -> s.maxBy(Integer::valueOf), s -> s.maxByInt(x -> x), s -> s.maxByLong(x -> x), s -> s - .maxByDouble(x -> x), s -> s.minBy(Integer::valueOf), s -> s.minByInt(x -> x), - s -> s.minByLong(x -> x), s -> s.minByDouble(x -> x)); - assertEquals(9, IntStreamEx.range(5, 12).max(Comparator.comparing(String::valueOf)).getAsInt()); - assertEquals(10, IntStreamEx.range(5, 12).min(Comparator.comparing(String::valueOf)).getAsInt()); - assertEquals(9, IntStreamEx.range(5, 12).maxBy(String::valueOf).getAsInt()); - assertEquals(10, IntStreamEx.range(5, 12).minBy(String::valueOf).getAsInt()); - assertEquals(5, IntStreamEx.range(5, 12).maxByDouble(x -> 1.0 / x).getAsInt()); - assertEquals(11, IntStreamEx.range(5, 12).minByDouble(x -> 1.0 / x).getAsInt()); - assertEquals(29, IntStreamEx.of(15, 8, 31, 47, 19, 29).maxByInt(x -> x % 10 * 10 + x / 10).getAsInt()); - assertEquals(31, IntStreamEx.of(15, 8, 31, 47, 19, 29).minByInt(x -> x % 10 * 10 + x / 10).getAsInt()); - assertEquals(29, IntStreamEx.of(15, 8, 31, 47, 19, 29).maxByLong(x -> Long.MIN_VALUE + x % 10 * 10 + x / 10) - .getAsInt()); - assertEquals(31, IntStreamEx.of(15, 8, 31, 47, 19, 29).minByLong(x -> Long.MIN_VALUE + x % 10 * 10 + x / 10) - .getAsInt()); - - Supplier s = () -> IntStreamEx.of(1, 50, 120, 35, 130, 12, 0); - IntUnaryOperator intKey = x -> String.valueOf(x).length(); - IntToLongFunction longKey = x -> String.valueOf(x).length(); - IntToDoubleFunction doubleKey = x -> String.valueOf(x).length(); - IntFunction objKey = x -> String.valueOf(x).length(); - List> minFns = Arrays.asList(is -> is.minByInt(intKey), is -> is - .minByLong(longKey), is -> is.minByDouble(doubleKey), is -> is.minBy(objKey)); - List> maxFns = Arrays.asList(is -> is.maxByInt(intKey), is -> is - .maxByLong(longKey), is -> is.maxByDouble(doubleKey), is -> is.maxBy(objKey)); - minFns.forEach(fn -> assertEquals(1, fn.apply(s.get()).getAsInt())); - minFns.forEach(fn -> assertEquals(1, fn.apply(s.get().parallel()).getAsInt())); - maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get()).getAsInt())); - maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get().parallel()).getAsInt())); - } - - private static IntStreamEx dropLast(IntStreamEx s) { - return s.pairMap((a, b) -> a); - } - - @Test - public void testPairMap() { - assertEquals(0, IntStreamEx.range(0).pairMap(Integer::sum).count()); - assertEquals(0, IntStreamEx.range(1).pairMap(Integer::sum).count()); - assertEquals(Collections.singletonMap(1, 9999L), IntStreamEx.range(10000).pairMap((a, b) -> b - a).boxed() - .groupingBy(Function.identity(), Collectors.counting())); - assertEquals(Collections.singletonMap(1, 9999L), IntStreamEx.range(10000).parallel().pairMap((a, b) -> b - a) - .boxed().groupingBy(Function.identity(), Collectors.counting())); - assertEquals("Test Capitalization Stream", IntStreamEx.ofChars("test caPiTaliZation streaM").parallel() - .prepend(0).pairMap( - (c1, c2) -> !Character.isLetter(c1) && Character.isLetter(c2) ? Character.toTitleCase(c2) - : Character.toLowerCase(c2)).charsToString()); - assertArrayEquals(IntStreamEx.range(9999).toArray(), dropLast(IntStreamEx.range(10000)).toArray()); - - withRandom(r -> { - int[] data = r.ints(1000, 1, 1000).toArray(); - int[] expected = new int[data.length - 1]; - int lastSquare = data[0] * data[0]; - for (int i = 0; i < expected.length; i++) { - int newSquare = data[i + 1] * data[i + 1]; - expected[i] = newSquare - lastSquare; - lastSquare = newSquare; - } - int[] result = IntStreamEx.of(data).map(x -> x * x).pairMap((a, b) -> b - a).toArray(); - assertArrayEquals(expected, result); - }); - - assertEquals(1, IntStreamEx.range(1000).map(x -> x * x).pairMap((a, b) -> b - a).pairMap((a, b) -> b - a) - .distinct().count()); - - assertArrayEquals(IntStreamEx.constant(1, 100).toArray(), IntStreamEx.iterate(0, i -> i + 1).parallel() - .pairMap((a, b) -> b - a).limit(100).toArray()); - - assertFalse(IntStreamEx.range(1000).greater(2000).parallel().pairMap((a, b) -> a).findFirst().isPresent()); - } - - @Test - public void testToByteArray() { - byte[] expected = new byte[10000]; - for (int i = 0; i < expected.length; i++) - expected[i] = (byte) i; - assertArrayEquals(expected, IntStreamEx.range(0, 10000).toByteArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().toByteArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).greater(-1).toByteArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().greater(-1).toByteArray()); - // Test when resize of internal buffer is not required on addAll (buffer size = 128) - assertArrayEquals(Arrays.copyOf(expected, 100), IntStreamEx.range(0, 100).parallel().toByteArray()); - } - - @Test - public void testToCharArray() { - char[] expected = new char[10000]; - for (int i = 0; i < expected.length; i++) - expected[i] = (char) i; - assertArrayEquals(expected, IntStreamEx.range(0, 10000).toCharArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().toCharArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).greater(-1).toCharArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().greater(-1).toCharArray()); - // Test when resize of internal buffer is not required on addAll (buffer size = 128) - assertArrayEquals(Arrays.copyOf(expected, 100), IntStreamEx.range(0, 100).parallel().toCharArray()); - } - - @Test - public void testToShortArray() { - short[] expected = new short[10000]; - for (int i = 0; i < expected.length; i++) - expected[i] = (short) i; - assertArrayEquals(expected, IntStreamEx.range(0, 10000).toShortArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().toShortArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).greater(-1).toShortArray()); - assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().greater(-1).toShortArray()); - // Test when resize of internal buffer is not required on addAll (buffer size = 128) - assertArrayEquals(Arrays.copyOf(expected, 100), IntStreamEx.range(0, 100).parallel().toShortArray()); - } - - @Test - public void testJoining() { - assertEquals("0,1,2,3,4,5,6,7,8,9", IntStreamEx.range(10).joining(",")); - assertEquals("0,1,2,3,4,5,6,7,8,9", IntStreamEx.range(10).parallel().joining(",")); - assertEquals("[0,1,2,3,4,5,6,7,8,9]", IntStreamEx.range(10).joining(",", "[", "]")); - assertEquals("[0,1,2,3,4,5,6,7,8,9]", IntStreamEx.range(10).parallel().joining(",", "[", "]")); - } - - @Test - public void testMapToEntry() { - Map> result = IntStreamEx.range(10).mapToEntry(x -> x % 2, x -> x).grouping(); - assertEquals(Arrays.asList(0, 2, 4, 6, 8), result.get(0)); - assertEquals(Arrays.asList(1, 3, 5, 7, 9), result.get(1)); - } - - @Test - public void testTakeWhile() { - assertArrayEquals(IntStreamEx.range(100).toArray(), IntStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 100) - .toArray()); - assertEquals(0, IntStreamEx.empty().takeWhile(i -> true).count()); - assertEquals(0, IntStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 0).count()); - assertEquals(1, IntStreamEx.of(1, 3, 2).takeWhile(i -> i < 3).count()); - assertEquals(3, IntStreamEx.of(1, 2, 3).takeWhile(i -> i < 100).count()); - } - - @Test - public void testTakeWhileInclusive() { - assertArrayEquals(IntStreamEx.range(101).toArray(), IntStreamEx.iterate(0, i -> i + 1).takeWhileInclusive( - i -> i < 100).toArray()); - assertEquals(0, IntStreamEx.empty().takeWhileInclusive(i -> true).count()); - assertEquals(1, IntStreamEx.iterate(0, i -> i + 1).takeWhileInclusive(i -> i < 0).count()); - assertEquals(2, IntStreamEx.of(1, 3, 2).takeWhileInclusive(i -> i < 3).count()); - assertEquals(3, IntStreamEx.of(1, 2, 3).takeWhileInclusive(i -> i < 100).count()); - } - - @Test - public void testDropWhile() { - assertArrayEquals(new int[] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, IntStreamEx.range(100).dropWhile( - i -> i % 10 < 5).limit(10).toArray()); - assertEquals(100, IntStreamEx.range(100).dropWhile(i -> i % 10 < 0).count()); - assertEquals(0, IntStreamEx.range(100).dropWhile(i -> i % 10 < 10).count()); - assertEquals(OptionalInt.of(0), IntStreamEx.range(100).dropWhile(i -> i % 10 < 0).findFirst()); - assertEquals(OptionalInt.empty(), IntStreamEx.range(100).dropWhile(i -> i % 10 < 10).findFirst()); - - java.util.Spliterator.OfInt spltr = IntStreamEx.range(100).dropWhile(i -> i % 10 < 1).spliterator(); - assertTrue(spltr.tryAdvance((int x) -> assertEquals(1, x))); - Builder builder = IntStream.builder(); - spltr.forEachRemaining(builder); - assertArrayEquals(IntStreamEx.range(2, 100).toArray(), builder.build().toArray()); - } - - @Test - public void testIndexOf() { - assertEquals(5, IntStreamEx.range(50, 100).indexOf(55).getAsLong()); - assertFalse(IntStreamEx.range(50, 100).indexOf(200).isPresent()); - assertEquals(5, IntStreamEx.range(50, 100).parallel().indexOf(55).getAsLong()); - assertFalse(IntStreamEx.range(50, 100).parallel().indexOf(200).isPresent()); - - assertEquals(11, IntStreamEx.range(50, 100).indexOf(x -> x > 60).getAsLong()); - assertFalse(IntStreamEx.range(50, 100).indexOf(x -> x < 0).isPresent()); - assertEquals(11, IntStreamEx.range(50, 100).parallel().indexOf(x -> x > 60).getAsLong()); - assertFalse(IntStreamEx.range(50, 100).parallel().indexOf(x -> x < 0).isPresent()); - } - - @Test - public void testFoldLeft() { - // non-associative - IntBinaryOperator accumulator = (x, y) -> (x + y) * (x + y); - assertEquals(2322576, IntStreamEx.constant(3, 4).foldLeft(accumulator).orElse(-1)); - assertEquals(2322576, IntStreamEx.constant(3, 4).parallel().foldLeft(accumulator).orElse(-1)); - assertFalse(IntStreamEx.empty().foldLeft(accumulator).isPresent()); - assertEquals(144, IntStreamEx.rangeClosed(1, 3).foldLeft(0, accumulator)); - assertEquals(144, IntStreamEx.rangeClosed(1, 3).parallel().foldLeft(0, accumulator)); - } - - @Test - public void testMapFirstLast() { - // capitalize - String str = "testString"; - assertEquals("TestString", IntStreamEx.ofCodePoints(str).mapFirst(Character::toUpperCase).codePointsToString()); - - streamEx(() -> StreamEx.of(1, 2, 3, 4, 5), s -> - assertArrayEquals(new int[] { -3, 2, 3, 4, 9 }, s.get().mapToInt(Integer::intValue) - .mapFirst(x -> x - 2).mapLast(x -> x + 2) - .mapFirst(x -> x - 2).mapLast(x -> x + 2).toArray())); - } - - @Test - public void testPeekFirst() { - int[] input = {1, 10, 100, 1000}; - - AtomicInteger firstElement = new AtomicInteger(); - assertArrayEquals(new int[] {10, 100, 1000}, IntStreamEx.of(input).peekFirst(firstElement::set).skip(1).toArray()); - assertEquals(1, firstElement.get()); - - assertArrayEquals(new int[] {10, 100, 1000}, IntStreamEx.of(input).skip(1).peekFirst(firstElement::set).toArray()); - assertEquals(10, firstElement.get()); - - firstElement.set(-1); - assertArrayEquals(new int[] {}, IntStreamEx.of(input).skip(4).peekFirst(firstElement::set).toArray()); - assertEquals(-1, firstElement.get()); - } - - @Test - public void testPeekLast() { - int[] input = {1, 10, 100, 1000}; - AtomicInteger lastElement = new AtomicInteger(-1); - assertArrayEquals(new int[] {1, 10, 100}, IntStreamEx.of(input).peekLast(lastElement::set).limit(3).toArray()); - assertEquals(-1, lastElement.get()); - - assertArrayEquals(new int[] { 1, 10, 100 }, IntStreamEx.of(input).less(1000).peekLast(lastElement::set) - .limit(3).toArray()); - assertEquals(100, lastElement.get()); - - assertArrayEquals(input, IntStreamEx.of(input).peekLast(lastElement::set).limit(4).toArray()); - assertEquals(1000, lastElement.get()); - - assertArrayEquals(new int[] {1, 10, 100}, IntStreamEx.of(input).limit(3).peekLast(lastElement::set).toArray()); - assertEquals(100, lastElement.get()); - } - - @Test - public void testScanLeft() { - assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10) - .scanLeft(Integer::sum)); - assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10).parallel().scanLeft( - Integer::sum)); - assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10).filter(x -> true) - .scanLeft(Integer::sum)); - assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10).filter(x -> true) - .parallel().scanLeft(Integer::sum)); - assertArrayEquals(new int[] { 1, 1, 2, 6, 24, 120 }, IntStreamEx.rangeClosed(1, 5).scanLeft(1, (a, b) -> a * b)); - assertArrayEquals(new int[] { 1, 1, 2, 6, 24, 120 }, IntStreamEx.rangeClosed(1, 5).parallel().scanLeft(1, - (a, b) -> a * b)); - } - - // Reads numbers from scanner stopping when non-number is encountered - // leaving scanner in known state - public static IntStreamEx scannerInts(Scanner sc) { - return IntStreamEx.produce(action -> { - if (sc.hasNextInt()) - action.accept(sc.nextInt()); - return sc.hasNextInt(); - }); - } - - @Test - public void testProduce() { - Scanner sc = new Scanner("1 2 3 4 20000000000 test"); - assertArrayEquals(new int[] {1, 2, 3, 4}, scannerInts(sc).stream().toArray()); - assertEquals("20000000000", sc.next()); - } - - @Test - public void testOfInputStream() { - byte[] data = new byte[] { 5, 3, 10, 1, 4, -1 }; - try (IntStream s = IntStreamEx.of(new ByteArrayInputStream(data))) { - assertEquals(22, s.map(b -> (byte) b).sum()); - } - try (IntStream s = IntStreamEx.of(new ByteArrayInputStream(data))) { - assertEquals(278, s.sum()); - } - InputStream is = new InputStream() { - @Override - public int read() throws IOException { - throw new IOException(); - } - - @Override - public void close() throws IOException { - throw new IOException(); - } - }; - IntStreamEx stream = IntStreamEx.of(is).filter(x -> x > 0); - assertThrows(UncheckedIOException.class, stream::count); - assertThrows(UncheckedIOException.class, stream::close); - } - - @Test - public void testAsInputStream() throws IOException { - AtomicBoolean flag = new AtomicBoolean(false); - InputStream is = IntStreamEx.range(256).onClose(() -> flag.set(true)).asByteInputStream(); - byte[] data = new byte[256]; - assertEquals(2, is.skip(2)); - assertEquals(254, is.read(data)); - assertEquals(-1, is.read()); - for (int i = 0; i < 254; i++) { - assertEquals((byte) (i + 2), data[i]); - } - assertEquals(0, data[254]); - assertEquals(0, data[255]); - assertFalse(flag.get()); - is.close(); - assertTrue(flag.get()); - } - - @Test - public void testPrefix() { - assertArrayEquals(new int[] { 1, 3, 6, 10, 20 }, IntStreamEx.of(1, 2, 3, 4, 10).prefix(Integer::sum).toArray()); - assertEquals(OptionalInt.of(10), IntStreamEx.of(1, 2, 3, 4, 10).prefix(Integer::sum).findFirst(x -> x > 7)); - assertEquals(OptionalInt.empty(), IntStreamEx.of(1, 2, 3, 4, 10).prefix(Integer::sum).findFirst(x -> x > 20)); - intStreamEx(() -> IntStreamEx.range(10000).unordered(), - s -> assertEquals(49995000, s.prefix(Integer::sum).max().getAsInt())); - intStreamEx(() -> IntStreamEx.constant(2, 10), - s -> assertEquals(1024, s.prefix((a, b) -> a*b).max().getAsInt())); - intStreamEx(() -> IntStreamEx.constant(1, 5), - s -> assertEquals(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), - s.prefix(Integer::sum).boxed().collect(Collectors.toSet()))); - intStreamEx(() -> IntStreamEx.constant(1, 5), - s -> assertEquals(OptionalInt.of(5), s.prefix(Integer::sum).findFirst(x -> x > 4))); - intStreamEx(() -> IntStreamEx.constant(1, 5), - s -> assertEquals(OptionalInt.empty(), s.prefix(Integer::sum).findFirst(x -> x > 6))); - } - - @Test - public void testIntersperse() { - assertArrayEquals(new int[] { 1, 0, 10, 0, 100, 0, 1000 }, IntStreamEx.of(1, 10, 100, 1000).intersperse(0) - .toArray()); - assertEquals(0L, IntStreamEx.empty().intersperse(1).count()); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.OptionalInt; +import java.util.PrimitiveIterator.OfInt; +import java.util.Random; +import java.util.Scanner; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; +import java.util.function.IntBinaryOperator; +import java.util.function.IntFunction; +import java.util.function.IntToDoubleFunction; +import java.util.function.IntToLongFunction; +import java.util.function.IntUnaryOperator; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.IntStream.Builder; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.IntStreamEx; +import one.util.streamex.StreamEx; + +import static one.util.streamex.TestHelpers.checkSpliterator; +import static one.util.streamex.TestHelpers.intStreamEx; +import static one.util.streamex.TestHelpers.streamEx; +import static one.util.streamex.TestHelpers.withRandom; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class IntStreamExTest { + private static final byte[] EVEN_BYTES = new byte[] { 2, 4, 6, 8, 10 }; + + @Test + public void testCreate() { + assertArrayEquals(new int[] {}, IntStreamEx.empty().toArray()); + // double test is intended + assertArrayEquals(new int[] {}, IntStreamEx.empty().toArray()); + assertArrayEquals(new int[] { 1 }, IntStreamEx.of(1).toArray()); + assertArrayEquals(new int[] { 1 }, IntStreamEx.of(OptionalInt.of(1)).toArray()); + assertArrayEquals(new int[] {}, IntStreamEx.of(OptionalInt.empty()).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 3).toArray()); + assertArrayEquals(new int[] { 4, 6 }, IntStreamEx.of(new int[] { 2, 4, 6, 8, 10 }, 1, 3).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(new byte[] { 1, 2, 3 }).toArray()); + assertArrayEquals(new int[] { 4, 6 }, IntStreamEx.of(EVEN_BYTES, 1, 3).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(new short[] { 1, 2, 3 }).toArray()); + assertArrayEquals(new int[] { 4, 6 }, IntStreamEx.of(new short[] { 2, 4, 6, 8, 10 }, 1, 3).toArray()); + assertArrayEquals(new int[] { 'a', 'b', 'c' }, IntStreamEx.of('a', 'b', 'c').toArray()); + assertArrayEquals(new int[] { '1', 'b' }, IntStreamEx.of(new char[] { 'a', '1', 'b', '2', 'c', '3' }, 1, 3) + .toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(IntStream.of(1, 2, 3)).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(Arrays.asList(1, 2, 3)).toArray()); + assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.range(3).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.range(1, 4).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.rangeClosed(1, 3).toArray()); + assertArrayEquals(new int[] { 1, 1, 1, 1 }, IntStreamEx.generate(() -> 1).limit(4).toArray()); + assertArrayEquals(new int[] { 1, 1, 1, 1 }, IntStreamEx.constant(1, 4).toArray()); + assertArrayEquals(new int[] { 'a', 'b', 'c' }, IntStreamEx.ofChars("abc").toArray()); + assertEquals(10, IntStreamEx.of(new Random(), 10).count()); + assertTrue(IntStreamEx.of(new Random(), 100, 1, 10).allMatch(x -> x >= 1 && x < 10)); + assertArrayEquals(IntStreamEx.of(new Random(1), 100, 1, 10).toArray(), IntStreamEx.of(new Random(1), 1, 10) + .limit(100).toArray()); + + IntStream stream = IntStreamEx.of(1, 2, 3); + assertSame(stream, IntStreamEx.of(stream)); + + assertArrayEquals(new int[] { 4, 2, 0, -2, -4 }, IntStreamEx.zip(new int[] { 5, 4, 3, 2, 1 }, + new int[] { 1, 2, 3, 4, 5 }, (a, b) -> a - b).toArray()); + + assertArrayEquals(new int[] { 1, 5, 3 }, IntStreamEx.of(Spliterators.spliterator(new int[] { 1, 5, 3 }, 0)) + .toArray()); + assertArrayEquals(new int[] { 1, 5, 3 }, IntStreamEx.of( + Spliterators.iterator(Spliterators.spliterator(new int[] { 1, 5, 3 }, 0))).toArray()); + assertArrayEquals(new int[0], IntStreamEx.of(Spliterators.iterator(Spliterators.emptyIntSpliterator())) + .parallel().toArray()); + + BitSet bs = new BitSet(); + bs.set(1); + bs.set(3); + bs.set(5); + assertArrayEquals(new int[] { 1, 3, 5 }, IntStreamEx.of(bs).toArray()); + + assertArrayEquals(new int[] { 2, 4, 6 }, IntStreamEx.of(new Integer[] { 2, 4, 6 }).toArray()); + } + + @Test + public void testOfIntBuffer() { + int[] data = IntStreamEx.range(100).toArray(); + assertArrayEquals(data, IntStreamEx.of(IntBuffer.wrap(data)).toArray()); + assertArrayEquals(IntStreamEx.range(50, 70).toArray(), IntStreamEx.of(IntBuffer.wrap(data, 50, 20)).toArray()); + assertArrayEquals(data, IntStreamEx.of(IntBuffer.wrap(data)).parallel().toArray()); + assertArrayEquals(IntStreamEx.range(50, 70).toArray(), IntStreamEx.of(IntBuffer.wrap(data, 50, 20)).parallel() + .toArray()); + } + + @Test + public void testIterate() { + assertArrayEquals(new int[] { 1, 2, 4, 8, 16 }, IntStreamEx.iterate(1, x -> x * 2).limit(5).toArray()); + assertArrayEquals(new int[] { 1, 2, 4, 8, 16, 32, 64 }, IntStreamEx.iterate(1, x -> x < 100, x -> x * 2).toArray()); + assertEquals(0, IntStreamEx.iterate(0, x -> x < 0, x -> 1 / x).count()); + assertFalse(IntStreamEx.iterate(1, x -> x < 100, x -> x * 2).has(10)); + checkSpliterator("iterate", () -> IntStreamEx.iterate(1, x -> x < 100, x -> x * 2).spliterator()); + } + + @Test + public void testInts() { + assertEquals(Integer.MAX_VALUE, IntStreamEx.ints().spliterator().getExactSizeIfKnown()); + assertArrayEquals(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, IntStreamEx.ints().limit(10).toArray()); + } + + @Test + public void testRangeStep() { + assertArrayEquals(new int[] { 0 }, IntStreamEx.range(0, 1000, 100000).toArray()); + assertArrayEquals(new int[] { 0 }, IntStreamEx.range(0, 1000, 1000).toArray()); + assertArrayEquals(new int[] { 0, Integer.MAX_VALUE - 1 }, IntStreamEx.range(0, Integer.MAX_VALUE, + Integer.MAX_VALUE - 1).toArray()); + assertArrayEquals(new int[] { Integer.MIN_VALUE, -1, Integer.MAX_VALUE - 1 }, IntStreamEx.range( + Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).toArray()); + assertArrayEquals(new int[] { Integer.MIN_VALUE, -1 }, IntStreamEx.range(Integer.MIN_VALUE, + Integer.MAX_VALUE - 1, Integer.MAX_VALUE).toArray()); + assertArrayEquals(new int[] { Integer.MAX_VALUE, -1 }, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE, + Integer.MIN_VALUE).toArray()); + assertArrayEquals(new int[] { Integer.MAX_VALUE }, IntStreamEx.range(Integer.MAX_VALUE, 0, Integer.MIN_VALUE) + .toArray()); + assertArrayEquals(new int[] { 1, Integer.MIN_VALUE + 1 }, IntStreamEx.range(1, Integer.MIN_VALUE, + Integer.MIN_VALUE).toArray()); + assertArrayEquals(new int[] { 0 }, IntStreamEx.range(0, Integer.MIN_VALUE, Integer.MIN_VALUE).toArray()); + assertArrayEquals(new int[] { 0, 2, 4, 6, 8 }, IntStreamEx.range(0, 9, 2).toArray()); + assertArrayEquals(new int[] { 0, 2, 4, 6 }, IntStreamEx.range(0, 8, 2).toArray()); + assertArrayEquals(new int[] { 0, -2, -4, -6, -8 }, IntStreamEx.range(0, -9, -2).toArray()); + assertArrayEquals(new int[] { 0, -2, -4, -6 }, IntStreamEx.range(0, -8, -2).toArray()); + assertArrayEquals(new int[] { 5, 4, 3, 2, 1, 0 }, IntStreamEx.range(5, -1, -1).toArray()); + assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE, 2).spliterator() + .getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE, IntStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE - 1, 2).spliterator() + .getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE, -2).spliterator() + .getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE + 1, -2).spliterator() + .getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE * 2L + 1L, IntStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE, 1) + .spliterator().getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE * 2L + 1L, IntStreamEx.range(Integer.MAX_VALUE, Integer.MIN_VALUE, -1) + .spliterator().getExactSizeIfKnown()); + assertEquals(0, IntStreamEx.range(0, -1000, 1).count()); + assertEquals(0, IntStreamEx.range(0, 1000, -1).count()); + assertEquals(0, IntStreamEx.range(0, 0, -1).count()); + assertEquals(0, IntStreamEx.range(0, 0, 1).count()); + assertEquals(0, IntStreamEx.range(0, -1000, 2).count()); + assertEquals(0, IntStreamEx.range(0, 1000, -2).count()); + assertEquals(0, IntStreamEx.range(0, 0, -2).count()); + assertEquals(0, IntStreamEx.range(0, 0, 2).count()); + + assertEquals(0, IntStreamEx.range(0, Integer.MIN_VALUE, 2).spliterator().getExactSizeIfKnown()); + assertEquals(0, IntStreamEx.range(0, Integer.MAX_VALUE, -2).spliterator().getExactSizeIfKnown()); + + assertThrows(IllegalArgumentException.class, () -> IntStreamEx.range(0, 1000, 0)); + } + + @Test + public void testRangeClosedStep() { + assertArrayEquals(new int[] { 0 }, IntStreamEx.rangeClosed(0, 1000, 100000).toArray()); + assertArrayEquals(new int[] { 0, 1000 }, IntStreamEx.rangeClosed(0, 1000, 1000).toArray()); + assertArrayEquals(new int[] { 0, Integer.MAX_VALUE - 1 }, IntStreamEx.rangeClosed(0, Integer.MAX_VALUE, + Integer.MAX_VALUE - 1).toArray()); + assertArrayEquals(new int[] { 0, Integer.MAX_VALUE }, IntStreamEx.rangeClosed(0, Integer.MAX_VALUE, + Integer.MAX_VALUE).toArray()); + assertArrayEquals(new int[] { Integer.MIN_VALUE, -1, Integer.MAX_VALUE - 1 }, IntStreamEx.rangeClosed( + Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE).toArray()); + assertArrayEquals(new int[] { Integer.MIN_VALUE, -1, Integer.MAX_VALUE - 1 }, IntStreamEx.rangeClosed( + Integer.MIN_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE).toArray()); + assertArrayEquals(new int[] { Integer.MAX_VALUE, -1 }, IntStreamEx.rangeClosed(Integer.MAX_VALUE, + Integer.MIN_VALUE, Integer.MIN_VALUE).toArray()); + assertArrayEquals(new int[] { Integer.MAX_VALUE }, IntStreamEx.rangeClosed(Integer.MAX_VALUE, 0, + Integer.MIN_VALUE).toArray()); + assertArrayEquals(new int[] { 0, Integer.MIN_VALUE }, IntStreamEx.rangeClosed(0, Integer.MIN_VALUE, + Integer.MIN_VALUE).toArray()); + assertArrayEquals(new int[] { 0, 2, 4, 6, 8 }, IntStreamEx.rangeClosed(0, 9, 2).toArray()); + assertArrayEquals(new int[] { 0, 2, 4, 6, 8 }, IntStreamEx.rangeClosed(0, 8, 2).toArray()); + assertArrayEquals(new int[] { 0, 2, 4, 6 }, IntStreamEx.rangeClosed(0, 7, 2).toArray()); + assertArrayEquals(new int[] { 0, -2, -4, -6, -8 }, IntStreamEx.rangeClosed(0, -9, -2).toArray()); + assertArrayEquals(new int[] { 0, -2, -4, -6, -8 }, IntStreamEx.rangeClosed(0, -8, -2).toArray()); + assertArrayEquals(new int[] { 0, -2, -4, -6 }, IntStreamEx.rangeClosed(0, -7, -2).toArray()); + assertArrayEquals(new int[] { 5, 4, 3, 2, 1, 0 }, IntStreamEx.rangeClosed(5, 0, -1).toArray()); + assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE, 2) + .spliterator().getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE - 1, 2) + .spliterator().getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE - 2, 2) + .spliterator().getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MAX_VALUE, Integer.MIN_VALUE, -2) + .spliterator().getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE + 1L, IntStreamEx.rangeClosed(Integer.MAX_VALUE, Integer.MIN_VALUE + 1, -2) + .spliterator().getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE * 2L + 2L, IntStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE, 1) + .spliterator().getExactSizeIfKnown()); + assertEquals(Integer.MAX_VALUE * 2L + 2L, IntStreamEx.rangeClosed(Integer.MAX_VALUE, Integer.MIN_VALUE, -1) + .spliterator().getExactSizeIfKnown()); + assertEquals(0, IntStreamEx.rangeClosed(0, -1000, 1).count()); + assertEquals(0, IntStreamEx.rangeClosed(0, 1000, -1).count()); + assertEquals(0, IntStreamEx.rangeClosed(0, 1, -1).count()); + assertEquals(0, IntStreamEx.rangeClosed(0, -1, 1).count()); + assertEquals(0, IntStreamEx.rangeClosed(0, -1000, 2).count()); + assertEquals(0, IntStreamEx.rangeClosed(0, 1000, -2).count()); + assertEquals(0, IntStreamEx.rangeClosed(0, 1, -2).count()); + assertEquals(0, IntStreamEx.rangeClosed(0, -1, 2).count()); + assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, 1).toArray()); + assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, 2).toArray()); + assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 11, 2).toArray()); + assertArrayEquals(new int[] {}, IntStreamEx.rangeClosed(11, 10, 2).toArray()); + assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, -1).toArray()); + assertArrayEquals(new int[] {10}, IntStreamEx.rangeClosed(10, 10, -2).toArray()); + assertArrayEquals(new int[] {}, IntStreamEx.rangeClosed(10, 11, -2).toArray()); + assertArrayEquals(new int[] {11}, IntStreamEx.rangeClosed(11, 10, -2).toArray()); + + assertThrows(ArrayIndexOutOfBoundsException.class, () -> IntStreamEx.of(EVEN_BYTES, -1, 3).findAny()); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> IntStreamEx.of(EVEN_BYTES, 3, 1).findAny()); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> IntStreamEx.of(EVEN_BYTES, 3, 6).findAny()); + } + + @Test + public void testArrayLengthOk() { + assertEquals(10, IntStreamEx.of(EVEN_BYTES, 3, 5).skip(1).findFirst().getAsInt()); + } + + @Test + public void testOfIndices() { + assertArrayEquals(new int[] {}, IntStreamEx.ofIndices(new int[0]).toArray()); + assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new int[] { 5, -100, 1 }).toArray()); + assertArrayEquals(new int[] { 0, 2 }, IntStreamEx.ofIndices(new int[] { 5, -100, 1 }, i -> i > 0).toArray()); + assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new long[] { 5, -100, 1 }).toArray()); + assertArrayEquals(new int[] { 0, 2 }, IntStreamEx.ofIndices(new long[] { 5, -100, 1 }, i -> i > 0).toArray()); + assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new double[] { 5, -100, 1 }).toArray()); + assertArrayEquals(new int[] { 0, 2 }, IntStreamEx.ofIndices(new double[] { 5, -100, 1 }, i -> i > 0).toArray()); + assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(new String[] { "a", "b", "c" }).toArray()); + assertArrayEquals(new int[] { 1 }, IntStreamEx.ofIndices(new String[] { "a", "", "c" }, String::isEmpty) + .toArray()); + assertArrayEquals(new int[] { 0, 1, 2 }, IntStreamEx.ofIndices(Arrays.asList("a", "b", "c")).toArray()); + assertArrayEquals(new int[] { 1 }, IntStreamEx.ofIndices(Arrays.asList("a", "", "c"), String::isEmpty) + .toArray()); + } + + @Test + public void testBasics() { + assertFalse(IntStreamEx.of(1).isParallel()); + assertTrue(IntStreamEx.of(1).parallel().isParallel()); + assertFalse(IntStreamEx.of(1).parallel().sequential().isParallel()); + AtomicInteger i = new AtomicInteger(); + try (IntStreamEx s = IntStreamEx.of(1).onClose(i::incrementAndGet)) { + assertEquals(1, s.count()); + } + assertEquals(1, i.get()); + assertEquals(6, IntStreamEx.range(0, 4).sum()); + assertEquals(3, IntStreamEx.range(0, 4).max().getAsInt()); + assertEquals(0, IntStreamEx.range(0, 4).min().getAsInt()); + assertEquals(1.5, IntStreamEx.range(0, 4).average().getAsDouble(), 0.000001); + assertEquals(4, IntStreamEx.range(0, 4).summaryStatistics().getCount()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.range(0, 5).skip(1).limit(3).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(3, 1, 2).sorted().toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 1, 3, 2).distinct().toArray()); + assertArrayEquals(new int[] { 2, 4, 6 }, IntStreamEx.range(1, 4).map(x -> x * 2).toArray()); + assertArrayEquals(new long[] { 2, 4, 6 }, IntStreamEx.range(1, 4).mapToLong(x -> x * 2).toArray()); + assertArrayEquals(new double[] { 2, 4, 6 }, IntStreamEx.range(1, 4).mapToDouble(x -> x * 2).toArray(), 0.0); + assertArrayEquals(new int[] { 1, 3 }, IntStreamEx.range(0, 5).filter(x -> x % 2 == 1).toArray()); + assertEquals(6, IntStreamEx.of(1, 2, 3).reduce(Integer::sum).getAsInt()); + assertEquals(Integer.MAX_VALUE, IntStreamEx.rangeClosed(1, Integer.MAX_VALUE).spliterator() + .getExactSizeIfKnown()); + + assertTrue(IntStreamEx.of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)); + assertFalse(IntStreamEx.of(1, 2, 3).unordered().spliterator().hasCharacteristics(Spliterator.ORDERED)); + + OfInt iterator = IntStreamEx.of(1, 2, 3).iterator(); + assertEquals(1, iterator.nextInt()); + assertEquals(2, iterator.nextInt()); + assertEquals(3, iterator.nextInt()); + assertFalse(iterator.hasNext()); + + List list = new ArrayList<>(); + IntStreamEx.range(10).parallel().forEachOrdered(list::add); + assertEquals(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), list); + + assertTrue(IntStreamEx.empty().noneMatch(x -> true)); + assertFalse(IntStreamEx.of(1).noneMatch(x -> true)); + assertTrue(IntStreamEx.of(1).noneMatch(x -> false)); + } + + @Test + public void testForEach() { + streamEx(() -> StreamEx.of(1, 2, 3), s -> { + AtomicInteger count = new AtomicInteger(0); + s.get().mapToInt(Integer::intValue).forEach(count::addAndGet); + assertEquals(6, count.get()); + s.get().mapToInt(Integer::intValue).pairMap((a, b) -> b - a).forEach(count::addAndGet); + assertEquals(8, count.get()); + }); + } + + @Test + public void testFlatMap() { + long[][] vals = { { 1, 2, 3 }, { 2, 3, 4 }, { 5, 4, Long.MAX_VALUE, Long.MIN_VALUE } }; + assertArrayEquals(new long[] { 1, 2, 3, 2, 3, 4, 5, 4, Long.MAX_VALUE, Long.MIN_VALUE }, IntStreamEx.ofIndices( + vals).flatMapToLong(idx -> Arrays.stream(vals[idx])).toArray()); + String expected = IntStream.range(0, 200).boxed().flatMap( + i -> IntStream.range(0, i).mapToObj(j -> i + ":" + j)).collect(Collectors.joining("/")); + String res = IntStreamEx.range(200).flatMapToObj(i -> IntStreamEx.range(i).mapToObj(j -> i + ":" + j)).joining( + "/"); + String parallel = IntStreamEx.range(200).parallel().flatMapToObj( + i -> IntStreamEx.range(i).mapToObj(j -> i + ":" + j)).joining("/"); + assertEquals(expected, res); + assertEquals(expected, parallel); + + double[] fractions = IntStreamEx.range(1, 5).flatMapToDouble( + i -> IntStreamEx.range(1, i).mapToDouble(j -> ((double) j) / i)).toArray(); + assertArrayEquals(new double[] { 1 / 2.0, 1 / 3.0, 2 / 3.0, 1 / 4.0, 2 / 4.0, 3 / 4.0 }, fractions, 0.000001); + + assertArrayEquals(new int[] { 0, 0, 1, 0, 1, 2 }, IntStreamEx.of(1, 2, 3).flatMap(IntStreamEx::range).toArray()); + } + + @Test + public void testElements() { + assertEquals(Arrays.asList("f", "d", "b"), IntStreamEx.of(5, 3, 1).elements("abcdef".split("")).toList()); + assertEquals(Arrays.asList("f", "d", "b"), IntStreamEx.of(5, 3, 1).elements( + Arrays.asList("a", "b", "c", "d", "e", "f")).toList()); + assertArrayEquals(new int[] { 10, 6, 2 }, IntStreamEx.of(5, 3, 1).elements(new int[] { 0, 2, 4, 6, 8, 10 }) + .toArray()); + assertArrayEquals(new long[] { 10, 6, 2 }, IntStreamEx.of(5, 3, 1).elements(new long[] { 0, 2, 4, 6, 8, 10 }) + .toArray()); + assertArrayEquals(new double[] { 10, 6, 2 }, IntStreamEx.of(5, 3, 1).elements( + new double[] { 0, 2, 4, 6, 8, 10 }).toArray(), 0.0); + } + + @Test + public void testPrepend() { + assertArrayEquals(new int[] { -1, 0, 1, 2, 3 }, IntStreamEx.of(1, 2, 3).prepend(-1, 0).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 3).prepend().toArray()); + assertArrayEquals(new int[] { 10, 11, 0, 1, 2, 3 }, IntStreamEx.range(0, 4).prepend(IntStreamEx.range(10, 12)) + .toArray()); + } + + @Test + public void testAppend() { + assertArrayEquals(new int[] { 1, 2, 3, 4, 5 }, IntStreamEx.of(1, 2, 3).append(4, 5).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.of(1, 2, 3).append().toArray()); + assertArrayEquals(new int[] { 0, 1, 2, 3, 10, 11 }, IntStreamEx.range(0, 4).append(IntStreamEx.range(10, 12)) + .toArray()); + } + + @Test + public void testHas() { + assertTrue(IntStreamEx.range(1, 4).has(3)); + assertFalse(IntStreamEx.range(1, 4).has(4)); + } + + @Test + public void testWithout() { + assertArrayEquals(new int[] { 1, 2 }, IntStreamEx.range(1, 4).without(3).toArray()); + assertArrayEquals(new int[] { 1, 2, 3 }, IntStreamEx.range(1, 4).without(5).toArray()); + IntStreamEx ise = IntStreamEx.range(5); + assertSame(ise, ise.without()); + assertArrayEquals(new int[] { 0, 1, 3, 4 }, IntStreamEx.range(5).without(new int[] { 2 }).toArray()); + assertArrayEquals(new int[] { 0 }, IntStreamEx.range(5).without(1, 2, 3, 4, 5, 6).toArray()); + } + + @Test + public void testRanges() { + assertArrayEquals(new int[] { 5, 4, Integer.MAX_VALUE }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE) + .greater(3).toArray()); + assertArrayEquals(new int[] { 5, 3, 4, Integer.MAX_VALUE }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE) + .atLeast(3).toArray()); + assertArrayEquals(new int[] { 1, -1 }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE).less(3).toArray()); + assertArrayEquals(new int[] { 1, 3, -1 }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE).atMost(3).toArray()); + assertArrayEquals(new int[] { 1, 3, 4, -1 }, IntStreamEx.of(1, 5, 3, 4, -1, Integer.MAX_VALUE).atMost(4).toArray()); + } + + @Test + public void testToBitSet() { + assertEquals("{0, 1, 2, 3, 4}", IntStreamEx.range(5).toBitSet().toString()); + assertEquals("{0, 2, 3, 4, 10}", IntStreamEx.of(0, 2, 0, 3, 0, 4, 0, 10).parallel().toBitSet().toString()); + } + + @Test + public void testAs() { + assertEquals(4, IntStreamEx.range(0, 5).asLongStream().findAny(x -> x > 3).getAsLong()); + assertEquals(4.0, IntStreamEx.range(0, 5).asDoubleStream().findAny(x -> x > 3).getAsDouble(), 0.0); + } + + @Test + public void testFind() { + assertEquals(6, IntStreamEx.range(1, 10).findFirst(i -> i > 5).getAsInt()); + assertFalse(IntStreamEx.range(1, 10).findAny(i -> i > 10).isPresent()); + } + + @Test + public void testRemove() { + assertArrayEquals(new int[] { 1, 2 }, IntStreamEx.of(1, 2, 3).remove(x -> x > 2).toArray()); + } + + @Test + public void testSort() { + assertArrayEquals(new int[] { 0, 3, 6, 1, 4, 7, 2, 5, 8 }, IntStreamEx.range(0, 9).sortedByInt( + i -> i % 3 * 3 + i / 3).toArray()); + assertArrayEquals(new int[] { 0, 3, 6, 1, 4, 7, 2, 5, 8 }, IntStreamEx.range(0, 9).sortedByLong( + i -> (long) i % 3 * Integer.MAX_VALUE + i / 3).toArray()); + assertArrayEquals(new int[] { 8, 7, 6, 5, 4, 3, 2, 1 }, IntStreamEx.range(1, 9).sortedByDouble(i -> 1.0 / i) + .toArray()); + assertArrayEquals(new int[] { 10, 11, 5, 6, 7, 8, 9 }, IntStreamEx.range(5, 12).sortedBy(String::valueOf) + .toArray()); + assertArrayEquals(new int[] { Integer.MAX_VALUE, 1000, 1, 0, -10, Integer.MIN_VALUE }, IntStreamEx.of(0, 1, + 1000, -10, Integer.MIN_VALUE, Integer.MAX_VALUE).reverseSorted().toArray()); + } + + @Test + public void testToString() { + assertEquals("LOWERCASE", IntStreamEx.ofChars("lowercase").map(c -> Character.toUpperCase((char) c)) + .charsToString()); + assertEquals("LOWERCASE", IntStreamEx.ofCodePoints("lowercase").map(Character::toUpperCase) + .codePointsToString()); + } + + @SafeVarargs + private static void checkEmpty(Function... fns) { + int i = 0; + for (Function fn : fns) { + assertFalse("#" + i, fn.apply(IntStreamEx.empty()).isPresent()); + assertFalse("#" + i, fn.apply(IntStreamEx.of(1, 2, 3, 4).greater(5).parallel()).isPresent()); + assertEquals("#" + i, 10, fn.apply(IntStreamEx.of(1, 1, 1, 1, 10, 10, 10, 10).greater(5).parallel()) + .getAsInt()); + i++; + } + } + + @Test + public void testMinMax() { + checkEmpty(s -> s.maxBy(Integer::valueOf), s -> s.maxByInt(x -> x), s -> s.maxByLong(x -> x), s -> s + .maxByDouble(x -> x), s -> s.minBy(Integer::valueOf), s -> s.minByInt(x -> x), + s -> s.minByLong(x -> x), s -> s.minByDouble(x -> x)); + assertEquals(9, IntStreamEx.range(5, 12).max(Comparator.comparing(String::valueOf)).getAsInt()); + assertEquals(10, IntStreamEx.range(5, 12).min(Comparator.comparing(String::valueOf)).getAsInt()); + assertEquals(9, IntStreamEx.range(5, 12).maxBy(String::valueOf).getAsInt()); + assertEquals(10, IntStreamEx.range(5, 12).minBy(String::valueOf).getAsInt()); + assertEquals(5, IntStreamEx.range(5, 12).maxByDouble(x -> 1.0 / x).getAsInt()); + assertEquals(11, IntStreamEx.range(5, 12).minByDouble(x -> 1.0 / x).getAsInt()); + assertEquals(29, IntStreamEx.of(15, 8, 31, 47, 19, 29).maxByInt(x -> x % 10 * 10 + x / 10).getAsInt()); + assertEquals(31, IntStreamEx.of(15, 8, 31, 47, 19, 29).minByInt(x -> x % 10 * 10 + x / 10).getAsInt()); + assertEquals(29, IntStreamEx.of(15, 8, 31, 47, 19, 29).maxByLong(x -> Long.MIN_VALUE + x % 10 * 10 + x / 10) + .getAsInt()); + assertEquals(31, IntStreamEx.of(15, 8, 31, 47, 19, 29).minByLong(x -> Long.MIN_VALUE + x % 10 * 10 + x / 10) + .getAsInt()); + + Supplier s = () -> IntStreamEx.of(1, 50, 120, 35, 130, 12, 0); + IntUnaryOperator intKey = x -> String.valueOf(x).length(); + IntToLongFunction longKey = x -> String.valueOf(x).length(); + IntToDoubleFunction doubleKey = x -> String.valueOf(x).length(); + IntFunction objKey = x -> String.valueOf(x).length(); + List> minFns = Arrays.asList(is -> is.minByInt(intKey), is -> is + .minByLong(longKey), is -> is.minByDouble(doubleKey), is -> is.minBy(objKey)); + List> maxFns = Arrays.asList(is -> is.maxByInt(intKey), is -> is + .maxByLong(longKey), is -> is.maxByDouble(doubleKey), is -> is.maxBy(objKey)); + minFns.forEach(fn -> assertEquals(1, fn.apply(s.get()).getAsInt())); + minFns.forEach(fn -> assertEquals(1, fn.apply(s.get().parallel()).getAsInt())); + maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get()).getAsInt())); + maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get().parallel()).getAsInt())); + } + + private static IntStreamEx dropLast(IntStreamEx s) { + return s.pairMap((a, b) -> a); + } + + @Test + public void testPairMap() { + assertEquals(0, IntStreamEx.range(0).pairMap(Integer::sum).count()); + assertEquals(0, IntStreamEx.range(1).pairMap(Integer::sum).count()); + assertEquals(Collections.singletonMap(1, 9999L), IntStreamEx.range(10000).pairMap((a, b) -> b - a).boxed() + .groupingBy(Function.identity(), Collectors.counting())); + assertEquals(Collections.singletonMap(1, 9999L), IntStreamEx.range(10000).parallel().pairMap((a, b) -> b - a) + .boxed().groupingBy(Function.identity(), Collectors.counting())); + assertEquals("Test Capitalization Stream", IntStreamEx.ofChars("test caPiTaliZation streaM").parallel() + .prepend(0).pairMap( + (c1, c2) -> !Character.isLetter(c1) && Character.isLetter(c2) ? Character.toTitleCase(c2) + : Character.toLowerCase(c2)).charsToString()); + assertArrayEquals(IntStreamEx.range(9999).toArray(), dropLast(IntStreamEx.range(10000)).toArray()); + + withRandom(r -> { + int[] data = r.ints(1000, 1, 1000).toArray(); + int[] expected = new int[data.length - 1]; + int lastSquare = data[0] * data[0]; + for (int i = 0; i < expected.length; i++) { + int newSquare = data[i + 1] * data[i + 1]; + expected[i] = newSquare - lastSquare; + lastSquare = newSquare; + } + int[] result = IntStreamEx.of(data).map(x -> x * x).pairMap((a, b) -> b - a).toArray(); + assertArrayEquals(expected, result); + }); + + assertEquals(1, IntStreamEx.range(1000).map(x -> x * x).pairMap((a, b) -> b - a).pairMap((a, b) -> b - a) + .distinct().count()); + + assertArrayEquals(IntStreamEx.constant(1, 100).toArray(), IntStreamEx.iterate(0, i -> i + 1).parallel() + .pairMap((a, b) -> b - a).limit(100).toArray()); + + assertFalse(IntStreamEx.range(1000).greater(2000).parallel().pairMap((a, b) -> a).findFirst().isPresent()); + } + + @Test + public void testToByteArray() { + byte[] expected = new byte[10000]; + for (int i = 0; i < expected.length; i++) + expected[i] = (byte) i; + assertArrayEquals(expected, IntStreamEx.range(0, 10000).toByteArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().toByteArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).greater(-1).toByteArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().greater(-1).toByteArray()); + // Test when resize of internal buffer is not required on addAll (buffer size = 128) + assertArrayEquals(Arrays.copyOf(expected, 100), IntStreamEx.range(0, 100).parallel().toByteArray()); + } + + @Test + public void testToCharArray() { + char[] expected = new char[10000]; + for (int i = 0; i < expected.length; i++) + expected[i] = (char) i; + assertArrayEquals(expected, IntStreamEx.range(0, 10000).toCharArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().toCharArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).greater(-1).toCharArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().greater(-1).toCharArray()); + // Test when resize of internal buffer is not required on addAll (buffer size = 128) + assertArrayEquals(Arrays.copyOf(expected, 100), IntStreamEx.range(0, 100).parallel().toCharArray()); + } + + @Test + public void testToShortArray() { + short[] expected = new short[10000]; + for (int i = 0; i < expected.length; i++) + expected[i] = (short) i; + assertArrayEquals(expected, IntStreamEx.range(0, 10000).toShortArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().toShortArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).greater(-1).toShortArray()); + assertArrayEquals(expected, IntStreamEx.range(0, 10000).parallel().greater(-1).toShortArray()); + // Test when resize of internal buffer is not required on addAll (buffer size = 128) + assertArrayEquals(Arrays.copyOf(expected, 100), IntStreamEx.range(0, 100).parallel().toShortArray()); + } + + @Test + public void testJoining() { + assertEquals("0,1,2,3,4,5,6,7,8,9", IntStreamEx.range(10).joining(",")); + assertEquals("0,1,2,3,4,5,6,7,8,9", IntStreamEx.range(10).parallel().joining(",")); + assertEquals("[0,1,2,3,4,5,6,7,8,9]", IntStreamEx.range(10).joining(",", "[", "]")); + assertEquals("[0,1,2,3,4,5,6,7,8,9]", IntStreamEx.range(10).parallel().joining(",", "[", "]")); + } + + @Test + public void testMapToEntry() { + Map> result = IntStreamEx.range(10).mapToEntry(x -> x % 2, x -> x).grouping(); + assertEquals(Arrays.asList(0, 2, 4, 6, 8), result.get(0)); + assertEquals(Arrays.asList(1, 3, 5, 7, 9), result.get(1)); + } + + @Test + public void testTakeWhile() { + assertArrayEquals(IntStreamEx.range(100).toArray(), IntStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 100) + .toArray()); + assertEquals(0, IntStreamEx.empty().takeWhile(i -> true).count()); + assertEquals(0, IntStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 0).count()); + assertEquals(1, IntStreamEx.of(1, 3, 2).takeWhile(i -> i < 3).count()); + assertEquals(3, IntStreamEx.of(1, 2, 3).takeWhile(i -> i < 100).count()); + } + + @Test + public void testTakeWhileInclusive() { + assertArrayEquals(IntStreamEx.range(101).toArray(), IntStreamEx.iterate(0, i -> i + 1).takeWhileInclusive( + i -> i < 100).toArray()); + assertEquals(0, IntStreamEx.empty().takeWhileInclusive(i -> true).count()); + assertEquals(1, IntStreamEx.iterate(0, i -> i + 1).takeWhileInclusive(i -> i < 0).count()); + assertEquals(2, IntStreamEx.of(1, 3, 2).takeWhileInclusive(i -> i < 3).count()); + assertEquals(3, IntStreamEx.of(1, 2, 3).takeWhileInclusive(i -> i < 100).count()); + } + + @Test + public void testDropWhile() { + assertArrayEquals(new int[] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, IntStreamEx.range(100).dropWhile( + i -> i % 10 < 5).limit(10).toArray()); + assertEquals(100, IntStreamEx.range(100).dropWhile(i -> i % 10 < 0).count()); + assertEquals(0, IntStreamEx.range(100).dropWhile(i -> i % 10 < 10).count()); + assertEquals(OptionalInt.of(0), IntStreamEx.range(100).dropWhile(i -> i % 10 < 0).findFirst()); + assertEquals(OptionalInt.empty(), IntStreamEx.range(100).dropWhile(i -> i % 10 < 10).findFirst()); + + java.util.Spliterator.OfInt spltr = IntStreamEx.range(100).dropWhile(i -> i % 10 < 1).spliterator(); + assertTrue(spltr.tryAdvance((int x) -> assertEquals(1, x))); + Builder builder = IntStream.builder(); + spltr.forEachRemaining(builder); + assertArrayEquals(IntStreamEx.range(2, 100).toArray(), builder.build().toArray()); + } + + @Test + public void testIndexOf() { + assertEquals(5, IntStreamEx.range(50, 100).indexOf(55).getAsLong()); + assertFalse(IntStreamEx.range(50, 100).indexOf(200).isPresent()); + assertEquals(5, IntStreamEx.range(50, 100).parallel().indexOf(55).getAsLong()); + assertFalse(IntStreamEx.range(50, 100).parallel().indexOf(200).isPresent()); + + assertEquals(11, IntStreamEx.range(50, 100).indexOf(x -> x > 60).getAsLong()); + assertFalse(IntStreamEx.range(50, 100).indexOf(x -> x < 0).isPresent()); + assertEquals(11, IntStreamEx.range(50, 100).parallel().indexOf(x -> x > 60).getAsLong()); + assertFalse(IntStreamEx.range(50, 100).parallel().indexOf(x -> x < 0).isPresent()); + } + + @Test + public void testFoldLeft() { + // non-associative + IntBinaryOperator accumulator = (x, y) -> (x + y) * (x + y); + assertEquals(2322576, IntStreamEx.constant(3, 4).foldLeft(accumulator).orElse(-1)); + assertEquals(2322576, IntStreamEx.constant(3, 4).parallel().foldLeft(accumulator).orElse(-1)); + assertFalse(IntStreamEx.empty().foldLeft(accumulator).isPresent()); + assertEquals(144, IntStreamEx.rangeClosed(1, 3).foldLeft(0, accumulator)); + assertEquals(144, IntStreamEx.rangeClosed(1, 3).parallel().foldLeft(0, accumulator)); + } + + @Test + public void testMapFirstLast() { + // capitalize + String str = "testString"; + assertEquals("TestString", IntStreamEx.ofCodePoints(str).mapFirst(Character::toUpperCase).codePointsToString()); + + streamEx(() -> StreamEx.of(1, 2, 3, 4, 5), s -> + assertArrayEquals(new int[] { -3, 2, 3, 4, 9 }, s.get().mapToInt(Integer::intValue) + .mapFirst(x -> x - 2).mapLast(x -> x + 2) + .mapFirst(x -> x - 2).mapLast(x -> x + 2).toArray())); + } + + @Test + public void testPeekFirst() { + int[] input = {1, 10, 100, 1000}; + + AtomicInteger firstElement = new AtomicInteger(); + assertArrayEquals(new int[] {10, 100, 1000}, IntStreamEx.of(input).peekFirst(firstElement::set).skip(1).toArray()); + assertEquals(1, firstElement.get()); + + assertArrayEquals(new int[] {10, 100, 1000}, IntStreamEx.of(input).skip(1).peekFirst(firstElement::set).toArray()); + assertEquals(10, firstElement.get()); + + firstElement.set(-1); + assertArrayEquals(new int[] {}, IntStreamEx.of(input).skip(4).peekFirst(firstElement::set).toArray()); + assertEquals(-1, firstElement.get()); + } + + @Test + public void testPeekLast() { + int[] input = {1, 10, 100, 1000}; + AtomicInteger lastElement = new AtomicInteger(-1); + assertArrayEquals(new int[] {1, 10, 100}, IntStreamEx.of(input).peekLast(lastElement::set).limit(3).toArray()); + assertEquals(-1, lastElement.get()); + + assertArrayEquals(new int[] { 1, 10, 100 }, IntStreamEx.of(input).less(1000).peekLast(lastElement::set) + .limit(3).toArray()); + assertEquals(100, lastElement.get()); + + assertArrayEquals(input, IntStreamEx.of(input).peekLast(lastElement::set).limit(4).toArray()); + assertEquals(1000, lastElement.get()); + + assertArrayEquals(new int[] {1, 10, 100}, IntStreamEx.of(input).limit(3).peekLast(lastElement::set).toArray()); + assertEquals(100, lastElement.get()); + } + + @Test + public void testScanLeft() { + assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10) + .scanLeft(Integer::sum)); + assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10).parallel().scanLeft( + Integer::sum)); + assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10).filter(x -> true) + .scanLeft(Integer::sum)); + assertArrayEquals(new int[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, IntStreamEx.range(10).filter(x -> true) + .parallel().scanLeft(Integer::sum)); + assertArrayEquals(new int[] { 1, 1, 2, 6, 24, 120 }, IntStreamEx.rangeClosed(1, 5).scanLeft(1, (a, b) -> a * b)); + assertArrayEquals(new int[] { 1, 1, 2, 6, 24, 120 }, IntStreamEx.rangeClosed(1, 5).parallel().scanLeft(1, + (a, b) -> a * b)); + } + + // Reads numbers from scanner stopping when non-number is encountered + // leaving scanner in known state + public static IntStreamEx scannerInts(Scanner sc) { + return IntStreamEx.produce(action -> { + if (sc.hasNextInt()) + action.accept(sc.nextInt()); + return sc.hasNextInt(); + }); + } + + @Test + public void testProduce() { + Scanner sc = new Scanner("1 2 3 4 20000000000 test"); + assertArrayEquals(new int[] {1, 2, 3, 4}, scannerInts(sc).toArray()); + assertEquals("20000000000", sc.next()); + } + + @Test + public void testOfInputStream() { + byte[] data = new byte[] { 5, 3, 10, 1, 4, -1 }; + try (IntStream s = IntStreamEx.of(new ByteArrayInputStream(data))) { + assertEquals(22, s.map(b -> (byte) b).sum()); + } + try (IntStream s = IntStreamEx.of(new ByteArrayInputStream(data))) { + assertEquals(278, s.sum()); + } + InputStream is = new InputStream() { + @Override + public int read() throws IOException { + throw new IOException(); + } + + @Override + public void close() throws IOException { + throw new IOException(); + } + }; + IntStreamEx stream = IntStreamEx.of(is).filter(x -> x > 0); + assertThrows(UncheckedIOException.class, stream::count); + assertThrows(UncheckedIOException.class, stream::close); + } + + @Test + public void testAsInputStream() throws IOException { + AtomicBoolean flag = new AtomicBoolean(false); + InputStream is = IntStreamEx.range(256).onClose(() -> flag.set(true)).asByteInputStream(); + byte[] data = new byte[256]; + assertEquals(2, is.skip(2)); + assertEquals(254, is.read(data)); + assertEquals(-1, is.read()); + for (int i = 0; i < 254; i++) { + assertEquals((byte) (i + 2), data[i]); + } + assertEquals(0, data[254]); + assertEquals(0, data[255]); + assertFalse(flag.get()); + is.close(); + assertTrue(flag.get()); + } + + @Test + public void testPrefix() { + assertArrayEquals(new int[] { 1, 3, 6, 10, 20 }, IntStreamEx.of(1, 2, 3, 4, 10).prefix(Integer::sum).toArray()); + assertEquals(OptionalInt.of(10), IntStreamEx.of(1, 2, 3, 4, 10).prefix(Integer::sum).findFirst(x -> x > 7)); + assertEquals(OptionalInt.empty(), IntStreamEx.of(1, 2, 3, 4, 10).prefix(Integer::sum).findFirst(x -> x > 20)); + intStreamEx(() -> IntStreamEx.range(10000).unordered(), + s -> assertEquals(49995000, s.prefix(Integer::sum).max().getAsInt())); + intStreamEx(() -> IntStreamEx.constant(2, 10), + s -> assertEquals(1024, s.prefix((a, b) -> a*b).max().getAsInt())); + intStreamEx(() -> IntStreamEx.constant(1, 5), + s -> assertEquals(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), + s.prefix(Integer::sum).boxed().collect(Collectors.toSet()))); + intStreamEx(() -> IntStreamEx.constant(1, 5), + s -> assertEquals(OptionalInt.of(5), s.prefix(Integer::sum).findFirst(x -> x > 4))); + intStreamEx(() -> IntStreamEx.constant(1, 5), + s -> assertEquals(OptionalInt.empty(), s.prefix(Integer::sum).findFirst(x -> x > 6))); + } + + @Test + public void testIntersperse() { + assertArrayEquals(new int[] { 1, 0, 10, 0, 100, 0, 1000 }, IntStreamEx.of(1, 10, 100, 1000).intersperse(0) + .toArray()); + assertEquals(0L, IntStreamEx.empty().intersperse(1).count()); + } +} diff --git a/src/test/java/one/util/streamex/JoiningTest.java b/src/test/java/one/util/streamex/api/JoiningTest.java similarity index 98% rename from src/test/java/one/util/streamex/JoiningTest.java rename to src/test/java/one/util/streamex/api/JoiningTest.java index e9ee92e5..62362b08 100644 --- a/src/test/java/one/util/streamex/JoiningTest.java +++ b/src/test/java/one/util/streamex/api/JoiningTest.java @@ -1,304 +1,308 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Locale; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import org.junit.Assert; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static one.util.streamex.TestHelpers.StreamExSupplier; -import static one.util.streamex.TestHelpers.checkCollector; -import static one.util.streamex.TestHelpers.checkShortCircuitCollector; -import static one.util.streamex.TestHelpers.streamEx; -import static org.junit.Assert.assertEquals; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class JoiningTest { - @Test(expected = IllegalArgumentException.class) - public void testMaxCharsRange() { - Joining.with(",").maxChars(-1); - } - - @Test(expected = IllegalArgumentException.class) - public void testMaxCodePointsRange() { - Joining.with(",").maxCodePoints(-2); - } - - @Test(expected = IllegalArgumentException.class) - public void testMaxSymbolsRange() { - Joining.with(",").maxGraphemes(Integer.MIN_VALUE); - } - - @Test - public void testSimple() { - Supplier> s = () -> IntStream.range(0, 100).mapToObj(String::valueOf); - checkCollector("joiningSimple", s.get().collect(Collectors.joining(", ")), s, Joining.with(", ")); - checkCollector("joiningWrap", s.get().collect(Collectors.joining(", ", "[", "]")), s, Joining.with(", ").wrap( - "[", "]")); - checkCollector("joiningWrap2", s.get().collect(Collectors.joining(", ", "[(", ")]")), s, Joining.with(", ") - .wrap("(", ")").wrap("[", "]")); - } - - @Test - public void testCutSimple() { - List input = Arrays.asList("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", - "ten"); - assertEquals("", StreamEx.of(input).peek(Assert::fail).collect(Joining.with(", ").maxChars(0).cutAnywhere())); - assertEquals("", StreamEx.of(input).parallel().peek(Assert::fail).collect( - Joining.with(", ").maxChars(0).cutAnywhere())); - String expected = "one, two, three, four, five, six, seven, eight, nine, ten"; - for (int i = 3; i < expected.length() + 5; i++) { - String exp = expected; - if (exp.length() > i) { - exp = exp.substring(0, i - 3) + "..."; - } - String exp2 = expected; - while (exp2.length() > i) { - int pos = exp2.lastIndexOf(", ", exp2.endsWith(", ...") ? exp2.length() - 6 : exp2.length()); - exp2 = pos >= 0 ? exp2.substring(0, pos + 2) + "..." : "..."; - } - for (StreamExSupplier supplier : streamEx(input::stream)) { - assertEquals(supplier + "/#" + i, exp, supplier.get().collect( - Joining.with(", ").maxChars(i).cutAnywhere())); - assertEquals(supplier + "/#" + i, expected.substring(0, Math.min(i, expected.length())), supplier.get() - .collect(Joining.with(", ").ellipsis("").maxChars(i).cutAnywhere())); - assertEquals(supplier + "/#" + i, exp2, supplier.get().collect( - Joining.with(", ").maxChars(i).cutAfterDelimiter())); - } - } - - byte[] data = { (byte) 0xFF, 0x30, 0x40, 0x50, 0x70, 0x12, (byte) 0xF0 }; - assertEquals("FF 30 40 50 ...", IntStreamEx.of(data).mapToObj( - b -> String.format(Locale.ENGLISH, "%02X", b & 0xFF)).collect( - Joining.with(" ").maxChars(15).cutAfterDelimiter())); - } - - @Test - public void testCuts() { - List input = Arrays.asList("one two", "three four", "five", "six seven"); - - checkShortCircuitCollector("cutBefore", "one two, three four...", 4, input::stream, Joining.with(", ") - .maxChars(25).cutBeforeDelimiter()); - checkShortCircuitCollector("cutBefore", "one two...", 2, input::stream, Joining.with(", ").maxChars(10) - .cutBeforeDelimiter()); - checkShortCircuitCollector("cutBefore", "...", 2, input::stream, Joining.with(", ").maxChars(9) - .cutBeforeDelimiter()); - - checkShortCircuitCollector("cutAfter", "one two, three four, ...", 4, input::stream, Joining.with(", ") - .maxChars(25).cutAfterDelimiter()); - checkShortCircuitCollector("cutAfter", "one two, ...", 2, input::stream, Joining.with(", ").maxChars(12) - .cutAfterDelimiter()); - checkShortCircuitCollector("cutAfter", "...", 2, input::stream, Joining.with(", ").maxChars(11) - .cutAfterDelimiter()); - - checkShortCircuitCollector("cutWord", "one two, three four, ...", 4, input::stream, Joining.with(", ") - .maxChars(25).cutAtWord()); - checkShortCircuitCollector("cutWord", "one two, ...", 2, input::stream, Joining.with(", ").maxChars(12) - .cutAtWord()); - checkShortCircuitCollector("cutWord", "one two,...", 2, input::stream, Joining.with(", ").maxChars(11) - .cutAtWord()); - checkShortCircuitCollector("cutWord", "one two...", 2, input::stream, Joining.with(", ").maxChars(10) - .cutAtWord()); - checkShortCircuitCollector("cutWord", "one ...", 2, input::stream, Joining.with(", ").maxChars(9).cutAtWord()); - checkShortCircuitCollector("cutWord", "one...", 1, input::stream, Joining.with(", ").maxChars(6).cutAtWord()); - - checkShortCircuitCollector("cutCodePoint", "one two, three four, f...", 4, input::stream, Joining.with(", ") - .maxChars(25)); - checkShortCircuitCollector("cutCodePoint", "one two, ...", 2, input::stream, Joining.with(", ").maxChars(12)); - checkShortCircuitCollector("cutCodePoint", "one two,...", 2, input::stream, Joining.with(", ").maxChars(11)); - checkShortCircuitCollector("cutCodePoint", "one two...", 2, input::stream, Joining.with(", ").maxChars(10)); - checkShortCircuitCollector("cutCodePoint", "one tw...", 2, input::stream, Joining.with(", ").maxChars(9)); - checkShortCircuitCollector("cutCodePoint", "one...", 1, input::stream, Joining.with(", ").maxChars(6)); - } - - @Test - public void testPrefixSuffix() { - List input = Arrays.asList("one two", "three four", "five", "six seven"); - checkShortCircuitCollector("cutWord", "[one two, three four,...]", 3, input::stream, Joining.with(", ").wrap( - "[", "]").maxChars(25).cutAtWord()); - checkShortCircuitCollector("cutWord", "[one two...]", 2, input::stream, Joining.with(", ").maxChars(12).wrap( - "[", "]").cutAtWord()); - checkShortCircuitCollector("cutWord", "[one ...]", 2, input::stream, Joining.with(", ").maxChars(11).wrap("[", - "]").cutAtWord()); - checkShortCircuitCollector("cutWord", "[one ...]", 2, input::stream, Joining.with(", ").maxChars(10).wrap("[", - "]").cutAtWord()); - checkShortCircuitCollector("cutWord", "[one...]", 1, input::stream, Joining.with(", ").maxChars(8).wrap("[", - "]").cutAtWord()); - checkShortCircuitCollector("cutWord", "[...]", 1, input::stream, Joining.with(", ").maxChars(6).wrap("[", "]") - .cutAtWord()); - checkShortCircuitCollector("cutWord", "[..]", 1, input::stream, Joining.with(", ").maxChars(4).wrap("[", "]") - .cutAtWord()); - checkShortCircuitCollector("cutWord", "[.]", 1, input::stream, Joining.with(", ").maxChars(3).wrap("[", "]") - .cutAtWord()); - checkShortCircuitCollector("cutWord", "[]", 0, input::stream, Joining.with(", ").maxChars(2).wrap("[", "]") - .cutAtWord()); - checkShortCircuitCollector("cutWord", "[", 0, input::stream, Joining.with(", ").maxChars(1).wrap("[", "]") - .cutAtWord()); - checkShortCircuitCollector("cutWord", "", 0, input::stream, Joining.with(", ").maxChars(0).wrap("[", "]") - .cutAtWord()); - - checkShortCircuitCollector("cutWord", "a prefix a ", 0, input::stream, Joining.with(" ").maxChars(15).wrap( - "a prefix ", " a suffix").cutAtWord()); - checkShortCircuitCollector("cutWord", "a prefix ", 0, input::stream, Joining.with(" ").maxChars(10).wrap( - "a prefix ", " a suffix").cutAtWord()); - checkShortCircuitCollector("cutWord", "a ", 0, input::stream, Joining.with(" ").maxChars(5).wrap("a prefix ", - " a suffix").cutAtWord()); - } - - @Test - public void testCodePoints() { - String string = "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49\ud801\udc2f\ud801\udc3b"; - List input = Arrays.asList(string, new StringBuilder(string), new StringBuffer(string)); - checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f\ud801", 1, input::stream, Joining.with(",") - .ellipsis("").maxChars(5).cutAnywhere()); - checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") - .ellipsis("").maxChars(5).cutAtCodePoint()); - checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") - .ellipsis("").maxChars(4).cutAtGrapheme()); - checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") - .ellipsis("").maxChars(4).cutAnywhere()); - checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") - .ellipsis("").maxChars(4).cutAtCodePoint()); - checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") - .ellipsis("").maxChars(4).cutAtGrapheme()); - checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28", 1, input::stream, - Joining.with(",").ellipsis("").maxChars(9)); - - checkShortCircuitCollector("maxCodePoints", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49", 1, - input::stream, Joining.with(",").ellipsis("").maxCodePoints(5).cutAnywhere()); - checkShortCircuitCollector("maxCodePoints", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49", 1, - input::stream, Joining.with(",").ellipsis("").maxCodePoints(5).cutAtCodePoint()); - checkShortCircuitCollector("maxCodePoints", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49", 1, - input::stream, Joining.with(",").ellipsis("").maxCodePoints(5).cutAtGrapheme()); - checkShortCircuitCollector("maxCodePoints", string, 2, input::stream, Joining.with(",").ellipsis("") - .maxCodePoints(7)); - checkShortCircuitCollector("maxCodePoints", string + ",", 2, input::stream, Joining.with(",").ellipsis("") - .maxCodePoints(8)); - checkShortCircuitCollector("maxCodePoints", string + ",\ud801\udc14", 2, input::stream, Joining.with(",") - .ellipsis("").maxCodePoints(9).cutAtCodePoint()); - checkShortCircuitCollector("maxCodePoints", string + "," + string + "," + string, 3, input::stream, Joining - .with(",").ellipsis("").maxCodePoints(23)); - checkShortCircuitCollector("maxCodePoints", string + "," + string - + ",\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49\ud801\udc2f", 3, input::stream, Joining - .with(",").ellipsis("").maxCodePoints(22)); - - checkShortCircuitCollector("maxCodePointsPrefix", string, 0, input::stream, Joining.with(",").wrap(string, - string).maxCodePoints(7).cutAnywhere()); - } - - @Test - public void testSurrogates() { - String string = "\ud801\ud801\ud801\ud801\ud801\udc14\udc14\udc14\udc14\udc14"; - List input = Collections.nCopies(3, string); - - checkShortCircuitCollector("highSurr", string.substring(0, 4), 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(4).cutAnywhere()); - checkShortCircuitCollector("highSurr", string.substring(0, 4), 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(4).cutAtCodePoint()); - checkShortCircuitCollector("highSurr", string.substring(0, 4), 1, input::stream, Joining.with(",").ellipsis("") - .maxCodePoints(4).cutAnywhere()); - - checkShortCircuitCollector("lowSurr", string.substring(0, 7), 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(7).cutAnywhere()); - checkShortCircuitCollector("lowSurr", string.substring(0, 7), 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(7).cutAtCodePoint()); - checkShortCircuitCollector("lowSurr", string.substring(0, 8), 1, input::stream, Joining.with(",").ellipsis("") - .maxCodePoints(7).cutAnywhere()); - - } - - @Test - public void testGraphemes() { - String string = "aa\u0300\u0321e\u0300a\u0321a\u0300\u0321a"; - List input = Collections.nCopies(3, string); - checkShortCircuitCollector("maxChars", "aa\u0300\u0321e", 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(5).cutAnywhere()); - checkShortCircuitCollector("maxChars", "aa\u0300\u0321e", 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(5).cutAtCodePoint()); - checkShortCircuitCollector("maxChars", "aa\u0300\u0321", 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(5).cutAtGrapheme()); - checkShortCircuitCollector("maxChars", "aa\u0300\u0321e\u0300", 1, input::stream, Joining.with(",") - .ellipsis("").maxChars(6).cutAtGrapheme()); - checkShortCircuitCollector("maxChars", "aa\u0300\u0321", 1, input::stream, Joining.with(",").ellipsis("") - .maxChars(4).cutAtGrapheme()); - checkShortCircuitCollector("maxChars", "a", 1, input::stream, Joining.with(",").ellipsis("").maxChars(3) - .cutAtGrapheme()); - - checkShortCircuitCollector("maxSymbols", "aa\u0300\u0321e\u0300", 1, input::stream, Joining.with(",").ellipsis( - "").maxGraphemes(3)); - checkShortCircuitCollector("maxSymbols", "aa\u0300\u0321e\u0300a\u0321a\u0300\u0321", 1, input::stream, Joining - .with(",").ellipsis("").maxGraphemes(5)); - checkShortCircuitCollector("maxSymbols", string, 2, input::stream, Joining.with(",").ellipsis("").maxGraphemes( - 6)); - checkShortCircuitCollector("maxSymbols", string + ",", 2, input::stream, Joining.with(",").ellipsis("") - .maxGraphemes(7)); - checkShortCircuitCollector("maxSymbols", string + ",a", 2, input::stream, Joining.with(",").ellipsis("") - .maxGraphemes(8)); - checkShortCircuitCollector("maxSymbols", string + ",aa\u0300\u0321", 2, input::stream, Joining.with(",") - .ellipsis("").maxGraphemes(9)); - - checkShortCircuitCollector("maxSymbolsBeforeDelimiter", "", 1, input::stream, Joining.with(",").ellipsis("") - .maxGraphemes(5).cutBeforeDelimiter()); - checkShortCircuitCollector("maxSymbolsBeforeDelimiter", string, 2, input::stream, Joining.with(",") - .ellipsis("").maxGraphemes(6).cutBeforeDelimiter()); - checkShortCircuitCollector("maxSymbolsBeforeDelimiter", string, 2, input::stream, Joining.with(",") - .ellipsis("").maxGraphemes(7).cutBeforeDelimiter()); - checkShortCircuitCollector("maxSymbolsBeforeDelimiter", string, 2, input::stream, Joining.with(",") - .ellipsis("").maxGraphemes(8).cutBeforeDelimiter()); - - checkShortCircuitCollector("maxSymbolsAfterDelimiter", "", 1, input::stream, Joining.with(",").ellipsis("") - .maxGraphemes(5).cutAfterDelimiter()); - checkShortCircuitCollector("maxSymbolsAfterDelimiter", "", 2, input::stream, Joining.with(",").ellipsis("") - .maxGraphemes(6).cutAfterDelimiter()); - checkShortCircuitCollector("maxSymbolsAfterDelimiter", string + ",", 2, input::stream, Joining.with(",") - .ellipsis("").maxGraphemes(7).cutAfterDelimiter()); - checkShortCircuitCollector("maxSymbolsAfterDelimiter", string + ",", 2, input::stream, Joining.with(",") - .ellipsis("").maxGraphemes(8).cutAfterDelimiter()); - - checkShortCircuitCollector("maxSymbolsBeforeDelimiterPrefix", string, 0, input::stream, Joining.with(",").wrap( - string, string).maxGraphemes(8).cutBeforeDelimiter()); - } - - @Test - public void testMaxElements() { - List input = Arrays.asList("one", "two", "three", "four"); - checkShortCircuitCollector("maxElements", "", 0, StreamEx::empty, Joining.with(", ").maxElements(0)); - checkShortCircuitCollector("maxElements", "...", 1, input::stream, Joining.with(", ").maxElements(0)); - checkShortCircuitCollector("maxElements", "one, ...", 2, input::stream, Joining.with(", ").maxElements(1)); - checkShortCircuitCollector("maxElements", "one, two, ...", 3, input::stream, Joining.with(", ").maxElements(2)); - checkShortCircuitCollector("maxElements", "one, two, three, ...", 4, input::stream, Joining.with(", ").maxElements(3)); - checkShortCircuitCollector("maxElements", "one, two, three, four", 4, input::stream, Joining.with(", ").maxElements(4)); - - checkShortCircuitCollector("maxElements", "...", 1, input::stream, Joining.with(", ").maxElements(0).cutBeforeDelimiter()); - checkShortCircuitCollector("maxElements", "one...", 2, input::stream, Joining.with(", ").maxElements(1).cutBeforeDelimiter()); - checkShortCircuitCollector("maxElements", "one, two...", 3, input::stream, Joining.with(", ").maxElements(2).cutBeforeDelimiter()); - checkShortCircuitCollector("maxElements", "one, two, three...", 4, input::stream, Joining.with(", ").maxElements(3).cutBeforeDelimiter()); - checkShortCircuitCollector("maxElements", "one, two, three, four", 4, input::stream, Joining.with(", ").maxElements(4).cutBeforeDelimiter()); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.IntStreamEx; +import one.util.streamex.Joining; +import one.util.streamex.StreamEx; + +import static one.util.streamex.TestHelpers.StreamExSupplier; +import static one.util.streamex.TestHelpers.checkCollector; +import static one.util.streamex.TestHelpers.checkShortCircuitCollector; +import static one.util.streamex.TestHelpers.streamEx; +import static org.junit.Assert.assertEquals; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class JoiningTest { + @Test(expected = IllegalArgumentException.class) + public void testMaxCharsRange() { + Joining.with(",").maxChars(-1); + } + + @Test(expected = IllegalArgumentException.class) + public void testMaxCodePointsRange() { + Joining.with(",").maxCodePoints(-2); + } + + @Test(expected = IllegalArgumentException.class) + public void testMaxSymbolsRange() { + Joining.with(",").maxGraphemes(Integer.MIN_VALUE); + } + + @Test + public void testSimple() { + Supplier> s = () -> IntStream.range(0, 100).mapToObj(String::valueOf); + checkCollector("joiningSimple", s.get().collect(Collectors.joining(", ")), s, Joining.with(", ")); + checkCollector("joiningWrap", s.get().collect(Collectors.joining(", ", "[", "]")), s, Joining.with(", ").wrap( + "[", "]")); + checkCollector("joiningWrap2", s.get().collect(Collectors.joining(", ", "[(", ")]")), s, Joining.with(", ") + .wrap("(", ")").wrap("[", "]")); + } + + @Test + public void testCutSimple() { + List input = Arrays.asList("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", + "ten"); + assertEquals("", StreamEx.of(input).peek(Assert::fail).collect(Joining.with(", ").maxChars(0).cutAnywhere())); + assertEquals("", StreamEx.of(input).parallel().peek(Assert::fail).collect( + Joining.with(", ").maxChars(0).cutAnywhere())); + String expected = "one, two, three, four, five, six, seven, eight, nine, ten"; + for (int i = 3; i < expected.length() + 5; i++) { + String exp = expected; + if (exp.length() > i) { + exp = exp.substring(0, i - 3) + "..."; + } + String exp2 = expected; + while (exp2.length() > i) { + int pos = exp2.lastIndexOf(", ", exp2.endsWith(", ...") ? exp2.length() - 6 : exp2.length()); + exp2 = pos >= 0 ? exp2.substring(0, pos + 2) + "..." : "..."; + } + for (StreamExSupplier supplier : streamEx(input::stream)) { + assertEquals(supplier + "/#" + i, exp, supplier.get().collect( + Joining.with(", ").maxChars(i).cutAnywhere())); + assertEquals(supplier + "/#" + i, expected.substring(0, Math.min(i, expected.length())), supplier.get() + .collect(Joining.with(", ").ellipsis("").maxChars(i).cutAnywhere())); + assertEquals(supplier + "/#" + i, exp2, supplier.get().collect( + Joining.with(", ").maxChars(i).cutAfterDelimiter())); + } + } + + byte[] data = { (byte) 0xFF, 0x30, 0x40, 0x50, 0x70, 0x12, (byte) 0xF0 }; + assertEquals("FF 30 40 50 ...", IntStreamEx.of(data).mapToObj( + b -> String.format(Locale.ENGLISH, "%02X", b & 0xFF)).collect( + Joining.with(" ").maxChars(15).cutAfterDelimiter())); + } + + @Test + public void testCuts() { + List input = Arrays.asList("one two", "three four", "five", "six seven"); + + checkShortCircuitCollector("cutBefore", "one two, three four...", 4, input::stream, Joining.with(", ") + .maxChars(25).cutBeforeDelimiter()); + checkShortCircuitCollector("cutBefore", "one two...", 2, input::stream, Joining.with(", ").maxChars(10) + .cutBeforeDelimiter()); + checkShortCircuitCollector("cutBefore", "...", 2, input::stream, Joining.with(", ").maxChars(9) + .cutBeforeDelimiter()); + + checkShortCircuitCollector("cutAfter", "one two, three four, ...", 4, input::stream, Joining.with(", ") + .maxChars(25).cutAfterDelimiter()); + checkShortCircuitCollector("cutAfter", "one two, ...", 2, input::stream, Joining.with(", ").maxChars(12) + .cutAfterDelimiter()); + checkShortCircuitCollector("cutAfter", "...", 2, input::stream, Joining.with(", ").maxChars(11) + .cutAfterDelimiter()); + + checkShortCircuitCollector("cutWord", "one two, three four, ...", 4, input::stream, Joining.with(", ") + .maxChars(25).cutAtWord()); + checkShortCircuitCollector("cutWord", "one two, ...", 2, input::stream, Joining.with(", ").maxChars(12) + .cutAtWord()); + checkShortCircuitCollector("cutWord", "one two,...", 2, input::stream, Joining.with(", ").maxChars(11) + .cutAtWord()); + checkShortCircuitCollector("cutWord", "one two...", 2, input::stream, Joining.with(", ").maxChars(10) + .cutAtWord()); + checkShortCircuitCollector("cutWord", "one ...", 2, input::stream, Joining.with(", ").maxChars(9).cutAtWord()); + checkShortCircuitCollector("cutWord", "one...", 1, input::stream, Joining.with(", ").maxChars(6).cutAtWord()); + + checkShortCircuitCollector("cutCodePoint", "one two, three four, f...", 4, input::stream, Joining.with(", ") + .maxChars(25)); + checkShortCircuitCollector("cutCodePoint", "one two, ...", 2, input::stream, Joining.with(", ").maxChars(12)); + checkShortCircuitCollector("cutCodePoint", "one two,...", 2, input::stream, Joining.with(", ").maxChars(11)); + checkShortCircuitCollector("cutCodePoint", "one two...", 2, input::stream, Joining.with(", ").maxChars(10)); + checkShortCircuitCollector("cutCodePoint", "one tw...", 2, input::stream, Joining.with(", ").maxChars(9)); + checkShortCircuitCollector("cutCodePoint", "one...", 1, input::stream, Joining.with(", ").maxChars(6)); + } + + @Test + public void testPrefixSuffix() { + List input = Arrays.asList("one two", "three four", "five", "six seven"); + checkShortCircuitCollector("cutWord", "[one two, three four,...]", 3, input::stream, Joining.with(", ").wrap( + "[", "]").maxChars(25).cutAtWord()); + checkShortCircuitCollector("cutWord", "[one two...]", 2, input::stream, Joining.with(", ").maxChars(12).wrap( + "[", "]").cutAtWord()); + checkShortCircuitCollector("cutWord", "[one ...]", 2, input::stream, Joining.with(", ").maxChars(11).wrap("[", + "]").cutAtWord()); + checkShortCircuitCollector("cutWord", "[one ...]", 2, input::stream, Joining.with(", ").maxChars(10).wrap("[", + "]").cutAtWord()); + checkShortCircuitCollector("cutWord", "[one...]", 1, input::stream, Joining.with(", ").maxChars(8).wrap("[", + "]").cutAtWord()); + checkShortCircuitCollector("cutWord", "[...]", 1, input::stream, Joining.with(", ").maxChars(6).wrap("[", "]") + .cutAtWord()); + checkShortCircuitCollector("cutWord", "[..]", 1, input::stream, Joining.with(", ").maxChars(4).wrap("[", "]") + .cutAtWord()); + checkShortCircuitCollector("cutWord", "[.]", 1, input::stream, Joining.with(", ").maxChars(3).wrap("[", "]") + .cutAtWord()); + checkShortCircuitCollector("cutWord", "[]", 0, input::stream, Joining.with(", ").maxChars(2).wrap("[", "]") + .cutAtWord()); + checkShortCircuitCollector("cutWord", "[", 0, input::stream, Joining.with(", ").maxChars(1).wrap("[", "]") + .cutAtWord()); + checkShortCircuitCollector("cutWord", "", 0, input::stream, Joining.with(", ").maxChars(0).wrap("[", "]") + .cutAtWord()); + + checkShortCircuitCollector("cutWord", "a prefix a ", 0, input::stream, Joining.with(" ").maxChars(15).wrap( + "a prefix ", " a suffix").cutAtWord()); + checkShortCircuitCollector("cutWord", "a prefix ", 0, input::stream, Joining.with(" ").maxChars(10).wrap( + "a prefix ", " a suffix").cutAtWord()); + checkShortCircuitCollector("cutWord", "a ", 0, input::stream, Joining.with(" ").maxChars(5).wrap("a prefix ", + " a suffix").cutAtWord()); + } + + @Test + public void testCodePoints() { + String string = "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49\ud801\udc2f\ud801\udc3b"; + List input = Arrays.asList(string, new StringBuilder(string), new StringBuffer(string)); + checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f\ud801", 1, input::stream, Joining.with(",") + .ellipsis("").maxChars(5).cutAnywhere()); + checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") + .ellipsis("").maxChars(5).cutAtCodePoint()); + checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") + .ellipsis("").maxChars(4).cutAtGrapheme()); + checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") + .ellipsis("").maxChars(4).cutAnywhere()); + checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") + .ellipsis("").maxChars(4).cutAtCodePoint()); + checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f", 1, input::stream, Joining.with(",") + .ellipsis("").maxChars(4).cutAtGrapheme()); + checkShortCircuitCollector("maxChars", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28", 1, input::stream, + Joining.with(",").ellipsis("").maxChars(9)); + + checkShortCircuitCollector("maxCodePoints", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49", 1, + input::stream, Joining.with(",").ellipsis("").maxCodePoints(5).cutAnywhere()); + checkShortCircuitCollector("maxCodePoints", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49", 1, + input::stream, Joining.with(",").ellipsis("").maxCodePoints(5).cutAtCodePoint()); + checkShortCircuitCollector("maxCodePoints", "\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49", 1, + input::stream, Joining.with(",").ellipsis("").maxCodePoints(5).cutAtGrapheme()); + checkShortCircuitCollector("maxCodePoints", string, 2, input::stream, Joining.with(",").ellipsis("") + .maxCodePoints(7)); + checkShortCircuitCollector("maxCodePoints", string + ",", 2, input::stream, Joining.with(",").ellipsis("") + .maxCodePoints(8)); + checkShortCircuitCollector("maxCodePoints", string + ",\ud801\udc14", 2, input::stream, Joining.with(",") + .ellipsis("").maxCodePoints(9).cutAtCodePoint()); + checkShortCircuitCollector("maxCodePoints", string + "," + string + "," + string, 3, input::stream, Joining + .with(",").ellipsis("").maxCodePoints(23)); + checkShortCircuitCollector("maxCodePoints", string + "," + string + + ",\ud801\udc14\ud801\udc2f\ud801\udc45\ud801\udc28\ud801\udc49\ud801\udc2f", 3, input::stream, Joining + .with(",").ellipsis("").maxCodePoints(22)); + + checkShortCircuitCollector("maxCodePointsPrefix", string, 0, input::stream, Joining.with(",").wrap(string, + string).maxCodePoints(7).cutAnywhere()); + } + + @Test + public void testSurrogates() { + String string = "\ud801\ud801\ud801\ud801\ud801\udc14\udc14\udc14\udc14\udc14"; + List input = Collections.nCopies(3, string); + + checkShortCircuitCollector("highSurr", string.substring(0, 4), 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(4).cutAnywhere()); + checkShortCircuitCollector("highSurr", string.substring(0, 4), 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(4).cutAtCodePoint()); + checkShortCircuitCollector("highSurr", string.substring(0, 4), 1, input::stream, Joining.with(",").ellipsis("") + .maxCodePoints(4).cutAnywhere()); + + checkShortCircuitCollector("lowSurr", string.substring(0, 7), 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(7).cutAnywhere()); + checkShortCircuitCollector("lowSurr", string.substring(0, 7), 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(7).cutAtCodePoint()); + checkShortCircuitCollector("lowSurr", string.substring(0, 8), 1, input::stream, Joining.with(",").ellipsis("") + .maxCodePoints(7).cutAnywhere()); + + } + + @Test + public void testGraphemes() { + String string = "aa\u0300\u0321e\u0300a\u0321a\u0300\u0321a"; + List input = Collections.nCopies(3, string); + checkShortCircuitCollector("maxChars", "aa\u0300\u0321e", 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(5).cutAnywhere()); + checkShortCircuitCollector("maxChars", "aa\u0300\u0321e", 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(5).cutAtCodePoint()); + checkShortCircuitCollector("maxChars", "aa\u0300\u0321", 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(5).cutAtGrapheme()); + checkShortCircuitCollector("maxChars", "aa\u0300\u0321e\u0300", 1, input::stream, Joining.with(",") + .ellipsis("").maxChars(6).cutAtGrapheme()); + checkShortCircuitCollector("maxChars", "aa\u0300\u0321", 1, input::stream, Joining.with(",").ellipsis("") + .maxChars(4).cutAtGrapheme()); + checkShortCircuitCollector("maxChars", "a", 1, input::stream, Joining.with(",").ellipsis("").maxChars(3) + .cutAtGrapheme()); + + checkShortCircuitCollector("maxSymbols", "aa\u0300\u0321e\u0300", 1, input::stream, Joining.with(",").ellipsis( + "").maxGraphemes(3)); + checkShortCircuitCollector("maxSymbols", "aa\u0300\u0321e\u0300a\u0321a\u0300\u0321", 1, input::stream, Joining + .with(",").ellipsis("").maxGraphemes(5)); + checkShortCircuitCollector("maxSymbols", string, 2, input::stream, Joining.with(",").ellipsis("").maxGraphemes( + 6)); + checkShortCircuitCollector("maxSymbols", string + ",", 2, input::stream, Joining.with(",").ellipsis("") + .maxGraphemes(7)); + checkShortCircuitCollector("maxSymbols", string + ",a", 2, input::stream, Joining.with(",").ellipsis("") + .maxGraphemes(8)); + checkShortCircuitCollector("maxSymbols", string + ",aa\u0300\u0321", 2, input::stream, Joining.with(",") + .ellipsis("").maxGraphemes(9)); + + checkShortCircuitCollector("maxSymbolsBeforeDelimiter", "", 1, input::stream, Joining.with(",").ellipsis("") + .maxGraphemes(5).cutBeforeDelimiter()); + checkShortCircuitCollector("maxSymbolsBeforeDelimiter", string, 2, input::stream, Joining.with(",") + .ellipsis("").maxGraphemes(6).cutBeforeDelimiter()); + checkShortCircuitCollector("maxSymbolsBeforeDelimiter", string, 2, input::stream, Joining.with(",") + .ellipsis("").maxGraphemes(7).cutBeforeDelimiter()); + checkShortCircuitCollector("maxSymbolsBeforeDelimiter", string, 2, input::stream, Joining.with(",") + .ellipsis("").maxGraphemes(8).cutBeforeDelimiter()); + + checkShortCircuitCollector("maxSymbolsAfterDelimiter", "", 1, input::stream, Joining.with(",").ellipsis("") + .maxGraphemes(5).cutAfterDelimiter()); + checkShortCircuitCollector("maxSymbolsAfterDelimiter", "", 2, input::stream, Joining.with(",").ellipsis("") + .maxGraphemes(6).cutAfterDelimiter()); + checkShortCircuitCollector("maxSymbolsAfterDelimiter", string + ",", 2, input::stream, Joining.with(",") + .ellipsis("").maxGraphemes(7).cutAfterDelimiter()); + checkShortCircuitCollector("maxSymbolsAfterDelimiter", string + ",", 2, input::stream, Joining.with(",") + .ellipsis("").maxGraphemes(8).cutAfterDelimiter()); + + checkShortCircuitCollector("maxSymbolsBeforeDelimiterPrefix", string, 0, input::stream, Joining.with(",").wrap( + string, string).maxGraphemes(8).cutBeforeDelimiter()); + } + + @Test + public void testMaxElements() { + List input = Arrays.asList("one", "two", "three", "four"); + checkShortCircuitCollector("maxElements", "", 0, StreamEx::empty, Joining.with(", ").maxElements(0)); + checkShortCircuitCollector("maxElements", "...", 1, input::stream, Joining.with(", ").maxElements(0)); + checkShortCircuitCollector("maxElements", "one, ...", 2, input::stream, Joining.with(", ").maxElements(1)); + checkShortCircuitCollector("maxElements", "one, two, ...", 3, input::stream, Joining.with(", ").maxElements(2)); + checkShortCircuitCollector("maxElements", "one, two, three, ...", 4, input::stream, Joining.with(", ").maxElements(3)); + checkShortCircuitCollector("maxElements", "one, two, three, four", 4, input::stream, Joining.with(", ").maxElements(4)); + + checkShortCircuitCollector("maxElements", "...", 1, input::stream, Joining.with(", ").maxElements(0).cutBeforeDelimiter()); + checkShortCircuitCollector("maxElements", "one...", 2, input::stream, Joining.with(", ").maxElements(1).cutBeforeDelimiter()); + checkShortCircuitCollector("maxElements", "one, two...", 3, input::stream, Joining.with(", ").maxElements(2).cutBeforeDelimiter()); + checkShortCircuitCollector("maxElements", "one, two, three...", 4, input::stream, Joining.with(", ").maxElements(3).cutBeforeDelimiter()); + checkShortCircuitCollector("maxElements", "one, two, three, four", 4, input::stream, Joining.with(", ").maxElements(4).cutBeforeDelimiter()); + } +} diff --git a/src/test/java/one/util/streamex/LongCollectorTest.java b/src/test/java/one/util/streamex/api/LongCollectorTest.java similarity index 97% rename from src/test/java/one/util/streamex/LongCollectorTest.java rename to src/test/java/one/util/streamex/api/LongCollectorTest.java index c413751c..90cc6576 100644 --- a/src/test/java/one/util/streamex/LongCollectorTest.java +++ b/src/test/java/one/util/streamex/api/LongCollectorTest.java @@ -1,189 +1,192 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.util.HashMap; -import java.util.LongSummaryStatistics; -import java.util.Map; -import java.util.OptionalLong; -import java.util.stream.Collectors; -import java.util.stream.LongStream; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static one.util.streamex.TestHelpers.withRandom; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class LongCollectorTest { - @Test - public void testJoining() { - String expected = LongStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining(", ")); - assertEquals(expected, LongStreamEx.range(10000).collect(LongCollector.joining(", "))); - assertEquals(expected, LongStreamEx.range(10000).parallel().collect(LongCollector.joining(", "))); - String expected2 = LongStreamEx.range(0, 1000).boxed().toList().toString(); - assertEquals(expected2, LongStreamEx.range(1000).collect(LongCollector.joining(", ", "[", "]"))); - assertEquals(expected2, LongStreamEx.range(1000).parallel().collect(LongCollector.joining(", ", "[", "]"))); - } - - @Test - public void testCounting() { - assertEquals(5000L, (long) LongStreamEx.range(10000).atLeast(5000).collect(LongCollector.counting())); - assertEquals(5000L, (long) LongStreamEx.range(10000).parallel().atLeast(5000).collect(LongCollector.counting())); - assertEquals(5000, (int) LongStreamEx.range(10000).atLeast(5000).collect(LongCollector.countingInt())); - assertEquals(5000, (int) LongStreamEx.range(10000).parallel().atLeast(5000) - .collect(LongCollector.countingInt())); - } - - @Test - public void testSumming() { - assertEquals(3725, (long) LongStreamEx.range(100).atLeast(50).collect(LongCollector.summing())); - assertEquals(3725, (long) LongStreamEx.range(100).parallel().atLeast(50).collect(LongCollector.summing())); - } - - @Test - public void testMin() { - assertEquals(50, LongStreamEx.range(100).atLeast(50).collect(LongCollector.min()).getAsLong()); - assertFalse(LongStreamEx.range(100).atLeast(200).collect(LongCollector.min()).isPresent()); - } - - @Test - public void testMax() { - assertEquals(99, LongStreamEx.range(100).atLeast(50).collect(LongCollector.max()).getAsLong()); - assertEquals(99, LongStreamEx.range(100).parallel().atLeast(50).collect(LongCollector.max()).getAsLong()); - assertFalse(LongStreamEx.range(100).atLeast(200).collect(LongCollector.max()).isPresent()); - } - - @Test - public void testSummarizing() { - withRandom(r -> { - long[] data = LongStreamEx.of(r, 1000, 1, Long.MAX_VALUE).toArray(); - LongSummaryStatistics expected = LongStream.of(data).summaryStatistics(); - LongSummaryStatistics statistics = LongStreamEx.of(data).collect(LongCollector.summarizing()); - assertEquals(expected.getCount(), statistics.getCount()); - assertEquals(expected.getSum(), statistics.getSum()); - assertEquals(expected.getMax(), statistics.getMax()); - assertEquals(expected.getMin(), statistics.getMin()); - statistics = LongStreamEx.of(data).parallel().collect(LongCollector.summarizing()); - assertEquals(expected.getCount(), statistics.getCount()); - assertEquals(expected.getSum(), statistics.getSum()); - assertEquals(expected.getMax(), statistics.getMax()); - assertEquals(expected.getMin(), statistics.getMin()); - }); - } - - @Test - public void testToArray() { - assertArrayEquals(new long[] { 0, 1, 2, 3, 4 }, LongStreamEx.of(0, 1, 2, 3, 4).collect(LongCollector.toArray())); - } - - @Test - public void testProduct() { - assertEquals(24L, (long) LongStreamEx.of(1, 2, 3, 4).collect(LongCollector.reducing(1, (a, b) -> a * b))); - assertEquals(24L, (long) LongStreamEx.of(1, 2, 3, 4).parallel().collect( - LongCollector.reducing(1, (a, b) -> a * b))); - assertEquals(24L, (long) LongStreamEx.of(1, 2, 3, 4).collect( - LongCollector.reducing((a, b) -> a * b).andThen(OptionalLong::getAsLong))); - } - - @Test - public void testPartitioning() { - long[] expectedEven = LongStream.range(0, 1000).map(i -> i * 2).toArray(); - long[] expectedOdd = LongStream.range(0, 1000).map(i -> i * 2 + 1).toArray(); - Map oddEven = LongStreamEx.range(2000).collect(LongCollector.partitioningBy(i -> i % 2 == 0)); - assertArrayEquals(expectedEven, oddEven.get(true)); - assertArrayEquals(expectedOdd, oddEven.get(false)); - oddEven = LongStreamEx.range(2000).parallel().collect(LongCollector.partitioningBy(i -> i % 2 == 0)); - assertArrayEquals(expectedEven, oddEven.get(true)); - assertArrayEquals(expectedOdd, oddEven.get(false)); - } - - @Test - public void testParts() { - LongCollector> collector = LongCollector.partitioningBy(i -> i % 2 == 0, LongCollector - .mapping(i -> i / 3, LongCollector.joining(","))); - LongCollector> collector2 = LongCollector.partitioningBy(i -> i % 2 == 0, LongCollector - .mappingToObj(i -> i / 3, LongCollector.joining(","))); - Map expected = new HashMap<>(); - expected.put(true, "0,0,1,2,2"); - expected.put(false, "0,1,1,2,3"); - - Map parts = LongStreamEx.range(10).parallel().collect(collector); - assertEquals(expected, parts); - assertEquals(parts, expected); - - Map parts2 = LongStreamEx.range(10).parallel().collect(collector2); - assertEquals(expected, parts2); - assertEquals(parts2, expected); - } - - @Test - public void testGroupingBy() { - Map collected = LongStreamEx.range(2000).collect(LongCollector.groupingBy(i -> i % 3)); - for (long i = 0; i < 3; i++) { - long rem = i; - assertArrayEquals(LongStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); - } - collected = LongStreamEx.range(2000).parallel().collect(LongCollector.groupingBy(i -> i % 3)); - for (long i = 0; i < 3; i++) { - long rem = i; - assertArrayEquals(LongStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); - } - } - - @Test - public void testAsCollector() { - assertEquals(10000499500L, (long) LongStream.range(10000000, 10001000).boxed().collect(LongCollector.summing())); - assertEquals(10000499500L, (long) LongStream.range(10000000, 10001000).boxed().parallel().collect( - LongCollector.summing())); - assertEquals(1000, (long) LongStream.range(0, 1000).boxed().collect(LongCollector.counting())); - } - - @Test - public void testAdaptor() { - assertEquals(10000499500L, (long) LongStreamEx.range(10000000, 10001000).collect( - LongCollector.of(LongCollector.summing()))); - assertEquals(10000499500L, (long) LongStreamEx.range(10000000, 10001000).collect( - LongCollector.of(Collectors.summingLong(Long::longValue)))); - } - - @Test - public void testAveraging() { - assertFalse(LongStreamEx.empty().collect(LongCollector.averaging()).isPresent()); - assertEquals(Long.MAX_VALUE, LongStreamEx.of(Long.MAX_VALUE, Long.MAX_VALUE).collect(LongCollector.averaging()) - .getAsDouble(), 1); - assertEquals(Long.MAX_VALUE, LongStreamEx.of(Long.MAX_VALUE, Long.MAX_VALUE).parallel().collect( - LongCollector.averaging()).getAsDouble(), 1); - } - - @Test - public void testToBooleanArray() { - assertArrayEquals(new boolean[0], LongStreamEx.empty().collect(LongCollector.toBooleanArray(x -> true))); - boolean[] expected = new boolean[] { true, false, false, false, true }; - assertArrayEquals(expected, LongStreamEx.of(Long.MIN_VALUE, Integer.MIN_VALUE, 0, Integer.MAX_VALUE, - Long.MAX_VALUE).collect(LongCollector.toBooleanArray(x -> x < Integer.MIN_VALUE || x > Integer.MAX_VALUE))); - assertArrayEquals(expected, LongStreamEx.of(Long.MIN_VALUE, Integer.MIN_VALUE, 0, Integer.MAX_VALUE, - Long.MAX_VALUE).parallel().collect( - LongCollector.toBooleanArray(x -> x < Integer.MIN_VALUE || x > Integer.MAX_VALUE))); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.util.HashMap; +import java.util.LongSummaryStatistics; +import java.util.Map; +import java.util.OptionalLong; +import java.util.stream.Collectors; +import java.util.stream.LongStream; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.LongCollector; +import one.util.streamex.LongStreamEx; + +import static one.util.streamex.TestHelpers.withRandom; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class LongCollectorTest { + @Test + public void testJoining() { + String expected = LongStream.range(0, 10000).mapToObj(String::valueOf).collect(Collectors.joining(", ")); + assertEquals(expected, LongStreamEx.range(10000).collect(LongCollector.joining(", "))); + assertEquals(expected, LongStreamEx.range(10000).parallel().collect(LongCollector.joining(", "))); + String expected2 = LongStreamEx.range(0, 1000).boxed().toList().toString(); + assertEquals(expected2, LongStreamEx.range(1000).collect(LongCollector.joining(", ", "[", "]"))); + assertEquals(expected2, LongStreamEx.range(1000).parallel().collect(LongCollector.joining(", ", "[", "]"))); + } + + @Test + public void testCounting() { + assertEquals(5000L, (long) LongStreamEx.range(10000).atLeast(5000).collect(LongCollector.counting())); + assertEquals(5000L, (long) LongStreamEx.range(10000).parallel().atLeast(5000).collect(LongCollector.counting())); + assertEquals(5000, (int) LongStreamEx.range(10000).atLeast(5000).collect(LongCollector.countingInt())); + assertEquals(5000, (int) LongStreamEx.range(10000).parallel().atLeast(5000) + .collect(LongCollector.countingInt())); + } + + @Test + public void testSumming() { + assertEquals(3725, (long) LongStreamEx.range(100).atLeast(50).collect(LongCollector.summing())); + assertEquals(3725, (long) LongStreamEx.range(100).parallel().atLeast(50).collect(LongCollector.summing())); + } + + @Test + public void testMin() { + assertEquals(50, LongStreamEx.range(100).atLeast(50).collect(LongCollector.min()).getAsLong()); + assertFalse(LongStreamEx.range(100).atLeast(200).collect(LongCollector.min()).isPresent()); + } + + @Test + public void testMax() { + assertEquals(99, LongStreamEx.range(100).atLeast(50).collect(LongCollector.max()).getAsLong()); + assertEquals(99, LongStreamEx.range(100).parallel().atLeast(50).collect(LongCollector.max()).getAsLong()); + assertFalse(LongStreamEx.range(100).atLeast(200).collect(LongCollector.max()).isPresent()); + } + + @Test + public void testSummarizing() { + withRandom(r -> { + long[] data = LongStreamEx.of(r, 1000, 1, Long.MAX_VALUE).toArray(); + LongSummaryStatistics expected = LongStream.of(data).summaryStatistics(); + LongSummaryStatistics statistics = LongStreamEx.of(data).collect(LongCollector.summarizing()); + assertEquals(expected.getCount(), statistics.getCount()); + assertEquals(expected.getSum(), statistics.getSum()); + assertEquals(expected.getMax(), statistics.getMax()); + assertEquals(expected.getMin(), statistics.getMin()); + statistics = LongStreamEx.of(data).parallel().collect(LongCollector.summarizing()); + assertEquals(expected.getCount(), statistics.getCount()); + assertEquals(expected.getSum(), statistics.getSum()); + assertEquals(expected.getMax(), statistics.getMax()); + assertEquals(expected.getMin(), statistics.getMin()); + }); + } + + @Test + public void testToArray() { + assertArrayEquals(new long[] { 0, 1, 2, 3, 4 }, LongStreamEx.of(0, 1, 2, 3, 4).collect(LongCollector.toArray())); + } + + @Test + public void testProduct() { + assertEquals(24L, (long) LongStreamEx.of(1, 2, 3, 4).collect(LongCollector.reducing(1, (a, b) -> a * b))); + assertEquals(24L, (long) LongStreamEx.of(1, 2, 3, 4).parallel().collect( + LongCollector.reducing(1, (a, b) -> a * b))); + assertEquals(24L, (long) LongStreamEx.of(1, 2, 3, 4).collect( + LongCollector.reducing((a, b) -> a * b).andThen(OptionalLong::getAsLong))); + } + + @Test + public void testPartitioning() { + long[] expectedEven = LongStream.range(0, 1000).map(i -> i * 2).toArray(); + long[] expectedOdd = LongStream.range(0, 1000).map(i -> i * 2 + 1).toArray(); + Map oddEven = LongStreamEx.range(2000).collect(LongCollector.partitioningBy(i -> i % 2 == 0)); + assertArrayEquals(expectedEven, oddEven.get(true)); + assertArrayEquals(expectedOdd, oddEven.get(false)); + oddEven = LongStreamEx.range(2000).parallel().collect(LongCollector.partitioningBy(i -> i % 2 == 0)); + assertArrayEquals(expectedEven, oddEven.get(true)); + assertArrayEquals(expectedOdd, oddEven.get(false)); + } + + @Test + public void testParts() { + LongCollector> collector = LongCollector.partitioningBy(i -> i % 2 == 0, LongCollector + .mapping(i -> i / 3, LongCollector.joining(","))); + LongCollector> collector2 = LongCollector.partitioningBy(i -> i % 2 == 0, LongCollector + .mappingToObj(i -> i / 3, LongCollector.joining(","))); + Map expected = new HashMap<>(); + expected.put(true, "0,0,1,2,2"); + expected.put(false, "0,1,1,2,3"); + + Map parts = LongStreamEx.range(10).parallel().collect(collector); + assertEquals(expected, parts); + assertEquals(parts, expected); + + Map parts2 = LongStreamEx.range(10).parallel().collect(collector2); + assertEquals(expected, parts2); + assertEquals(parts2, expected); + } + + @Test + public void testGroupingBy() { + Map collected = LongStreamEx.range(2000).collect(LongCollector.groupingBy(i -> i % 3)); + for (long i = 0; i < 3; i++) { + long rem = i; + assertArrayEquals(LongStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); + } + collected = LongStreamEx.range(2000).parallel().collect(LongCollector.groupingBy(i -> i % 3)); + for (long i = 0; i < 3; i++) { + long rem = i; + assertArrayEquals(LongStream.range(0, 2000).filter(a -> a % 3 == rem).toArray(), collected.get(i)); + } + } + + @Test + public void testAsCollector() { + assertEquals(10000499500L, (long) LongStream.range(10000000, 10001000).boxed().collect(LongCollector.summing())); + assertEquals(10000499500L, (long) LongStream.range(10000000, 10001000).boxed().parallel().collect( + LongCollector.summing())); + assertEquals(1000, (long) LongStream.range(0, 1000).boxed().collect(LongCollector.counting())); + } + + @Test + public void testAdaptor() { + assertEquals(10000499500L, (long) LongStreamEx.range(10000000, 10001000).collect( + LongCollector.of(LongCollector.summing()))); + assertEquals(10000499500L, (long) LongStreamEx.range(10000000, 10001000).collect( + LongCollector.of(Collectors.summingLong(Long::longValue)))); + } + + @Test + public void testAveraging() { + assertFalse(LongStreamEx.empty().collect(LongCollector.averaging()).isPresent()); + assertEquals(Long.MAX_VALUE, LongStreamEx.of(Long.MAX_VALUE, Long.MAX_VALUE).collect(LongCollector.averaging()) + .getAsDouble(), 1); + assertEquals(Long.MAX_VALUE, LongStreamEx.of(Long.MAX_VALUE, Long.MAX_VALUE).parallel().collect( + LongCollector.averaging()).getAsDouble(), 1); + } + + @Test + public void testToBooleanArray() { + assertArrayEquals(new boolean[0], LongStreamEx.empty().collect(LongCollector.toBooleanArray(x -> true))); + boolean[] expected = new boolean[] { true, false, false, false, true }; + assertArrayEquals(expected, LongStreamEx.of(Long.MIN_VALUE, Integer.MIN_VALUE, 0, Integer.MAX_VALUE, + Long.MAX_VALUE).collect(LongCollector.toBooleanArray(x -> x < Integer.MIN_VALUE || x > Integer.MAX_VALUE))); + assertArrayEquals(expected, LongStreamEx.of(Long.MIN_VALUE, Integer.MIN_VALUE, 0, Integer.MAX_VALUE, + Long.MAX_VALUE).parallel().collect( + LongCollector.toBooleanArray(x -> x < Integer.MIN_VALUE || x > Integer.MAX_VALUE))); + } +} diff --git a/src/test/java/one/util/streamex/LongStreamExTest.java b/src/test/java/one/util/streamex/api/LongStreamExTest.java similarity index 97% rename from src/test/java/one/util/streamex/LongStreamExTest.java rename to src/test/java/one/util/streamex/api/LongStreamExTest.java index 3608bb28..e9632c5b 100644 --- a/src/test/java/one/util/streamex/LongStreamExTest.java +++ b/src/test/java/one/util/streamex/api/LongStreamExTest.java @@ -1,632 +1,636 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.nio.LongBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.OptionalLong; -import java.util.PrimitiveIterator.OfLong; -import java.util.Random; -import java.util.Scanner; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Function; -import java.util.function.LongBinaryOperator; -import java.util.function.LongConsumer; -import java.util.function.LongFunction; -import java.util.function.LongToDoubleFunction; -import java.util.function.LongToIntFunction; -import java.util.function.LongUnaryOperator; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.LongStream; -import java.util.stream.LongStream.Builder; - -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import static one.util.streamex.TestHelpers.assertThrows; -import static one.util.streamex.TestHelpers.checkSpliterator; -import static one.util.streamex.TestHelpers.longStreamEx; -import static one.util.streamex.TestHelpers.streamEx; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - -/** - * @author Tagir Valeev - */ -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class LongStreamExTest { - final LongConsumer EMPTY = l -> { - // nothing - }; - - @Test - public void testCreate() { - assertArrayEquals(new long[] {}, LongStreamEx.empty().toArray()); - // double test is intended - assertArrayEquals(new long[] {}, LongStreamEx.empty().toArray()); - assertArrayEquals(new long[] { 1 }, LongStreamEx.of(1).toArray()); - assertArrayEquals(new long[] { 1 }, LongStreamEx.of(OptionalLong.of(1)).toArray()); - assertArrayEquals(new long[] {}, LongStreamEx.of(OptionalLong.empty()).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 3).toArray()); - assertArrayEquals(new long[] { 4, 6 }, LongStreamEx.of(new long[] { 2, 4, 6, 8, 10 }, 1, 3).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(LongStream.of(1, 2, 3)).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(Arrays.asList(1L, 2L, 3L)).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.range(1L, 4L).toArray()); - assertArrayEquals(new long[] { 0, 1, 2 }, LongStreamEx.range(3L).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.rangeClosed(1, 3).toArray()); - assertArrayEquals(new long[] { 1, 1, 1, 1 }, LongStreamEx.generate(() -> 1).limit(4).toArray()); - assertArrayEquals(new long[] { 1, 1, 1, 1 }, LongStreamEx.constant(1L, 4).toArray()); - assertEquals(10, LongStreamEx.of(new Random(), 10).count()); - assertTrue(LongStreamEx.of(new Random(), 100, 1, 10).allMatch(x -> x >= 1 && x < 10)); - assertArrayEquals(LongStreamEx.of(new Random(1), 100, 1, 10).toArray(), LongStreamEx.of(new Random(1), 1, 10) - .limit(100).toArray()); - assertArrayEquals(LongStreamEx.of(new Random(1), 100).toArray(), LongStreamEx.of(new Random(1)).limit(100) - .toArray()); - - LongStream stream = LongStreamEx.of(1, 2, 3); - assertSame(stream, LongStreamEx.of(stream)); - - assertArrayEquals(new long[] { 4, 2, 0, -2, -4 }, LongStreamEx.zip(new long[] { 5, 4, 3, 2, 1 }, - new long[] { 1, 2, 3, 4, 5 }, (a, b) -> a - b).toArray()); - - assertArrayEquals(new long[] { 1, 5, 3 }, LongStreamEx.of(Spliterators.spliterator(new long[] { 1, 5, 3 }, 0)) - .toArray()); - assertArrayEquals(new long[] { 1, 5, 3 }, LongStreamEx.of( - Spliterators.iterator(Spliterators.spliterator(new long[] { 1, 5, 3 }, 0))).toArray()); - assertArrayEquals(new long[0], LongStreamEx.of(Spliterators.iterator(Spliterators.emptyLongSpliterator())) - .parallel().toArray()); - - assertArrayEquals(new long[] { 2, 4, 6 }, LongStreamEx.of(new Long[] { 2L, 4L, 6L }).toArray()); - } - - @Test - public void testOfLongBuffer() { - long[] data = LongStreamEx.range(100).toArray(); - assertArrayEquals(data, LongStreamEx.of(LongBuffer.wrap(data)).toArray()); - assertArrayEquals(LongStreamEx.range(50, 70).toArray(), LongStreamEx.of(LongBuffer.wrap(data, 50, 20)).toArray()); - assertArrayEquals(data, LongStreamEx.of(LongBuffer.wrap(data)).parallel().toArray()); - assertArrayEquals(LongStreamEx.range(50, 70).toArray(), LongStreamEx.of(LongBuffer.wrap(data, 50, 20)).parallel() - .toArray()); - } - - @Test - public void testIterate() { - assertArrayEquals(new long[] { 1, 2, 4, 8, 16 }, LongStreamEx.iterate(1, x -> x * 2).limit(5).toArray()); - assertArrayEquals(new long[] { 1, 2, 4, 8, 16, 32, 64 }, LongStreamEx.iterate(1, x -> x < 100, x -> x * 2).toArray()); - assertEquals(0, LongStreamEx.iterate(0, x -> x < 0, x -> 1 / x).count()); - assertFalse(LongStreamEx.iterate(1, x -> x < 100, x -> x * 2).has(10)); - checkSpliterator("iterate", () -> LongStreamEx.iterate(1, x -> x < 100, x -> x * 2).spliterator()); - } - - @Test - public void testLongs() { - assertEquals(Long.MAX_VALUE, LongStreamEx.longs().spliterator().getExactSizeIfKnown()); - assertArrayEquals(new long[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, LongStreamEx.longs().limit(10).toArray()); - } - - @Test - public void testRangeStep() { - assertArrayEquals(new long[] { 0 }, LongStreamEx.range(0, 1000, 100000).toArray()); - assertArrayEquals(new long[] { 0, Long.MAX_VALUE - 1 }, LongStreamEx.range(0, Long.MAX_VALUE, - Long.MAX_VALUE - 1).toArray()); - assertArrayEquals(new long[] { Long.MIN_VALUE, -1, Long.MAX_VALUE - 1 }, LongStreamEx.range(Long.MIN_VALUE, - Long.MAX_VALUE, Long.MAX_VALUE).toArray()); - assertArrayEquals(new long[] { Long.MIN_VALUE, -1 }, LongStreamEx.range(Long.MIN_VALUE, Long.MAX_VALUE - 1, - Long.MAX_VALUE).toArray()); - assertArrayEquals(new long[] { Long.MAX_VALUE, -1 }, LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE, - Long.MIN_VALUE).toArray()); - assertArrayEquals(new long[] { Long.MAX_VALUE }, LongStreamEx.range(Long.MAX_VALUE, 0, Long.MIN_VALUE) - .toArray()); - assertArrayEquals(new long[] { 1, Long.MIN_VALUE + 1 }, LongStreamEx.range(1, Long.MIN_VALUE, Long.MIN_VALUE) - .toArray()); - assertArrayEquals(new long[] { 0 }, LongStreamEx.range(0, Long.MIN_VALUE, Long.MIN_VALUE).toArray()); - assertArrayEquals(new long[] { 0, 2, 4, 6, 8 }, LongStreamEx.range(0, 9, 2).toArray()); - assertArrayEquals(new long[] { 0, 2, 4, 6 }, LongStreamEx.range(0, 8, 2).toArray()); - assertArrayEquals(new long[] { 0, -2, -4, -6, -8 }, LongStreamEx.range(0, -9, -2).toArray()); - assertArrayEquals(new long[] { 0, -2, -4, -6 }, LongStreamEx.range(0, -8, -2).toArray()); - assertArrayEquals(new long[] { 5, 4, 3, 2, 1, 0 }, LongStreamEx.range(5, -1, -1).toArray()); - assertEquals(Integer.MAX_VALUE + 1L, LongStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE, 2).spliterator() - .getExactSizeIfKnown()); - assertEquals(Long.MAX_VALUE, LongStreamEx.range(Long.MIN_VALUE, Long.MAX_VALUE - 1, 2).spliterator() - .getExactSizeIfKnown()); - java.util.Spliterator.OfLong spliterator = LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE, -2).spliterator(); - assertEquals(-1, spliterator.getExactSizeIfKnown()); - assertTrue(spliterator.tryAdvance(EMPTY)); - assertEquals(Long.MAX_VALUE, spliterator.estimateSize()); - assertTrue(spliterator.tryAdvance(EMPTY)); - assertEquals(Long.MAX_VALUE - 1, spliterator.estimateSize()); - assertEquals(Long.MAX_VALUE, LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE + 1, -2).spliterator() - .getExactSizeIfKnown()); - assertEquals(-1, LongStreamEx.range(Long.MIN_VALUE, Long.MAX_VALUE, 1).spliterator().getExactSizeIfKnown()); - assertEquals(-1, LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE, -1).spliterator().getExactSizeIfKnown()); - assertEquals(0, LongStreamEx.range(0, -1000, 1).count()); - assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, 1).toArray()); - assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, 2).toArray()); - assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 11, 2).toArray()); - assertArrayEquals(new long[] {}, LongStreamEx.rangeClosed(11, 10, 2).toArray()); - assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, -1).toArray()); - assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, -2).toArray()); - assertArrayEquals(new long[] {}, LongStreamEx.rangeClosed(10, 11, -2).toArray()); - assertArrayEquals(new long[] {11}, LongStreamEx.rangeClosed(11, 10, -2).toArray()); - assertEquals(0, LongStreamEx.range(0, 1000, -1).count()); - assertEquals(0, LongStreamEx.range(0, 0, -1).count()); - assertEquals(0, LongStreamEx.range(0, 0, 1).count()); - assertEquals(0, LongStreamEx.range(0, -1000, 2).count()); - assertEquals(0, LongStreamEx.range(0, 1000, -2).count()); - assertEquals(0, LongStreamEx.range(0, 0, -2).count()); - assertEquals(0, LongStreamEx.range(0, 0, 2).count()); - - assertEquals(0, LongStreamEx.range(0, Long.MIN_VALUE, 2).spliterator().getExactSizeIfKnown()); - assertEquals(0, LongStreamEx.range(0, Long.MAX_VALUE, -2).spliterator().getExactSizeIfKnown()); - - assertThrows(IllegalArgumentException.class, () -> LongStreamEx.range(0, 1000, 0)); - } - - @Test - public void testRangeClosedStep() { - assertArrayEquals(new long[] { 0 }, LongStreamEx.rangeClosed(0, 1000, 100000).toArray()); - assertArrayEquals(new long[] { 0, 1000 }, LongStreamEx.rangeClosed(0, 1000, 1000).toArray()); - assertArrayEquals(new long[] { 0, Long.MAX_VALUE - 1 }, LongStreamEx.rangeClosed(0, Long.MAX_VALUE - 1, - Long.MAX_VALUE - 1).toArray()); - assertArrayEquals(new long[] { Long.MIN_VALUE, -1, Long.MAX_VALUE - 1 }, LongStreamEx.rangeClosed( - Long.MIN_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE).toArray()); - assertArrayEquals(new long[] { Long.MIN_VALUE, -1 }, LongStreamEx.rangeClosed(Long.MIN_VALUE, - Long.MAX_VALUE - 2, Long.MAX_VALUE).toArray()); - assertArrayEquals(new long[] { Long.MAX_VALUE, -1 }, LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE, - Long.MIN_VALUE).toArray()); - assertArrayEquals(new long[] { Long.MAX_VALUE }, LongStreamEx.rangeClosed(Long.MAX_VALUE, 0, Long.MIN_VALUE) - .toArray()); - assertArrayEquals(new long[] { 0, Long.MIN_VALUE }, LongStreamEx.rangeClosed(0, Long.MIN_VALUE, Long.MIN_VALUE) - .toArray()); - assertArrayEquals(new long[] { 0, 2, 4, 6, 8 }, LongStreamEx.rangeClosed(0, 9, 2).toArray()); - assertArrayEquals(new long[] { 0, 2, 4, 6, 8 }, LongStreamEx.rangeClosed(0, 8, 2).toArray()); - assertArrayEquals(new long[] { 0, 2, 4, 6 }, LongStreamEx.rangeClosed(0, 7, 2).toArray()); - assertArrayEquals(new long[] { 0, -2, -4, -6, -8 }, LongStreamEx.rangeClosed(0, -9, -2).toArray()); - assertArrayEquals(new long[] { 0, -2, -4, -6, -8 }, LongStreamEx.rangeClosed(0, -8, -2).toArray()); - assertArrayEquals(new long[] { 0, -2, -4, -6 }, LongStreamEx.rangeClosed(0, -7, -2).toArray()); - assertArrayEquals(new long[] { 5, 4, 3, 2, 1, 0 }, LongStreamEx.rangeClosed(5, 0, -1).toArray()); - assertEquals(Integer.MAX_VALUE + 1L, LongStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE, 2) - .spliterator().getExactSizeIfKnown()); - assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(Long.MIN_VALUE, Long.MAX_VALUE - 2, 2).spliterator() - .getExactSizeIfKnown()); - java.util.Spliterator.OfLong spliterator = LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE, -2) - .spliterator(); - assertEquals(-1, spliterator.getExactSizeIfKnown()); - assertTrue(spliterator.tryAdvance(EMPTY)); - assertEquals(Long.MAX_VALUE, spliterator.estimateSize()); - assertTrue(spliterator.tryAdvance(EMPTY)); - assertEquals(Long.MAX_VALUE - 1, spliterator.estimateSize()); - assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE + 2, -2).spliterator() - .getExactSizeIfKnown()); - assertEquals(-1, LongStreamEx.rangeClosed(Long.MIN_VALUE, Long.MAX_VALUE, 1).spliterator() - .getExactSizeIfKnown()); - assertEquals(-1, LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE, -1).spliterator() - .getExactSizeIfKnown()); - assertEquals(0, LongStreamEx.rangeClosed(0, -1000, 1).count()); - assertEquals(0, LongStreamEx.rangeClosed(0, 1000, -1).count()); - assertEquals(0, LongStreamEx.rangeClosed(0, 1, -1).count()); - assertEquals(0, LongStreamEx.rangeClosed(0, -1, 1).count()); - assertEquals(0, LongStreamEx.rangeClosed(0, -1000, 2).count()); - assertEquals(0, LongStreamEx.rangeClosed(0, 1000, -2).count()); - assertEquals(0, LongStreamEx.rangeClosed(0, 1, -2).count()); - assertEquals(0, LongStreamEx.rangeClosed(0, -1, 2).count()); - - assertEquals(0, LongStreamEx.rangeClosed(0, Long.MIN_VALUE, 2).spliterator().getExactSizeIfKnown()); - assertEquals(0, LongStreamEx.rangeClosed(0, Long.MAX_VALUE, -2).spliterator().getExactSizeIfKnown()); - } - - @Test - public void testBasics() { - assertFalse(LongStreamEx.of(1).isParallel()); - assertTrue(LongStreamEx.of(1).parallel().isParallel()); - assertFalse(LongStreamEx.of(1).parallel().sequential().isParallel()); - AtomicInteger i = new AtomicInteger(); - try (LongStreamEx s = LongStreamEx.of(1).onClose(i::incrementAndGet)) { - assertEquals(1, s.count()); - } - assertEquals(1, i.get()); - assertEquals(6, LongStreamEx.range(0, 4).sum()); - assertEquals(3, LongStreamEx.range(0, 4).max().getAsLong()); - assertEquals(0, LongStreamEx.range(0, 4).min().getAsLong()); - assertEquals(1.5, LongStreamEx.range(0, 4).average().getAsDouble(), 0.000001); - assertEquals(4, LongStreamEx.range(0, 4).summaryStatistics().getCount()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.range(0, 5).skip(1).limit(3).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(3, 1, 2).sorted().toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 1, 3, 2).distinct().toArray()); - assertArrayEquals(new int[] { 2, 4, 6 }, LongStreamEx.range(1, 4).mapToInt(x -> (int) x * 2).toArray()); - assertArrayEquals(new long[] { 2, 4, 6 }, LongStreamEx.range(1, 4).map(x -> x * 2).toArray()); - assertArrayEquals(new double[] { 2, 4, 6 }, LongStreamEx.range(1, 4).mapToDouble(x -> x * 2).toArray(), 0.0); - assertArrayEquals(new long[] { 1, 3 }, LongStreamEx.range(0, 5).filter(x -> x % 2 == 1).toArray()); - assertEquals(6, LongStreamEx.of(1, 2, 3).reduce(Long::sum).getAsLong()); - assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(1, Long.MAX_VALUE).spliterator().getExactSizeIfKnown()); - - assertTrue(LongStreamEx.of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)); - assertFalse(LongStreamEx.of(1, 2, 3).unordered().spliterator().hasCharacteristics(Spliterator.ORDERED)); - - OfLong iterator = LongStreamEx.of(1, 2, 3).iterator(); - assertEquals(1L, iterator.nextLong()); - assertEquals(2L, iterator.nextLong()); - assertEquals(3L, iterator.nextLong()); - assertFalse(iterator.hasNext()); - - AtomicInteger idx = new AtomicInteger(); - long[] result = new long[500]; - LongStreamEx.range(1000).atLeast(500).parallel().forEachOrdered(val -> result[idx.getAndIncrement()] = val); - assertArrayEquals(LongStreamEx.range(500, 1000).toArray(), result); - - assertTrue(LongStreamEx.empty().noneMatch(x -> true)); - assertFalse(LongStreamEx.of(1).noneMatch(x -> true)); - assertTrue(LongStreamEx.of(1).noneMatch(x -> false)); - } - - @Test - public void testForEach() { - List list = new ArrayList<>(); - LongStreamEx.of(1).forEach(list::add); - assertEquals(Arrays.asList(1L), list); - streamEx(() -> StreamEx.of(1L, 2L, 3L), s -> { - AtomicLong count = new AtomicLong(0); - s.get().mapToLong(Long::longValue).forEach(count::addAndGet); - assertEquals(6, count.get()); - s.get().mapToLong(Long::longValue).pairMap((a, b) -> b - a).forEach(count::addAndGet); - assertEquals(8, count.get()); - }); - } - - @Test - public void testFlatMap() { - assertArrayEquals(new long[] { 0, 0, 1, 0, 1, 2 }, LongStreamEx.of(1, 2, 3).flatMap(LongStreamEx::range) - .toArray()); - assertArrayEquals(new int[] { 1, 5, 1, 4, 2, 0, 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5, 4, 7, 7, 5, 8, 0, 7 }, - LongStreamEx.of(15, 14, 20, Long.MAX_VALUE).flatMapToInt(n -> String.valueOf(n).chars().map(x -> x - '0')) - .toArray()); - - String expected = LongStreamEx.range(200).boxed().flatMap( - i -> LongStreamEx.range(0, i).mapToObj(j -> i + ":" + j)).joining("/"); - String res = LongStreamEx.range(200).flatMapToObj(i -> LongStreamEx.range(i).mapToObj(j -> i + ":" + j)) - .joining("/"); - String parallel = LongStreamEx.range(200).parallel().flatMapToObj( - i -> LongStreamEx.range(i).mapToObj(j -> i + ":" + j)).joining("/"); - assertEquals(expected, res); - assertEquals(expected, parallel); - - double[] fractions = LongStreamEx.range(1, 5).flatMapToDouble( - i -> LongStreamEx.range(1, i).mapToDouble(j -> ((double) j) / i)).toArray(); - assertArrayEquals(new double[] { 1 / 2.0, 1 / 3.0, 2 / 3.0, 1 / 4.0, 2 / 4.0, 3 / 4.0 }, fractions, 0.000001); - } - - @Test - public void testPrepend() { - assertArrayEquals(new long[] { -1, 0, 1, 2, 3 }, LongStreamEx.of(1, 2, 3).prepend(-1, 0).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 3).prepend().toArray()); - assertArrayEquals(new long[] { 10, 11, 0, 1, 2, 3 }, LongStreamEx.range(0, 4).prepend( - LongStreamEx.range(10, 12)).toArray()); - } - - @Test - public void testAppend() { - assertArrayEquals(new long[] { 1, 2, 3, 4, 5 }, LongStreamEx.of(1, 2, 3).append(4, 5).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 3).append().toArray()); - assertArrayEquals(new long[] { 0, 1, 2, 3, 10, 11 }, LongStreamEx.range(0, 4) - .append(LongStreamEx.range(10, 12)).toArray()); - } - - @Test - public void testHas() { - assertTrue(LongStreamEx.range(1, 4).has(3)); - assertFalse(LongStreamEx.range(1, 4).has(4)); - } - - @Test - public void testWithout() { - assertArrayEquals(new long[] { 1, 2 }, LongStreamEx.range(1, 4).without(3).toArray()); - assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.range(1, 4).without(5).toArray()); - LongStreamEx lse = LongStreamEx.range(5); - assertSame(lse, lse.without()); - assertArrayEquals(new long[] { 0, 1, 3, 4 }, LongStreamEx.range(5).without(new long[] { 2 }).toArray()); - assertArrayEquals(new long[] { 0 }, LongStreamEx.range(5).without(1, 2, 3, 4, 5, 6).toArray()); - } - - @Test - public void testRanges() { - assertArrayEquals(new long[] { 5, 4, Long.MAX_VALUE }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).greater( - 3).toArray()); - assertArrayEquals(new long[] {}, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).greater(Long.MAX_VALUE) - .toArray()); - assertArrayEquals(new long[] { 5, 3, 4, Long.MAX_VALUE }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE) - .atLeast(3).toArray()); - assertArrayEquals(new long[] { Long.MAX_VALUE }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).atLeast( - Long.MAX_VALUE).toArray()); - assertArrayEquals(new long[] { 1, -1 }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).less(3).toArray()); - assertArrayEquals(new long[] { 1, 3, -1 }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).atMost(3).toArray()); - assertArrayEquals(new long[] { 1, 3, 4, -1 }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).atMost(4).toArray()); - } - - @Test - public void testFind() { - assertEquals(6, LongStreamEx.range(1, 10).findFirst(i -> i > 5).getAsLong()); - assertFalse(LongStreamEx.range(1, 10).findAny(i -> i > 10).isPresent()); - } - - @Test - public void testRemove() { - assertArrayEquals(new long[] { 1, 2 }, LongStreamEx.of(1, 2, 3).remove(x -> x > 2).toArray()); - } - - @Test - public void testSort() { - assertArrayEquals(new long[] { 0, 3, 6, 1, 4, 7, 2, 5, 8 }, LongStreamEx.range(0, 9).sortedByLong( - i -> i % 3 * 3 + i / 3).toArray()); - assertArrayEquals(new long[] { 0, 4, 8, 1, 5, 9, 2, 6, 3, 7 }, LongStreamEx.range(0, 10).sortedByInt( - i -> (int) i % 4).toArray()); - assertArrayEquals(new long[] { 10, 11, 5, 6, 7, 8, 9 }, LongStreamEx.range(5, 12).sortedBy(String::valueOf) - .toArray()); - assertArrayEquals(new long[] { Long.MAX_VALUE, 1000, 1, 0, -10, Long.MIN_VALUE }, LongStreamEx.of(0, 1, 1000, - -10, Long.MIN_VALUE, Long.MAX_VALUE).reverseSorted().toArray()); - assertArrayEquals(new long[] { Long.MAX_VALUE, Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MAX_VALUE - 1 }, - LongStreamEx.of(Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MAX_VALUE - 1, Long.MAX_VALUE).sortedByLong( - l -> l + 1).toArray()); - assertArrayEquals(new long[] { -10, Long.MIN_VALUE, Long.MAX_VALUE, 1000, 1, 0 }, LongStreamEx.of(0, 1, 1000, - -10, Long.MIN_VALUE, Long.MAX_VALUE).sortedByDouble(x -> 1.0 / x).toArray()); - } - - @SafeVarargs - private static void checkEmpty(Function... fns) { - int i = 0; - for (Function fn : fns) { - assertFalse("#" + i, fn.apply(LongStreamEx.empty()).isPresent()); - assertFalse("#" + i, fn.apply(LongStreamEx.of(1, 2, 3, 4).greater(5).parallel()).isPresent()); - assertEquals("#" + i, 10, fn.apply(LongStreamEx.of(1, 1, 1, 1, 10, 10, 10, 10).greater(5).parallel()) - .getAsLong()); - i++; - } - } - - @Test - public void testMinMax() { - checkEmpty(s -> s.maxBy(Long::valueOf), s -> s.maxByInt(x -> (int) x), s -> s.maxByLong(x -> x), s -> s - .maxByDouble(x -> x), s -> s.minBy(Long::valueOf), s -> s.minByInt(x -> (int) x), s -> s - .minByLong(x -> x), s -> s.minByDouble(x -> x)); - assertEquals(9, LongStreamEx.range(5, 12).max(Comparator.comparing(String::valueOf)) - .getAsLong()); - assertEquals(10, LongStreamEx.range(5, 12).min(Comparator.comparing(String::valueOf)) - .getAsLong()); - assertEquals(9, LongStreamEx.range(5, 12).maxBy(String::valueOf).getAsLong()); - assertEquals(10, LongStreamEx.range(5, 12).minBy(String::valueOf).getAsLong()); - assertEquals(5, LongStreamEx.range(5, 12).maxByDouble(x -> 1.0 / x).getAsLong()); - assertEquals(11, LongStreamEx.range(5, 12).minByDouble(x -> 1.0 / x).getAsLong()); - assertEquals(29, LongStreamEx.of(15, 8, 31, 47, 19, 29).maxByInt(x -> (int) (x % 10 * 10 + x / 10)).getAsLong()); - assertEquals(31, LongStreamEx.of(15, 8, 31, 47, 19, 29).minByInt(x -> (int) (x % 10 * 10 + x / 10)).getAsLong()); - assertEquals(29, LongStreamEx.of(15, 8, 31, 47, 19, 29).maxByLong(x -> x % 10 * 10 + x / 10).getAsLong()); - assertEquals(31, LongStreamEx.of(15, 8, 31, 47, 19, 29).minByLong(x -> x % 10 * 10 + x / 10).getAsLong()); - - Supplier s = () -> LongStreamEx.of(1, 50, 120, 35, 130, 12, 0); - LongToIntFunction intKey = x -> String.valueOf(x).length(); - LongUnaryOperator longKey = x -> String.valueOf(x).length(); - LongToDoubleFunction doubleKey = x -> String.valueOf(x).length(); - LongFunction objKey = x -> String.valueOf(x).length(); - List> minFns = Arrays.asList(is -> is.minByInt(intKey), is -> is - .minByLong(longKey), is -> is.minByDouble(doubleKey), is -> is.minBy(objKey)); - List> maxFns = Arrays.asList(is -> is.maxByInt(intKey), is -> is - .maxByLong(longKey), is -> is.maxByDouble(doubleKey), is -> is.maxBy(objKey)); - minFns.forEach(fn -> assertEquals(1, fn.apply(s.get()).getAsLong())); - minFns.forEach(fn -> assertEquals(1, fn.apply(s.get().parallel()).getAsLong())); - maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get()).getAsLong())); - maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get().parallel()).getAsLong())); - } - - @Test - public void testPairMap() { - assertEquals(0, LongStreamEx.range(0).pairMap(Long::sum).count()); - assertEquals(0, LongStreamEx.range(1).pairMap(Long::sum).count()); - assertArrayEquals(new long[] { 6, 7, 8, 9, 10 }, LongStreamEx.of(1, 5, 2, 6, 3, 7).pairMap(Long::sum).toArray()); - assertArrayEquals(LongStreamEx.range(999).map(x -> x * 2 + 1).toArray(), LongStreamEx.range(1000).parallel() - .map(x -> x * x).pairMap((a, b) -> b - a).toArray()); - - assertArrayEquals(LongStreamEx.range(1, 100).toArray(), LongStreamEx.range(100).map(i -> i * (i + 1) / 2) - .append(LongStream.empty()).parallel().pairMap((a, b) -> b - a).toArray()); - assertArrayEquals(LongStreamEx.range(1, 100).toArray(), LongStreamEx.range(100).map(i -> i * (i + 1) / 2) - .prepend(LongStream.empty()).parallel().pairMap((a, b) -> b - a).toArray()); - - assertEquals(1, LongStreamEx.range(1000).map(x -> x * x).pairMap((a, b) -> b - a).pairMap((a, b) -> b - a) - .distinct().count()); - - assertFalse(LongStreamEx.range(1000).greater(2000).parallel().pairMap((a, b) -> a).findFirst().isPresent()); - } - - @Test - public void testJoining() { - assertEquals("0,1,2,3,4,5,6,7,8,9", LongStreamEx.range(10).joining(",")); - assertEquals("0,1,2,3,4,5,6,7,8,9", LongStreamEx.range(10).parallel().joining(",")); - assertEquals("[0,1,2,3,4,5,6,7,8,9]", LongStreamEx.range(10).joining(",", "[", "]")); - assertEquals("[0,1,2,3,4,5,6,7,8,9]", LongStreamEx.range(10).parallel().joining(",", "[", "]")); - } - - @Test - public void testMapToEntry() { - Map> result = LongStreamEx.range(10).mapToEntry(x -> x % 2, x -> x).grouping(); - assertEquals(Arrays.asList(0L, 2L, 4L, 6L, 8L), result.get(0L)); - assertEquals(Arrays.asList(1L, 3L, 5L, 7L, 9L), result.get(1L)); - } - - @Test - public void testTakeWhile() { - assertArrayEquals(LongStreamEx.range(100).toArray(), LongStreamEx.iterate(0, i -> i + 1) - .takeWhile(i -> i < 100).toArray()); - assertEquals(0, LongStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 0).count()); - assertEquals(1, LongStreamEx.of(1, 3, 2).takeWhile(i -> i < 3).count()); - assertEquals(3, LongStreamEx.of(1, 2, 3).takeWhile(i -> i < 100).count()); - } - - @Test - public void testTakeWhileInclusive() { - assertArrayEquals(LongStreamEx.range(101).toArray(), LongStreamEx.iterate(0, i -> i + 1) - .takeWhileInclusive(i -> i < 100).toArray()); - assertEquals(1, LongStreamEx.iterate(0, i -> i + 1).takeWhileInclusive(i -> i < 0).count()); - assertEquals(2, LongStreamEx.of(1, 3, 2).takeWhileInclusive(i -> i < 3).count()); - assertEquals(3, LongStreamEx.of(1, 2, 3).takeWhileInclusive(i -> i < 100).count()); - } - - @Test - public void testDropWhile() { - assertArrayEquals(new long[] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, LongStreamEx.range(100).dropWhile( - i -> i % 10 < 5).limit(10).toArray()); - assertEquals(100, LongStreamEx.range(100).dropWhile(i -> i % 10 < 0).count()); - assertEquals(0, LongStreamEx.range(100).dropWhile(i -> i % 10 < 10).count()); - assertEquals(OptionalLong.of(0), LongStreamEx.range(100).dropWhile(i -> i % 10 < 0).findFirst()); - assertEquals(OptionalLong.empty(), LongStreamEx.range(100).dropWhile(i -> i % 10 < 10).findFirst()); - - java.util.Spliterator.OfLong spltr = LongStreamEx.range(100).dropWhile(i -> i % 10 < 1).spliterator(); - assertTrue(spltr.tryAdvance((long x) -> assertEquals(1, x))); - Builder builder = LongStream.builder(); - spltr.forEachRemaining(builder); - assertArrayEquals(LongStreamEx.range(2, 100).toArray(), builder.build().toArray()); - } - - @Test - public void testIndexOf() { - assertEquals(5, LongStreamEx.range(50, 100).indexOf(55).getAsLong()); - assertFalse(LongStreamEx.range(50, 100).indexOf(200).isPresent()); - assertEquals(5, LongStreamEx.range(50, 100).parallel().indexOf(55).getAsLong()); - assertFalse(LongStreamEx.range(50, 100).parallel().indexOf(200).isPresent()); - - assertEquals(11, LongStreamEx.range(50, 100).indexOf(x -> x > 60).getAsLong()); - assertFalse(LongStreamEx.range(50, 100).indexOf(x -> x < 0).isPresent()); - assertEquals(11, LongStreamEx.range(50, 100).parallel().indexOf(x -> x > 60).getAsLong()); - assertFalse(LongStreamEx.range(50, 100).parallel().indexOf(x -> x < 0).isPresent()); - } - - @Test - public void testFoldLeft() { - // non-associative - LongBinaryOperator accumulator = (x, y) -> (x + y) * (x + y); - assertEquals(2322576, LongStreamEx.constant(3, 4).foldLeft(accumulator).orElse(-1)); - assertEquals(2322576, LongStreamEx.constant(3, 4).parallel().foldLeft(accumulator).orElse(-1)); - assertFalse(LongStreamEx.empty().foldLeft(accumulator).isPresent()); - assertEquals(144, LongStreamEx.rangeClosed(1, 3).foldLeft(0L, accumulator)); - assertEquals(144, LongStreamEx.rangeClosed(1, 3).parallel().foldLeft(0L, accumulator)); - } - - @Test - public void testMapFirstLast() { - assertArrayEquals(new long[] { -1, 2, 3, 4, 7 }, LongStreamEx.of(1, 2, 3, 4, 5).mapFirst(x -> x - 2L).mapLast( - x -> x + 2L).toArray()); - } - - @Test - public void testPeekFirst() { - long[] input = {1, 10, 100, 1000}; - - AtomicLong firstElement = new AtomicLong(); - assertArrayEquals(new long[] {10, 100, 1000}, LongStreamEx.of(input).peekFirst(firstElement::set).skip(1).toArray()); - assertEquals(1, firstElement.get()); - - assertArrayEquals(new long[] {10, 100, 1000}, LongStreamEx.of(input).skip(1).peekFirst(firstElement::set).toArray()); - assertEquals(10, firstElement.get()); - - firstElement.set(-1); - assertArrayEquals(new long[] {}, LongStreamEx.of(input).skip(4).peekFirst(firstElement::set).toArray()); - assertEquals(-1, firstElement.get()); - } - - @Test - public void testPeekLast() { - long[] input = {1, 10, 100, 1000}; - AtomicLong lastElement = new AtomicLong(-1); - assertArrayEquals(new long[] {1, 10, 100}, LongStreamEx.of(input).peekLast(lastElement::set).limit(3).toArray()); - assertEquals(-1, lastElement.get()); - - assertArrayEquals(new long[] { 1, 10, 100 }, LongStreamEx.of(input).less(1000).peekLast(lastElement::set) - .limit(3).toArray()); - assertEquals(100, lastElement.get()); - - assertArrayEquals(input, LongStreamEx.of(input).peekLast(lastElement::set).limit(4).toArray()); - assertEquals(1000, lastElement.get()); - - assertArrayEquals(new long[] {1, 10, 100}, LongStreamEx.of(input).limit(3).peekLast(lastElement::set).toArray()); - assertEquals(100, lastElement.get()); - } - - @Test - public void testScanLeft() { - assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).scanLeft(Long::sum)); - assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).parallel() - .scanLeft(Long::sum)); - assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).filter(x -> true) - .scanLeft(Long::sum)); - assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).filter(x -> true) - .parallel().scanLeft(Long::sum)); - assertArrayEquals(new long[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).scanLeft(1, - (a, b) -> a * b)); - assertArrayEquals(new long[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).parallel().scanLeft(1, - (a, b) -> a * b)); - } - - // Reads numbers from scanner stopping when non-number is encountered - // leaving scanner in known state - public static LongStreamEx scannerLongs(Scanner sc) { - return LongStreamEx.produce(action -> { - if (sc.hasNextLong()) - action.accept(sc.nextLong()); - return sc.hasNextLong(); - }); - } - - @Test - public void testProduce() { - Scanner sc = new Scanner("1 2 3 4 20000000000 test"); - assertArrayEquals(new long[] {1, 2, 3, 4, 20000000000L}, scannerLongs(sc).stream().toArray()); - assertEquals("test", sc.next()); - } - - @Test - public void testPrefix() { - assertArrayEquals(new long[] { 1, 3, 6, 10, 20 }, LongStreamEx.of(1, 2, 3, 4, 10).prefix(Long::sum).toArray()); - assertEquals(OptionalLong.of(10), LongStreamEx.of(1, 2, 3, 4, 10).prefix(Long::sum).findFirst(x -> x > 7)); - assertEquals(OptionalLong.empty(), LongStreamEx.of(1, 2, 3, 4, 10).prefix(Long::sum).findFirst(x -> x > 20)); - longStreamEx(() -> LongStreamEx.range(10000).unordered(), - s -> assertEquals(49995000L, s.prefix(Long::sum).max().getAsLong())); - longStreamEx(() -> LongStreamEx.constant(2, 10), - s -> assertEquals(1024L, s.prefix((a, b) -> a*b).max().getAsLong())); - longStreamEx(() -> LongStreamEx.constant(1, 5), - s -> assertEquals(new HashSet<>(Arrays.asList(1L, 2L, 3L, 4L, 5L)), - s.prefix(Long::sum).boxed().collect(Collectors.toSet()))); - longStreamEx(() -> LongStreamEx.constant(1, 5), - s -> assertEquals(OptionalLong.of(5), s.prefix(Long::sum).findFirst(x -> x > 4))); - longStreamEx(() -> LongStreamEx.constant(1, 5), - s -> assertEquals(OptionalLong.empty(), s.prefix(Long::sum).findFirst(x -> x > 6))); - } - - @Test - public void testIntersperse() { - assertArrayEquals(new long[] { 1, 0, 10, 0, 100, 0, 1000 }, LongStreamEx.of(1, 10, 100, 1000).intersperse(0) - .toArray()); - assertEquals(0L, IntStreamEx.empty().intersperse(1).count()); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.nio.LongBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.OptionalLong; +import java.util.PrimitiveIterator.OfLong; +import java.util.Random; +import java.util.Scanner; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; +import java.util.function.LongBinaryOperator; +import java.util.function.LongConsumer; +import java.util.function.LongFunction; +import java.util.function.LongToDoubleFunction; +import java.util.function.LongToIntFunction; +import java.util.function.LongUnaryOperator; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.LongStream; +import java.util.stream.LongStream.Builder; + +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +import one.util.streamex.IntStreamEx; +import one.util.streamex.LongStreamEx; +import one.util.streamex.StreamEx; + +import static one.util.streamex.TestHelpers.checkSpliterator; +import static one.util.streamex.TestHelpers.longStreamEx; +import static one.util.streamex.TestHelpers.streamEx; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +/** + * @author Tagir Valeev + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class LongStreamExTest { + final LongConsumer EMPTY = l -> { + // nothing + }; + + @Test + public void testCreate() { + assertArrayEquals(new long[] {}, LongStreamEx.empty().toArray()); + // double test is intended + assertArrayEquals(new long[] {}, LongStreamEx.empty().toArray()); + assertArrayEquals(new long[] { 1 }, LongStreamEx.of(1).toArray()); + assertArrayEquals(new long[] { 1 }, LongStreamEx.of(OptionalLong.of(1)).toArray()); + assertArrayEquals(new long[] {}, LongStreamEx.of(OptionalLong.empty()).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 3).toArray()); + assertArrayEquals(new long[] { 4, 6 }, LongStreamEx.of(new long[] { 2, 4, 6, 8, 10 }, 1, 3).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(LongStream.of(1, 2, 3)).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(Arrays.asList(1L, 2L, 3L)).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.range(1L, 4L).toArray()); + assertArrayEquals(new long[] { 0, 1, 2 }, LongStreamEx.range(3L).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.rangeClosed(1, 3).toArray()); + assertArrayEquals(new long[] { 1, 1, 1, 1 }, LongStreamEx.generate(() -> 1).limit(4).toArray()); + assertArrayEquals(new long[] { 1, 1, 1, 1 }, LongStreamEx.constant(1L, 4).toArray()); + assertEquals(10, LongStreamEx.of(new Random(), 10).count()); + assertTrue(LongStreamEx.of(new Random(), 100, 1, 10).allMatch(x -> x >= 1 && x < 10)); + assertArrayEquals(LongStreamEx.of(new Random(1), 100, 1, 10).toArray(), LongStreamEx.of(new Random(1), 1, 10) + .limit(100).toArray()); + assertArrayEquals(LongStreamEx.of(new Random(1), 100).toArray(), LongStreamEx.of(new Random(1)).limit(100) + .toArray()); + + LongStream stream = LongStreamEx.of(1, 2, 3); + assertSame(stream, LongStreamEx.of(stream)); + + assertArrayEquals(new long[] { 4, 2, 0, -2, -4 }, LongStreamEx.zip(new long[] { 5, 4, 3, 2, 1 }, + new long[] { 1, 2, 3, 4, 5 }, (a, b) -> a - b).toArray()); + + assertArrayEquals(new long[] { 1, 5, 3 }, LongStreamEx.of(Spliterators.spliterator(new long[] { 1, 5, 3 }, 0)) + .toArray()); + assertArrayEquals(new long[] { 1, 5, 3 }, LongStreamEx.of( + Spliterators.iterator(Spliterators.spliterator(new long[] { 1, 5, 3 }, 0))).toArray()); + assertArrayEquals(new long[0], LongStreamEx.of(Spliterators.iterator(Spliterators.emptyLongSpliterator())) + .parallel().toArray()); + + assertArrayEquals(new long[] { 2, 4, 6 }, LongStreamEx.of(new Long[] { 2L, 4L, 6L }).toArray()); + } + + @Test + public void testOfLongBuffer() { + long[] data = LongStreamEx.range(100).toArray(); + assertArrayEquals(data, LongStreamEx.of(LongBuffer.wrap(data)).toArray()); + assertArrayEquals(LongStreamEx.range(50, 70).toArray(), LongStreamEx.of(LongBuffer.wrap(data, 50, 20)).toArray()); + assertArrayEquals(data, LongStreamEx.of(LongBuffer.wrap(data)).parallel().toArray()); + assertArrayEquals(LongStreamEx.range(50, 70).toArray(), LongStreamEx.of(LongBuffer.wrap(data, 50, 20)).parallel() + .toArray()); + } + + @Test + public void testIterate() { + assertArrayEquals(new long[] { 1, 2, 4, 8, 16 }, LongStreamEx.iterate(1, x -> x * 2).limit(5).toArray()); + assertArrayEquals(new long[] { 1, 2, 4, 8, 16, 32, 64 }, LongStreamEx.iterate(1, x -> x < 100, x -> x * 2).toArray()); + assertEquals(0, LongStreamEx.iterate(0, x -> x < 0, x -> 1 / x).count()); + assertFalse(LongStreamEx.iterate(1, x -> x < 100, x -> x * 2).has(10)); + checkSpliterator("iterate", () -> LongStreamEx.iterate(1, x -> x < 100, x -> x * 2).spliterator()); + } + + @Test + public void testLongs() { + assertEquals(Long.MAX_VALUE, LongStreamEx.longs().spliterator().getExactSizeIfKnown()); + assertArrayEquals(new long[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, LongStreamEx.longs().limit(10).toArray()); + } + + @Test + public void testRangeStep() { + assertArrayEquals(new long[] { 0 }, LongStreamEx.range(0, 1000, 100000).toArray()); + assertArrayEquals(new long[] { 0, Long.MAX_VALUE - 1 }, LongStreamEx.range(0, Long.MAX_VALUE, + Long.MAX_VALUE - 1).toArray()); + assertArrayEquals(new long[] { Long.MIN_VALUE, -1, Long.MAX_VALUE - 1 }, LongStreamEx.range(Long.MIN_VALUE, + Long.MAX_VALUE, Long.MAX_VALUE).toArray()); + assertArrayEquals(new long[] { Long.MIN_VALUE, -1 }, LongStreamEx.range(Long.MIN_VALUE, Long.MAX_VALUE - 1, + Long.MAX_VALUE).toArray()); + assertArrayEquals(new long[] { Long.MAX_VALUE, -1 }, LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE, + Long.MIN_VALUE).toArray()); + assertArrayEquals(new long[] { Long.MAX_VALUE }, LongStreamEx.range(Long.MAX_VALUE, 0, Long.MIN_VALUE) + .toArray()); + assertArrayEquals(new long[] { 1, Long.MIN_VALUE + 1 }, LongStreamEx.range(1, Long.MIN_VALUE, Long.MIN_VALUE) + .toArray()); + assertArrayEquals(new long[] { 0 }, LongStreamEx.range(0, Long.MIN_VALUE, Long.MIN_VALUE).toArray()); + assertArrayEquals(new long[] { 0, 2, 4, 6, 8 }, LongStreamEx.range(0, 9, 2).toArray()); + assertArrayEquals(new long[] { 0, 2, 4, 6 }, LongStreamEx.range(0, 8, 2).toArray()); + assertArrayEquals(new long[] { 0, -2, -4, -6, -8 }, LongStreamEx.range(0, -9, -2).toArray()); + assertArrayEquals(new long[] { 0, -2, -4, -6 }, LongStreamEx.range(0, -8, -2).toArray()); + assertArrayEquals(new long[] { 5, 4, 3, 2, 1, 0 }, LongStreamEx.range(5, -1, -1).toArray()); + assertEquals(Integer.MAX_VALUE + 1L, LongStreamEx.range(Integer.MIN_VALUE, Integer.MAX_VALUE, 2).spliterator() + .getExactSizeIfKnown()); + assertEquals(Long.MAX_VALUE, LongStreamEx.range(Long.MIN_VALUE, Long.MAX_VALUE - 1, 2).spliterator() + .getExactSizeIfKnown()); + java.util.Spliterator.OfLong spliterator = LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE, -2).spliterator(); + assertEquals(-1, spliterator.getExactSizeIfKnown()); + assertTrue(spliterator.tryAdvance(EMPTY)); + assertEquals(Long.MAX_VALUE, spliterator.estimateSize()); + assertTrue(spliterator.tryAdvance(EMPTY)); + assertEquals(Long.MAX_VALUE - 1, spliterator.estimateSize()); + assertEquals(Long.MAX_VALUE, LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE + 1, -2).spliterator() + .getExactSizeIfKnown()); + assertEquals(-1, LongStreamEx.range(Long.MIN_VALUE, Long.MAX_VALUE, 1).spliterator().getExactSizeIfKnown()); + assertEquals(-1, LongStreamEx.range(Long.MAX_VALUE, Long.MIN_VALUE, -1).spliterator().getExactSizeIfKnown()); + assertEquals(0, LongStreamEx.range(0, -1000, 1).count()); + assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, 1).toArray()); + assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, 2).toArray()); + assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 11, 2).toArray()); + assertArrayEquals(new long[] {}, LongStreamEx.rangeClosed(11, 10, 2).toArray()); + assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, -1).toArray()); + assertArrayEquals(new long[] {10}, LongStreamEx.rangeClosed(10, 10, -2).toArray()); + assertArrayEquals(new long[] {}, LongStreamEx.rangeClosed(10, 11, -2).toArray()); + assertArrayEquals(new long[] {11}, LongStreamEx.rangeClosed(11, 10, -2).toArray()); + assertEquals(0, LongStreamEx.range(0, 1000, -1).count()); + assertEquals(0, LongStreamEx.range(0, 0, -1).count()); + assertEquals(0, LongStreamEx.range(0, 0, 1).count()); + assertEquals(0, LongStreamEx.range(0, -1000, 2).count()); + assertEquals(0, LongStreamEx.range(0, 1000, -2).count()); + assertEquals(0, LongStreamEx.range(0, 0, -2).count()); + assertEquals(0, LongStreamEx.range(0, 0, 2).count()); + + assertEquals(0, LongStreamEx.range(0, Long.MIN_VALUE, 2).spliterator().getExactSizeIfKnown()); + assertEquals(0, LongStreamEx.range(0, Long.MAX_VALUE, -2).spliterator().getExactSizeIfKnown()); + + assertThrows(IllegalArgumentException.class, () -> LongStreamEx.range(0, 1000, 0)); + } + + @Test + public void testRangeClosedStep() { + assertArrayEquals(new long[] { 0 }, LongStreamEx.rangeClosed(0, 1000, 100000).toArray()); + assertArrayEquals(new long[] { 0, 1000 }, LongStreamEx.rangeClosed(0, 1000, 1000).toArray()); + assertArrayEquals(new long[] { 0, Long.MAX_VALUE - 1 }, LongStreamEx.rangeClosed(0, Long.MAX_VALUE - 1, + Long.MAX_VALUE - 1).toArray()); + assertArrayEquals(new long[] { Long.MIN_VALUE, -1, Long.MAX_VALUE - 1 }, LongStreamEx.rangeClosed( + Long.MIN_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE).toArray()); + assertArrayEquals(new long[] { Long.MIN_VALUE, -1 }, LongStreamEx.rangeClosed(Long.MIN_VALUE, + Long.MAX_VALUE - 2, Long.MAX_VALUE).toArray()); + assertArrayEquals(new long[] { Long.MAX_VALUE, -1 }, LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE, + Long.MIN_VALUE).toArray()); + assertArrayEquals(new long[] { Long.MAX_VALUE }, LongStreamEx.rangeClosed(Long.MAX_VALUE, 0, Long.MIN_VALUE) + .toArray()); + assertArrayEquals(new long[] { 0, Long.MIN_VALUE }, LongStreamEx.rangeClosed(0, Long.MIN_VALUE, Long.MIN_VALUE) + .toArray()); + assertArrayEquals(new long[] { 0, 2, 4, 6, 8 }, LongStreamEx.rangeClosed(0, 9, 2).toArray()); + assertArrayEquals(new long[] { 0, 2, 4, 6, 8 }, LongStreamEx.rangeClosed(0, 8, 2).toArray()); + assertArrayEquals(new long[] { 0, 2, 4, 6 }, LongStreamEx.rangeClosed(0, 7, 2).toArray()); + assertArrayEquals(new long[] { 0, -2, -4, -6, -8 }, LongStreamEx.rangeClosed(0, -9, -2).toArray()); + assertArrayEquals(new long[] { 0, -2, -4, -6, -8 }, LongStreamEx.rangeClosed(0, -8, -2).toArray()); + assertArrayEquals(new long[] { 0, -2, -4, -6 }, LongStreamEx.rangeClosed(0, -7, -2).toArray()); + assertArrayEquals(new long[] { 5, 4, 3, 2, 1, 0 }, LongStreamEx.rangeClosed(5, 0, -1).toArray()); + assertEquals(Integer.MAX_VALUE + 1L, LongStreamEx.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE, 2) + .spliterator().getExactSizeIfKnown()); + assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(Long.MIN_VALUE, Long.MAX_VALUE - 2, 2).spliterator() + .getExactSizeIfKnown()); + java.util.Spliterator.OfLong spliterator = LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE, -2) + .spliterator(); + assertEquals(-1, spliterator.getExactSizeIfKnown()); + assertTrue(spliterator.tryAdvance(EMPTY)); + assertEquals(Long.MAX_VALUE, spliterator.estimateSize()); + assertTrue(spliterator.tryAdvance(EMPTY)); + assertEquals(Long.MAX_VALUE - 1, spliterator.estimateSize()); + assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE + 2, -2).spliterator() + .getExactSizeIfKnown()); + assertEquals(-1, LongStreamEx.rangeClosed(Long.MIN_VALUE, Long.MAX_VALUE, 1).spliterator() + .getExactSizeIfKnown()); + assertEquals(-1, LongStreamEx.rangeClosed(Long.MAX_VALUE, Long.MIN_VALUE, -1).spliterator() + .getExactSizeIfKnown()); + assertEquals(0, LongStreamEx.rangeClosed(0, -1000, 1).count()); + assertEquals(0, LongStreamEx.rangeClosed(0, 1000, -1).count()); + assertEquals(0, LongStreamEx.rangeClosed(0, 1, -1).count()); + assertEquals(0, LongStreamEx.rangeClosed(0, -1, 1).count()); + assertEquals(0, LongStreamEx.rangeClosed(0, -1000, 2).count()); + assertEquals(0, LongStreamEx.rangeClosed(0, 1000, -2).count()); + assertEquals(0, LongStreamEx.rangeClosed(0, 1, -2).count()); + assertEquals(0, LongStreamEx.rangeClosed(0, -1, 2).count()); + + assertEquals(0, LongStreamEx.rangeClosed(0, Long.MIN_VALUE, 2).spliterator().getExactSizeIfKnown()); + assertEquals(0, LongStreamEx.rangeClosed(0, Long.MAX_VALUE, -2).spliterator().getExactSizeIfKnown()); + } + + @Test + public void testBasics() { + assertFalse(LongStreamEx.of(1).isParallel()); + assertTrue(LongStreamEx.of(1).parallel().isParallel()); + assertFalse(LongStreamEx.of(1).parallel().sequential().isParallel()); + AtomicInteger i = new AtomicInteger(); + try (LongStreamEx s = LongStreamEx.of(1).onClose(i::incrementAndGet)) { + assertEquals(1, s.count()); + } + assertEquals(1, i.get()); + assertEquals(6, LongStreamEx.range(0, 4).sum()); + assertEquals(3, LongStreamEx.range(0, 4).max().getAsLong()); + assertEquals(0, LongStreamEx.range(0, 4).min().getAsLong()); + assertEquals(1.5, LongStreamEx.range(0, 4).average().getAsDouble(), 0.000001); + assertEquals(4, LongStreamEx.range(0, 4).summaryStatistics().getCount()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.range(0, 5).skip(1).limit(3).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(3, 1, 2).sorted().toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 1, 3, 2).distinct().toArray()); + assertArrayEquals(new int[] { 2, 4, 6 }, LongStreamEx.range(1, 4).mapToInt(x -> (int) x * 2).toArray()); + assertArrayEquals(new long[] { 2, 4, 6 }, LongStreamEx.range(1, 4).map(x -> x * 2).toArray()); + assertArrayEquals(new double[] { 2, 4, 6 }, LongStreamEx.range(1, 4).mapToDouble(x -> x * 2).toArray(), 0.0); + assertArrayEquals(new long[] { 1, 3 }, LongStreamEx.range(0, 5).filter(x -> x % 2 == 1).toArray()); + assertEquals(6, LongStreamEx.of(1, 2, 3).reduce(Long::sum).getAsLong()); + assertEquals(Long.MAX_VALUE, LongStreamEx.rangeClosed(1, Long.MAX_VALUE).spliterator().getExactSizeIfKnown()); + + assertTrue(LongStreamEx.of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)); + assertFalse(LongStreamEx.of(1, 2, 3).unordered().spliterator().hasCharacteristics(Spliterator.ORDERED)); + + OfLong iterator = LongStreamEx.of(1, 2, 3).iterator(); + assertEquals(1L, iterator.nextLong()); + assertEquals(2L, iterator.nextLong()); + assertEquals(3L, iterator.nextLong()); + assertFalse(iterator.hasNext()); + + AtomicInteger idx = new AtomicInteger(); + long[] result = new long[500]; + LongStreamEx.range(1000).atLeast(500).parallel().forEachOrdered(val -> result[idx.getAndIncrement()] = val); + assertArrayEquals(LongStreamEx.range(500, 1000).toArray(), result); + + assertTrue(LongStreamEx.empty().noneMatch(x -> true)); + assertFalse(LongStreamEx.of(1).noneMatch(x -> true)); + assertTrue(LongStreamEx.of(1).noneMatch(x -> false)); + } + + @Test + public void testForEach() { + List list = new ArrayList<>(); + LongStreamEx.of(1).forEach(list::add); + assertEquals(Arrays.asList(1L), list); + streamEx(() -> StreamEx.of(1L, 2L, 3L), s -> { + AtomicLong count = new AtomicLong(0); + s.get().mapToLong(Long::longValue).forEach(count::addAndGet); + assertEquals(6, count.get()); + s.get().mapToLong(Long::longValue).pairMap((a, b) -> b - a).forEach(count::addAndGet); + assertEquals(8, count.get()); + }); + } + + @Test + public void testFlatMap() { + assertArrayEquals(new long[] { 0, 0, 1, 0, 1, 2 }, LongStreamEx.of(1, 2, 3).flatMap(LongStreamEx::range) + .toArray()); + assertArrayEquals(new int[] { 1, 5, 1, 4, 2, 0, 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5, 4, 7, 7, 5, 8, 0, 7 }, + LongStreamEx.of(15, 14, 20, Long.MAX_VALUE).flatMapToInt(n -> String.valueOf(n).chars().map(x -> x - '0')) + .toArray()); + + String expected = LongStreamEx.range(200).boxed().flatMap( + i -> LongStreamEx.range(0, i).mapToObj(j -> i + ":" + j)).joining("/"); + String res = LongStreamEx.range(200).flatMapToObj(i -> LongStreamEx.range(i).mapToObj(j -> i + ":" + j)) + .joining("/"); + String parallel = LongStreamEx.range(200).parallel().flatMapToObj( + i -> LongStreamEx.range(i).mapToObj(j -> i + ":" + j)).joining("/"); + assertEquals(expected, res); + assertEquals(expected, parallel); + + double[] fractions = LongStreamEx.range(1, 5).flatMapToDouble( + i -> LongStreamEx.range(1, i).mapToDouble(j -> ((double) j) / i)).toArray(); + assertArrayEquals(new double[] { 1 / 2.0, 1 / 3.0, 2 / 3.0, 1 / 4.0, 2 / 4.0, 3 / 4.0 }, fractions, 0.000001); + } + + @Test + public void testPrepend() { + assertArrayEquals(new long[] { -1, 0, 1, 2, 3 }, LongStreamEx.of(1, 2, 3).prepend(-1, 0).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 3).prepend().toArray()); + assertArrayEquals(new long[] { 10, 11, 0, 1, 2, 3 }, LongStreamEx.range(0, 4).prepend( + LongStreamEx.range(10, 12)).toArray()); + } + + @Test + public void testAppend() { + assertArrayEquals(new long[] { 1, 2, 3, 4, 5 }, LongStreamEx.of(1, 2, 3).append(4, 5).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.of(1, 2, 3).append().toArray()); + assertArrayEquals(new long[] { 0, 1, 2, 3, 10, 11 }, LongStreamEx.range(0, 4) + .append(LongStreamEx.range(10, 12)).toArray()); + } + + @Test + public void testHas() { + assertTrue(LongStreamEx.range(1, 4).has(3)); + assertFalse(LongStreamEx.range(1, 4).has(4)); + } + + @Test + public void testWithout() { + assertArrayEquals(new long[] { 1, 2 }, LongStreamEx.range(1, 4).without(3).toArray()); + assertArrayEquals(new long[] { 1, 2, 3 }, LongStreamEx.range(1, 4).without(5).toArray()); + LongStreamEx lse = LongStreamEx.range(5); + assertSame(lse, lse.without()); + assertArrayEquals(new long[] { 0, 1, 3, 4 }, LongStreamEx.range(5).without(new long[] { 2 }).toArray()); + assertArrayEquals(new long[] { 0 }, LongStreamEx.range(5).without(1, 2, 3, 4, 5, 6).toArray()); + } + + @Test + public void testRanges() { + assertArrayEquals(new long[] { 5, 4, Long.MAX_VALUE }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).greater( + 3).toArray()); + assertArrayEquals(new long[] {}, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).greater(Long.MAX_VALUE) + .toArray()); + assertArrayEquals(new long[] { 5, 3, 4, Long.MAX_VALUE }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE) + .atLeast(3).toArray()); + assertArrayEquals(new long[] { Long.MAX_VALUE }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).atLeast( + Long.MAX_VALUE).toArray()); + assertArrayEquals(new long[] { 1, -1 }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).less(3).toArray()); + assertArrayEquals(new long[] { 1, 3, -1 }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).atMost(3).toArray()); + assertArrayEquals(new long[] { 1, 3, 4, -1 }, LongStreamEx.of(1, 5, 3, 4, -1, Long.MAX_VALUE).atMost(4).toArray()); + } + + @Test + public void testFind() { + assertEquals(6, LongStreamEx.range(1, 10).findFirst(i -> i > 5).getAsLong()); + assertFalse(LongStreamEx.range(1, 10).findAny(i -> i > 10).isPresent()); + } + + @Test + public void testRemove() { + assertArrayEquals(new long[] { 1, 2 }, LongStreamEx.of(1, 2, 3).remove(x -> x > 2).toArray()); + } + + @Test + public void testSort() { + assertArrayEquals(new long[] { 0, 3, 6, 1, 4, 7, 2, 5, 8 }, LongStreamEx.range(0, 9).sortedByLong( + i -> i % 3 * 3 + i / 3).toArray()); + assertArrayEquals(new long[] { 0, 4, 8, 1, 5, 9, 2, 6, 3, 7 }, LongStreamEx.range(0, 10).sortedByInt( + i -> (int) i % 4).toArray()); + assertArrayEquals(new long[] { 10, 11, 5, 6, 7, 8, 9 }, LongStreamEx.range(5, 12).sortedBy(String::valueOf) + .toArray()); + assertArrayEquals(new long[] { Long.MAX_VALUE, 1000, 1, 0, -10, Long.MIN_VALUE }, LongStreamEx.of(0, 1, 1000, + -10, Long.MIN_VALUE, Long.MAX_VALUE).reverseSorted().toArray()); + assertArrayEquals(new long[] { Long.MAX_VALUE, Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MAX_VALUE - 1 }, + LongStreamEx.of(Long.MIN_VALUE, Long.MIN_VALUE + 1, Long.MAX_VALUE - 1, Long.MAX_VALUE).sortedByLong( + l -> l + 1).toArray()); + assertArrayEquals(new long[] { -10, Long.MIN_VALUE, Long.MAX_VALUE, 1000, 1, 0 }, LongStreamEx.of(0, 1, 1000, + -10, Long.MIN_VALUE, Long.MAX_VALUE).sortedByDouble(x -> 1.0 / x).toArray()); + } + + @SafeVarargs + private static void checkEmpty(Function... fns) { + int i = 0; + for (Function fn : fns) { + assertFalse("#" + i, fn.apply(LongStreamEx.empty()).isPresent()); + assertFalse("#" + i, fn.apply(LongStreamEx.of(1, 2, 3, 4).greater(5).parallel()).isPresent()); + assertEquals("#" + i, 10, fn.apply(LongStreamEx.of(1, 1, 1, 1, 10, 10, 10, 10).greater(5).parallel()) + .getAsLong()); + i++; + } + } + + @Test + public void testMinMax() { + checkEmpty(s -> s.maxBy(Long::valueOf), s -> s.maxByInt(x -> (int) x), s -> s.maxByLong(x -> x), s -> s + .maxByDouble(x -> x), s -> s.minBy(Long::valueOf), s -> s.minByInt(x -> (int) x), s -> s + .minByLong(x -> x), s -> s.minByDouble(x -> x)); + assertEquals(9, LongStreamEx.range(5, 12).max(Comparator.comparing(String::valueOf)) + .getAsLong()); + assertEquals(10, LongStreamEx.range(5, 12).min(Comparator.comparing(String::valueOf)) + .getAsLong()); + assertEquals(9, LongStreamEx.range(5, 12).maxBy(String::valueOf).getAsLong()); + assertEquals(10, LongStreamEx.range(5, 12).minBy(String::valueOf).getAsLong()); + assertEquals(5, LongStreamEx.range(5, 12).maxByDouble(x -> 1.0 / x).getAsLong()); + assertEquals(11, LongStreamEx.range(5, 12).minByDouble(x -> 1.0 / x).getAsLong()); + assertEquals(29, LongStreamEx.of(15, 8, 31, 47, 19, 29).maxByInt(x -> (int) (x % 10 * 10 + x / 10)).getAsLong()); + assertEquals(31, LongStreamEx.of(15, 8, 31, 47, 19, 29).minByInt(x -> (int) (x % 10 * 10 + x / 10)).getAsLong()); + assertEquals(29, LongStreamEx.of(15, 8, 31, 47, 19, 29).maxByLong(x -> x % 10 * 10 + x / 10).getAsLong()); + assertEquals(31, LongStreamEx.of(15, 8, 31, 47, 19, 29).minByLong(x -> x % 10 * 10 + x / 10).getAsLong()); + + Supplier s = () -> LongStreamEx.of(1, 50, 120, 35, 130, 12, 0); + LongToIntFunction intKey = x -> String.valueOf(x).length(); + LongUnaryOperator longKey = x -> String.valueOf(x).length(); + LongToDoubleFunction doubleKey = x -> String.valueOf(x).length(); + LongFunction objKey = x -> String.valueOf(x).length(); + List> minFns = Arrays.asList(is -> is.minByInt(intKey), is -> is + .minByLong(longKey), is -> is.minByDouble(doubleKey), is -> is.minBy(objKey)); + List> maxFns = Arrays.asList(is -> is.maxByInt(intKey), is -> is + .maxByLong(longKey), is -> is.maxByDouble(doubleKey), is -> is.maxBy(objKey)); + minFns.forEach(fn -> assertEquals(1, fn.apply(s.get()).getAsLong())); + minFns.forEach(fn -> assertEquals(1, fn.apply(s.get().parallel()).getAsLong())); + maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get()).getAsLong())); + maxFns.forEach(fn -> assertEquals(120, fn.apply(s.get().parallel()).getAsLong())); + } + + @Test + public void testPairMap() { + assertEquals(0, LongStreamEx.range(0).pairMap(Long::sum).count()); + assertEquals(0, LongStreamEx.range(1).pairMap(Long::sum).count()); + assertArrayEquals(new long[] { 6, 7, 8, 9, 10 }, LongStreamEx.of(1, 5, 2, 6, 3, 7).pairMap(Long::sum).toArray()); + assertArrayEquals(LongStreamEx.range(999).map(x -> x * 2 + 1).toArray(), LongStreamEx.range(1000).parallel() + .map(x -> x * x).pairMap((a, b) -> b - a).toArray()); + + assertArrayEquals(LongStreamEx.range(1, 100).toArray(), LongStreamEx.range(100).map(i -> i * (i + 1) / 2) + .append(LongStream.empty()).parallel().pairMap((a, b) -> b - a).toArray()); + assertArrayEquals(LongStreamEx.range(1, 100).toArray(), LongStreamEx.range(100).map(i -> i * (i + 1) / 2) + .prepend(LongStream.empty()).parallel().pairMap((a, b) -> b - a).toArray()); + + assertEquals(1, LongStreamEx.range(1000).map(x -> x * x).pairMap((a, b) -> b - a).pairMap((a, b) -> b - a) + .distinct().count()); + + assertFalse(LongStreamEx.range(1000).greater(2000).parallel().pairMap((a, b) -> a).findFirst().isPresent()); + } + + @Test + public void testJoining() { + assertEquals("0,1,2,3,4,5,6,7,8,9", LongStreamEx.range(10).joining(",")); + assertEquals("0,1,2,3,4,5,6,7,8,9", LongStreamEx.range(10).parallel().joining(",")); + assertEquals("[0,1,2,3,4,5,6,7,8,9]", LongStreamEx.range(10).joining(",", "[", "]")); + assertEquals("[0,1,2,3,4,5,6,7,8,9]", LongStreamEx.range(10).parallel().joining(",", "[", "]")); + } + + @Test + public void testMapToEntry() { + Map> result = LongStreamEx.range(10).mapToEntry(x -> x % 2, x -> x).grouping(); + assertEquals(Arrays.asList(0L, 2L, 4L, 6L, 8L), result.get(0L)); + assertEquals(Arrays.asList(1L, 3L, 5L, 7L, 9L), result.get(1L)); + } + + @Test + public void testTakeWhile() { + assertArrayEquals(LongStreamEx.range(100).toArray(), LongStreamEx.iterate(0, i -> i + 1) + .takeWhile(i -> i < 100).toArray()); + assertEquals(0, LongStreamEx.iterate(0, i -> i + 1).takeWhile(i -> i < 0).count()); + assertEquals(1, LongStreamEx.of(1, 3, 2).takeWhile(i -> i < 3).count()); + assertEquals(3, LongStreamEx.of(1, 2, 3).takeWhile(i -> i < 100).count()); + } + + @Test + public void testTakeWhileInclusive() { + assertArrayEquals(LongStreamEx.range(101).toArray(), LongStreamEx.iterate(0, i -> i + 1) + .takeWhileInclusive(i -> i < 100).toArray()); + assertEquals(1, LongStreamEx.iterate(0, i -> i + 1).takeWhileInclusive(i -> i < 0).count()); + assertEquals(2, LongStreamEx.of(1, 3, 2).takeWhileInclusive(i -> i < 3).count()); + assertEquals(3, LongStreamEx.of(1, 2, 3).takeWhileInclusive(i -> i < 100).count()); + } + + @Test + public void testDropWhile() { + assertArrayEquals(new long[] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, LongStreamEx.range(100).dropWhile( + i -> i % 10 < 5).limit(10).toArray()); + assertEquals(100, LongStreamEx.range(100).dropWhile(i -> i % 10 < 0).count()); + assertEquals(0, LongStreamEx.range(100).dropWhile(i -> i % 10 < 10).count()); + assertEquals(OptionalLong.of(0), LongStreamEx.range(100).dropWhile(i -> i % 10 < 0).findFirst()); + assertEquals(OptionalLong.empty(), LongStreamEx.range(100).dropWhile(i -> i % 10 < 10).findFirst()); + + java.util.Spliterator.OfLong spltr = LongStreamEx.range(100).dropWhile(i -> i % 10 < 1).spliterator(); + assertTrue(spltr.tryAdvance((long x) -> assertEquals(1, x))); + Builder builder = LongStream.builder(); + spltr.forEachRemaining(builder); + assertArrayEquals(LongStreamEx.range(2, 100).toArray(), builder.build().toArray()); + } + + @Test + public void testIndexOf() { + assertEquals(5, LongStreamEx.range(50, 100).indexOf(55).getAsLong()); + assertFalse(LongStreamEx.range(50, 100).indexOf(200).isPresent()); + assertEquals(5, LongStreamEx.range(50, 100).parallel().indexOf(55).getAsLong()); + assertFalse(LongStreamEx.range(50, 100).parallel().indexOf(200).isPresent()); + + assertEquals(11, LongStreamEx.range(50, 100).indexOf(x -> x > 60).getAsLong()); + assertFalse(LongStreamEx.range(50, 100).indexOf(x -> x < 0).isPresent()); + assertEquals(11, LongStreamEx.range(50, 100).parallel().indexOf(x -> x > 60).getAsLong()); + assertFalse(LongStreamEx.range(50, 100).parallel().indexOf(x -> x < 0).isPresent()); + } + + @Test + public void testFoldLeft() { + // non-associative + LongBinaryOperator accumulator = (x, y) -> (x + y) * (x + y); + assertEquals(2322576, LongStreamEx.constant(3, 4).foldLeft(accumulator).orElse(-1)); + assertEquals(2322576, LongStreamEx.constant(3, 4).parallel().foldLeft(accumulator).orElse(-1)); + assertFalse(LongStreamEx.empty().foldLeft(accumulator).isPresent()); + assertEquals(144, LongStreamEx.rangeClosed(1, 3).foldLeft(0L, accumulator)); + assertEquals(144, LongStreamEx.rangeClosed(1, 3).parallel().foldLeft(0L, accumulator)); + } + + @Test + public void testMapFirstLast() { + assertArrayEquals(new long[] { -1, 2, 3, 4, 7 }, LongStreamEx.of(1, 2, 3, 4, 5).mapFirst(x -> x - 2L).mapLast( + x -> x + 2L).toArray()); + } + + @Test + public void testPeekFirst() { + long[] input = {1, 10, 100, 1000}; + + AtomicLong firstElement = new AtomicLong(); + assertArrayEquals(new long[] {10, 100, 1000}, LongStreamEx.of(input).peekFirst(firstElement::set).skip(1).toArray()); + assertEquals(1, firstElement.get()); + + assertArrayEquals(new long[] {10, 100, 1000}, LongStreamEx.of(input).skip(1).peekFirst(firstElement::set).toArray()); + assertEquals(10, firstElement.get()); + + firstElement.set(-1); + assertArrayEquals(new long[] {}, LongStreamEx.of(input).skip(4).peekFirst(firstElement::set).toArray()); + assertEquals(-1, firstElement.get()); + } + + @Test + public void testPeekLast() { + long[] input = {1, 10, 100, 1000}; + AtomicLong lastElement = new AtomicLong(-1); + assertArrayEquals(new long[] {1, 10, 100}, LongStreamEx.of(input).peekLast(lastElement::set).limit(3).toArray()); + assertEquals(-1, lastElement.get()); + + assertArrayEquals(new long[] { 1, 10, 100 }, LongStreamEx.of(input).less(1000).peekLast(lastElement::set) + .limit(3).toArray()); + assertEquals(100, lastElement.get()); + + assertArrayEquals(input, LongStreamEx.of(input).peekLast(lastElement::set).limit(4).toArray()); + assertEquals(1000, lastElement.get()); + + assertArrayEquals(new long[] {1, 10, 100}, LongStreamEx.of(input).limit(3).peekLast(lastElement::set).toArray()); + assertEquals(100, lastElement.get()); + } + + @Test + public void testScanLeft() { + assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).scanLeft(Long::sum)); + assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).parallel() + .scanLeft(Long::sum)); + assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).filter(x -> true) + .scanLeft(Long::sum)); + assertArrayEquals(new long[] { 0, 1, 3, 6, 10, 15, 21, 28, 36, 45 }, LongStreamEx.range(10).filter(x -> true) + .parallel().scanLeft(Long::sum)); + assertArrayEquals(new long[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).scanLeft(1, + (a, b) -> a * b)); + assertArrayEquals(new long[] { 1, 1, 2, 6, 24, 120 }, LongStreamEx.rangeClosed(1, 5).parallel().scanLeft(1, + (a, b) -> a * b)); + } + + // Reads numbers from scanner stopping when non-number is encountered + // leaving scanner in known state + public static LongStreamEx scannerLongs(Scanner sc) { + return LongStreamEx.produce(action -> { + if (sc.hasNextLong()) + action.accept(sc.nextLong()); + return sc.hasNextLong(); + }); + } + + @Test + public void testProduce() { + Scanner sc = new Scanner("1 2 3 4 20000000000 test"); + assertArrayEquals(new long[] {1, 2, 3, 4, 20000000000L}, scannerLongs(sc).toArray()); + assertEquals("test", sc.next()); + } + + @Test + public void testPrefix() { + assertArrayEquals(new long[] { 1, 3, 6, 10, 20 }, LongStreamEx.of(1, 2, 3, 4, 10).prefix(Long::sum).toArray()); + assertEquals(OptionalLong.of(10), LongStreamEx.of(1, 2, 3, 4, 10).prefix(Long::sum).findFirst(x -> x > 7)); + assertEquals(OptionalLong.empty(), LongStreamEx.of(1, 2, 3, 4, 10).prefix(Long::sum).findFirst(x -> x > 20)); + longStreamEx(() -> LongStreamEx.range(10000).unordered(), + s -> assertEquals(49995000L, s.prefix(Long::sum).max().getAsLong())); + longStreamEx(() -> LongStreamEx.constant(2, 10), + s -> assertEquals(1024L, s.prefix((a, b) -> a*b).max().getAsLong())); + longStreamEx(() -> LongStreamEx.constant(1, 5), + s -> assertEquals(new HashSet<>(Arrays.asList(1L, 2L, 3L, 4L, 5L)), + s.prefix(Long::sum).boxed().collect(Collectors.toSet()))); + longStreamEx(() -> LongStreamEx.constant(1, 5), + s -> assertEquals(OptionalLong.of(5), s.prefix(Long::sum).findFirst(x -> x > 4))); + longStreamEx(() -> LongStreamEx.constant(1, 5), + s -> assertEquals(OptionalLong.empty(), s.prefix(Long::sum).findFirst(x -> x > 6))); + } + + @Test + public void testIntersperse() { + assertArrayEquals(new long[] { 1, 0, 10, 0, 100, 0, 1000 }, + LongStreamEx.of(1, 10, 100, 1000).intersperse(0).toArray()); + assertEquals(0L, IntStreamEx.empty().intersperse(1).count()); + } +} diff --git a/src/test/java/one/util/streamex/MoreCollectorsTest.java b/src/test/java/one/util/streamex/api/MoreCollectorsTest.java similarity index 94% rename from src/test/java/one/util/streamex/MoreCollectorsTest.java rename to src/test/java/one/util/streamex/api/MoreCollectorsTest.java index 0b75dd2d..3e370299 100644 --- a/src/test/java/one/util/streamex/MoreCollectorsTest.java +++ b/src/test/java/one/util/streamex/api/MoreCollectorsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015, 2019 StreamEx contributors + * Copyright 2015, 2020 StreamEx contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package one.util.streamex; +package one.util.streamex.api; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -53,10 +53,15 @@ import org.junit.Test; import org.junit.runners.MethodSorters; -import one.util.streamex.Internals.BooleanMap; +import one.util.streamex.EntryStream; +import one.util.streamex.IntStreamEx; +import one.util.streamex.Joining; +import one.util.streamex.LongStreamEx; +import one.util.streamex.MoreCollectors; +import one.util.streamex.StreamEx; import static java.util.Arrays.asList; -import static one.util.streamex.TestHelpers.assertThrows; +import static one.util.streamex.TestHelpers.assertStatementThrows; import static one.util.streamex.TestHelpers.checkCollector; import static one.util.streamex.TestHelpers.checkCollectorEmpty; import static one.util.streamex.TestHelpers.checkIllegalStateException; @@ -67,6 +72,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -453,45 +459,70 @@ public void testToBooleanArray() { public void testPartitioningBy() { assertThrows(NullPointerException.class, () -> MoreCollectors.partitioningBy(null, Collectors.toList())); assertThrows(NullPointerException.class, () -> MoreCollectors.partitioningBy(x -> x.hashCode() > 0, null)); - Collector>> by20 = MoreCollectors.partitioningBy(x -> x % 20 == 0, - MoreCollectors.first()); - Collector>> by200 = MoreCollectors.partitioningBy(x -> x % 200 == 0, - MoreCollectors.first()); + + Collector>> by20 = MoreCollectors.partitioningBy(x -> x % 20 == 0, MoreCollectors.first()); + Collector>> by200 = MoreCollectors.partitioningBy(x -> x % 200 == 0, MoreCollectors.first()); Supplier> supplier = () -> IntStreamEx.range(1, 100).boxed(); - checkShortCircuitCollector("by20", new BooleanMap<>(Optional.of(20), Optional.of(1)), 20, supplier, by20); - checkShortCircuitCollector("by200", new BooleanMap<>(Optional.empty(), Optional.of(1)), 99, supplier, by200); + { + Map> expected = new HashMap<>(); + expected.put(Boolean.TRUE, Optional.of(20)); + expected.put(Boolean.FALSE, Optional.of(1)); + checkShortCircuitCollector("by20", expected, 20, supplier, by20); + } + { + Map> expected = new HashMap<>(); + expected.put(Boolean.TRUE, Optional.empty()); + expected.put(Boolean.FALSE, Optional.of(1)); + checkShortCircuitCollector("by200", expected, 99, supplier, by200); + } } @Test public void testMapping() { assertThrows(NullPointerException.class, () -> MoreCollectors.mapping(null, Collectors.toList())); assertThrows(NullPointerException.class, () -> MoreCollectors.mapping(Function.identity(), null)); - List input = asList("Capital", "lower", "Foo", "bar"); - Collector>> collector = MoreCollectors - .partitioningBy(str -> Character.isUpperCase(str.charAt(0)), MoreCollectors.mapping(String::length, - MoreCollectors.first())); - checkShortCircuitCollector("mapping", new BooleanMap<>(Optional.of(7), Optional.of(5)), 2, input::stream, - collector); - Collector>> collectorLast = MoreCollectors.partitioningBy( - str -> Character.isUpperCase(str.charAt(0)), MoreCollectors.mapping(String::length, MoreCollectors.last())); - checkCollector("last", new BooleanMap<>(Optional.of(3), Optional.of(3)), input::stream, collectorLast); - - input = asList("Abc", "Bac", "Aac", "Abv", "Bbc", "Bgd", "Atc", "Bpv"); - Map> expected = EntryStream.of('A', asList("Abc", "Aac"), 'B', asList("Bac", "Bbc")) - .toMap(); - AtomicInteger cnt = new AtomicInteger(); - Collector>> groupMap = Collectors.groupingBy(s -> s.charAt(0), - MoreCollectors.mapping(x -> { - cnt.incrementAndGet(); - return x; - }, MoreCollectors.head(2))); - checkCollector("groupMap", expected, input::stream, groupMap); - cnt.set(0); - assertEquals(expected, input.stream().collect(groupMap)); - assertEquals(4, cnt.get()); - - checkCollector("mapping-toList", asList("a", "b", "c"), asList("a1", "b2", "c3")::stream, MoreCollectors - .mapping(str -> str.substring(0, 1))); + + { + List input = asList("Abc", "Bac", "Aac", "Abv", "Bbc", "Bgd", "Atc", "Bpv"); + Map> expected = EntryStream.of('A', asList("Abc", "Aac"), 'B', asList("Bac", "Bbc")) + .toMap(); + AtomicInteger cnt = new AtomicInteger(); + Collector>> groupMap = + Collectors.groupingBy(s -> s.charAt(0), + MoreCollectors.mapping(x -> { + cnt.incrementAndGet(); + return x; + }, MoreCollectors.head(2))); + checkCollector("groupMap", expected, input::stream, groupMap); + cnt.set(0); + assertEquals(expected, input.stream().collect(groupMap)); + assertEquals(4, cnt.get()); + } + + checkCollector("mapping-toList", asList("a", "b", "c"), asList("a1", "b2", "c3")::stream, + MoreCollectors.mapping(str -> str.substring(0, 1))); + + { + List input = asList("Capital", "lower", "Foo", "bar"); + Map> expected = new HashMap<>(); + expected.put(Boolean.TRUE, Optional.of(7)); + expected.put(Boolean.FALSE, Optional.of(5)); + + Collector>> collectorFirst = MoreCollectors.partitioningBy( + str -> Character.isUpperCase(str.charAt(0)), + MoreCollectors.mapping(String::length, MoreCollectors.first())); + checkShortCircuitCollector("mapping", expected, 2, input::stream, collectorFirst); + } + { + List input = asList("Capital", "lower", "Foo", "bar"); + Map> expected = new HashMap<>(); + expected.put(Boolean.TRUE, Optional.of(3)); + expected.put(Boolean.FALSE, Optional.of(3)); + Collector>> collectorLast = MoreCollectors.partitioningBy( + str -> Character.isUpperCase(str.charAt(0)), + MoreCollectors.mapping(String::length, MoreCollectors.last())); + checkCollector("last", expected, input::stream, collectorLast); + } } @Test @@ -662,7 +693,7 @@ public void testEntriesToCustomMap() { assertThrows(NullPointerException.class, () -> EntryStream.of("a", "*", "b", null).collect( MoreCollectors.entriesToCustomMap(LinkedHashMap::new))); - assertThrows(IllegalStateException.class, + assertStatementThrows(IllegalStateException.class, "Duplicate entry for key 'a' (attempt to merge values '*' and '**')"::equals, () -> EntryStream.of("a", "*", "a", "**").collect(MoreCollectors.entriesToCustomMap(LinkedHashMap::new))); diff --git a/src/test/java/one/util/streamex/PrefixOpsTest.java b/src/test/java/one/util/streamex/api/PrefixOpsTest.java similarity index 96% rename from src/test/java/one/util/streamex/PrefixOpsTest.java rename to src/test/java/one/util/streamex/api/PrefixOpsTest.java index 558502f5..abc62be1 100644 --- a/src/test/java/one/util/streamex/PrefixOpsTest.java +++ b/src/test/java/one/util/streamex/api/PrefixOpsTest.java @@ -13,8 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -package one.util.streamex; +package one.util.streamex.api; import java.util.Arrays; import java.util.HashSet; @@ -25,6 +24,10 @@ import org.junit.Test; +import one.util.streamex.IntStreamEx; +import one.util.streamex.LongStreamEx; +import one.util.streamex.StreamEx; + import static one.util.streamex.TestHelpers.consumeElement; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; diff --git a/src/test/java/one/util/streamex/StreamExHeadTailTest.java b/src/test/java/one/util/streamex/api/StreamExHeadTailTest.java similarity index 97% rename from src/test/java/one/util/streamex/StreamExHeadTailTest.java rename to src/test/java/one/util/streamex/api/StreamExHeadTailTest.java index a7fc4022..ba3e832b 100644 --- a/src/test/java/one/util/streamex/StreamExHeadTailTest.java +++ b/src/test/java/one/util/streamex/api/StreamExHeadTailTest.java @@ -1,586 +1,591 @@ -/* - * Copyright 2015, 2019 StreamEx contributors - * - * 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 one.util.streamex; - -import java.io.StringReader; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Deque; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Random; -import java.util.Set; -import java.util.Spliterator; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.BiPredicate; -import java.util.function.BinaryOperator; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.stream.Collector; -import java.util.stream.Stream; - -import org.junit.Test; - -import static java.util.Arrays.asList; -import static one.util.streamex.TestHelpers.consumeElement; -import static one.util.streamex.TestHelpers.emptyStreamEx; -import static one.util.streamex.TestHelpers.repeat; -import static one.util.streamex.TestHelpers.streamEx; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -/** - * Tests/examples for StreamEx.headTail() method - * - * @author Tagir Valeev - */ -public class StreamExHeadTailTest { - // /////////////////////// - // JDK-8 intermediate ops - - // Stream.skip (TSO) - static StreamEx skip(StreamEx input, int n) { - return input.headTail((head, tail) -> n > 0 ? skip(tail, n - 1) : tail.prepend(head)); - } - - // Stream.limit (TSO) - static StreamEx limit(StreamEx input, int n) { - return input.headTail((head, tail) -> n > 1 ? limit(tail, n - 1).prepend(head) : Stream.of(head)); - } - - // Stream.filter (TSO) - static StreamEx filter(StreamEx input, Predicate predicate) { - return input.headTail((head, tail) -> predicate.test(head) ? filter(tail, predicate).prepend(head) : filter(tail, predicate)); - } - - // Stream.distinct - static StreamEx distinct(StreamEx input) { - return input.headTail((head, tail) -> distinct(tail.filter(n -> !Objects.equals(head, n))).prepend(head)); - } - - // Stream.distinct (TSO) - static StreamEx distinctTSO(StreamEx input) { - return distinctTSO(input, new HashSet<>()); - } - - private static StreamEx distinctTSO(StreamEx input, Set observed) { - return input.headTail((head, tail) -> observed.add(head) ? distinctTSO(tail, observed).prepend(head) - : distinctTSO(tail, observed)); - } - - // Stream.map (TSO) - static StreamEx map(StreamEx input, Function mapper) { - return input.headTail((head, tail) -> map(tail, mapper).prepend(mapper.apply(head))); - } - - // Stream.peek (TSO) - static StreamEx peek(StreamEx input, Consumer consumer) { - return input.headTail((head, tail) -> { - consumer.accept(head); - return peek(tail, consumer).prepend(head); - }); - } - - // Stream.flatMap (TSO) - static StreamEx flatMap(StreamEx input, Function> mapper) { - return input.headTail((head, tail) -> flatMap(tail, mapper).prepend(mapper.apply(head))); - } - - // Stream.sorted - static StreamEx sorted(StreamEx input) { - return sorted(input, new ArrayList<>()); - } - - private static StreamEx sorted(StreamEx input, List cur) { - return input.headTail((head, tail) -> { - cur.add(head); - return sorted(tail, cur); - }, () -> { - cur.sort(null); - return cur.stream(); - }); - } - - // /////////////////////// - // JDK-9 intermediate ops - - // Stream.takeWhile (TSO) - static StreamEx takeWhile(StreamEx input, Predicate predicate) { - return input.headTail((head, tail) -> predicate.test(head) ? takeWhile(tail, predicate).prepend(head) : null); - } - - // Stream.dropWhile (TSO) - static StreamEx dropWhile(StreamEx input, Predicate predicate) { - return input.headTail((head, tail) -> predicate.test(head) ? dropWhile(tail, predicate) : tail.prepend(head)); - } - - // /////////////////////// - // Other intermediate ops - - // Filters the input stream of natural numbers (2, 3, 4...) leaving only - // prime numbers (lazy) - static StreamEx sieve(StreamEx input) { - return input.headTail((head, tail) -> sieve(tail.filter(n -> n % head != 0)).prepend(head)); - } - - // Creates a reversed stream - static StreamEx reverse(StreamEx input) { - return input.headTail((head, tail) -> reverse(tail).append(head)); - } - - // Creates a reversed stream (TSO) - static StreamEx reverseTSO(StreamEx input) { - return reverseTSO(input, new ArrayDeque<>()); - } - - private static StreamEx reverseTSO(StreamEx input, Deque buf) { - return input.headTail((head, tail) -> { - buf.addFirst(head); - return reverseTSO(tail, buf); - }, buf::stream); - } - - // Creates a stream which consists of this stream and this reversed stream - static StreamEx mirror(StreamEx input) { - return input.headTail((head, tail) -> mirror(tail).append(head).prepend(head)); - } - - // Creates a reversed stream (TSO) - static StreamEx mirrorTSO(StreamEx input) { - return mirrorTSO(input, new ArrayDeque<>()); - } - - private static StreamEx mirrorTSO(StreamEx input, Deque buf) { - return input.headTail((head, tail) -> { - buf.addFirst(head); - return mirrorTSO(tail, buf).prepend(head); - }, buf::stream); - } - - // Creates an infinitely cycled stream - static StreamEx cycle(StreamEx input) { - return input.headTail((head, tail) -> cycle(tail.append(head)).prepend(head)); - } - - // Creates a n-times cycled stream (TSO) - static StreamEx cycleTSO(StreamEx input, int n) { - return cycleTSO(input, n, new ArrayList<>()); - } - - private static StreamEx cycleTSO(StreamEx input, int n, List buf) { - return input.headTail((head, tail) -> { - buf.add(head); - return cycleTSO(tail, n, buf).prepend(head); - }, () -> IntStreamEx.range(n - 1).flatMapToObj(i -> buf.stream())); - } - - // mapFirst (TSO) - static StreamEx mapFirst(StreamEx input, UnaryOperator operator) { - return input.headTail((head, tail) -> tail.prepend(operator.apply(head))); - } - - // Creates lazy scanLeft stream (TSO) - static StreamEx scanLeft(StreamEx input, BinaryOperator operator) { - return input.headTail((head, tail) -> scanLeft(tail.mapFirst(cur -> operator.apply(head, cur)), operator) - .prepend(head)); - } - - static UnaryOperator> scanLeft(BinaryOperator operator) { - return stream -> scanLeft(stream, operator); - } - - // takeWhileClosed: takeWhile+first element violating the predicate (TSO) - static StreamEx takeWhileClosed(StreamEx input, Predicate predicate) { - return input.headTail((head, tail) -> predicate.test(head) ? takeWhileClosed(tail, predicate).prepend(head) - : Stream.of(head)); - } - - // take every nth stream element (starting from the first) (TSO) - static StreamEx every(StreamEx input, int n) { - return input.headTail((head, tail) -> every(skip(tail, n - 1), n).prepend(head)); - } - - static StreamEx every3(StreamEx input) { - return input.headTail( - (first, tail1) -> tail1.headTail( - (second, tail2) -> tail2.headTail( - (third, tail3) -> every3(tail3))).prepend(first)); - } - - // maps every couple of elements using given mapper (in non-sliding manner) - static StreamEx couples(StreamEx input, BiFunction mapper) { - return input.headTail((left, tail1) -> tail1.headTail((right, tail2) -> couples(tail2, mapper).prepend( - mapper.apply(left, right)))); - } - - // maps every pair of elements using given mapper (in sliding manner) - static StreamEx pairs(StreamEx input, BiFunction mapper) { - return input.headTail((left, tail1) -> tail1.headTail((right, tail2) -> pairs(tail2.prepend(right), mapper) - .prepend(mapper.apply(left, right)))); - } - - // Stream of fixed size batches (TSO) - static StreamEx> batches(StreamEx input, int size) { - return batches(input, size, Collections.emptyList()); - } - - private static StreamEx> batches(StreamEx input, int size, List cur) { - return input.headTail((head, tail) -> cur.size() >= size - ? batches(tail, size, asList(head)).prepend(cur) - : batches(tail, size, StreamEx.of(cur).append(head).toList()), - () -> Stream.of(cur)); - } - - // Stream of single element lists -> stream of sliding windows (TSO) - static StreamEx> sliding(StreamEx> input, int size) { - return input.headTail((head, tail) -> head.size() == size ? sliding( - tail.mapFirst(next -> StreamEx.of(head.subList(1, size), next).toFlatList(l -> l)), size).prepend(head) - : sliding(tail.mapFirst(next -> StreamEx.of(head, next).toFlatList(l -> l)), size)); - } - - // Stream of dominators (removes immediately following elements which the - // current element dominates on) (TSO) - static StreamEx dominators(StreamEx input, BiPredicate isDominator) { - return input.headTail((head, tail) -> dominators(dropWhile(tail, e -> isDominator.test(head, e)), isDominator) - .prepend(head)); - } - - // Stream of mappings of (index, element) (TSO) - static StreamEx withIndices(StreamEx input, BiFunction mapper) { - return withIndices(input, 0, mapper); - } - - private static StreamEx withIndices(StreamEx input, int idx, BiFunction mapper) { - return input.headTail((head, tail) -> withIndices(tail, idx + 1, mapper).prepend(mapper.apply(idx, head))); - } - - // Appends the stream of Integer with their sum - static StreamEx appendSum(StreamEx input) { - return reduceLast(input.append(0), Integer::sum); - } - - private static StreamEx reduceLast(StreamEx input, BinaryOperator op) { - return input.headTail((head, tail) -> reduceLast(tail, op).prepend(head).mapLast(last -> op.apply(head, last))); - } - - // Append the result of reduction of given stream (TCO) - static StreamEx appendReduction(StreamEx input, T identity, BinaryOperator op) { - return input.headTail((head, tail) -> appendReduction(tail, op.apply(identity, head), op).prepend(head), - () -> Stream.of(identity)); - } - - // Returns stream filtered by f1, then concatenated with the original stream filtered by f2 - static StreamEx twoFilters(StreamEx input, Predicate f1, Predicate f2) { - return twoFilters(input, f1, f2, Stream.builder()); - } - - private static StreamEx twoFilters(StreamEx input, Predicate f1, Predicate f2, Stream.Builder buf) { - return input.headTail((head, tail) -> { - StreamEx res = twoFilters(tail, f1, f2, buf); - if (f2.test(head)) { - buf.add(head); - } - return f1.test(head) ? res.prepend(head) : res; - }, buf::build); - } - - static StreamEx skipLast(Stream input, int n) { - return skipLast(StreamEx.of(input), n, new ArrayDeque<>()); - } - - private static StreamEx skipLast(StreamEx input, int n, Deque buf) { - return input.headTail((head, tail) -> { - buf.addLast(head); - return buf.size() > n ? skipLast(tail, n, buf).prepend(buf.pollFirst()) : skipLast(tail, n, buf); - }); - } - - static UnaryOperator> limitSorted(Comparator comparator, int n) { - @SuppressWarnings("unchecked") - Collector> collector = (Collector>) MoreCollectors.least(comparator, n); - return stream -> collectAndStream(stream, collector.supplier().get(), collector.accumulator(), collector - .finisher().andThen(StreamEx::of)); - } - - private static StreamEx collectAndStream(StreamEx input, A buf, BiConsumer accumulator, Function> finisher) { - return input.headTail((head, tail) -> { - accumulator.accept(buf, head); - return collectAndStream(tail, buf, accumulator, finisher); - }, () -> finisher.apply(buf)); - } - - static UnaryOperator> moveToEnd(Predicate pred) { - return stream -> moveToEnd(stream, pred, Stream.builder()); - } - - private static StreamEx moveToEnd(StreamEx input, Predicate pred, Stream.Builder buf) { - return input.headTail((head, tail) -> - pred.test(head) ? moveToEnd(tail, pred, buf.add(head)) : moveToEnd(tail, pred, buf).prepend(head), - buf::build); - } - - static UnaryOperator> moveToEndOrMap(Predicate pred, UnaryOperator mapper) { - return stream -> moveToEndOrMap(stream, pred, mapper, Stream.builder()); - } - - private static StreamEx moveToEndOrMap(StreamEx input, Predicate pred, UnaryOperator mapper, Stream.Builder buf) { - return input.headTail((head, tail) -> - pred.test(head) - ? moveToEndOrMap(tail, pred, mapper, buf.add(head)) - : moveToEndOrMap(tail, pred, mapper, buf).prepend(mapper.apply(head)), - buf::build); - } - - // /////////////////////// - // Terminal ops - - // Returns either the first stream element matching the predicate or just - // the first element if nothing matches - private static T firstMatchingOrFirst(StreamEx stream, Predicate predicate) { - return stream.headTail((head, tail) -> tail.prepend(head).filter(predicate).append(head)).findFirst().get(); - } - - // /////////////////////// - // Tests - - @Test - public void testHeadTailRecursive() { - streamEx(() -> StreamEx.iterate(2, x -> x + 1), s -> assertEquals(asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, - 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97), s.get().chain(StreamExHeadTailTest::sieve).takeWhile( - x -> x < 100).toList())); - - emptyStreamEx(Integer.class, s -> { - assertEquals(0L, s.get().headTail((first, head) -> { - throw new IllegalStateException(); - }).count()); - assertFalse(s.get().headTail((first, head) -> { - throw new IllegalStateException(); - }).findFirst().isPresent()); - }); - - streamEx(() -> IntStreamEx.range(100).boxed(), s -> assertEquals(IntStreamEx.rangeClosed(99, 0, -1).boxed() - .toList(), reverse(s.get()).toList())); - streamEx(() -> IntStreamEx.range(100).boxed(), s -> assertEquals(IntStreamEx.rangeClosed(99, 0, -1).boxed() - .toList(), reverseTSO(s.get()).toList())); - - streamEx(() -> StreamEx.of(1, 2), s -> assertEquals(0, s.get().headTail((head, stream) -> null).count())); - - streamEx(() -> StreamEx.iterate(1, x -> x + 1), s -> assertEquals(asList(1, 3, 6, 10, 15, 21, 28, 36, 45, 55, - 66, 78, 91), s.get().chain(scanLeft(Integer::sum)).takeWhile(x -> x < 100).toList())); - - streamEx(() -> StreamEx.iterate(1, x -> x + 1), s -> assertEquals(IntStreamEx.range(1, 100).boxed().toList(), - takeWhile(s.get(), x -> x < 100).toList())); - - streamEx(() -> StreamEx.iterate(1, x -> x + 1), s -> assertEquals(IntStreamEx.rangeClosed(1, 100).boxed() - .toList(), s.get().chain(str -> takeWhileClosed(str, x -> x < 100)).toList())); - - streamEx(() -> IntStreamEx.range(1000).boxed(), s -> assertEquals(IntStreamEx.range(0, 1000, 20).boxed() - .toList(), every(s.get(), 20).toList())); - - // http://stackoverflow.com/q/34395943/4856258 - int[] input = { 1, 2, 3, -1, 3, -10, 9, 100, 1, 100, 0 }; - AtomicInteger counter = new AtomicInteger(); - assertEquals(5, IntStreamEx.of(input).peek(x -> counter.incrementAndGet()).boxed() - .chain(scanLeft(Integer::sum)).indexOf(x -> x < 0).getAsLong()); - assertEquals(6, counter.get()); - - assertEquals(4, (int) firstMatchingOrFirst(StreamEx.of(1, 2, 3, 4, 5), x -> x > 3)); - assertEquals(1, (int) firstMatchingOrFirst(StreamEx.of(1, 2, 3, 4, 5), x -> x > 5)); - assertEquals(1, (int) firstMatchingOrFirst(StreamEx.of(1, 2, 3, 4, 5), x -> x > 0)); - - assertEquals(asList(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3), cycle(StreamEx.of(1, 2, 3, 4, 5)) - .limit(18).toList()); - assertEquals(asList(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5), cycleTSO(StreamEx.of(1, 2, 3, 4, 5), 3) - .toList()); - assertEquals(asList(1, 2, 3, 4, 5, 5, 4, 3, 2, 1), mirror(StreamEx.of(1, 2, 3, 4, 5)).toList()); - - assertEquals(asList(9, 13, 17), StreamEx.of(1, 3, 5, 7, 9).headTail( - (head, tail) -> tail.pairMap((a, b) -> a + b + head)).toList()); - - assertEquals("[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]", batches( - IntStreamEx.range(20).boxed(), 4).toList().toString()); - assertEquals("[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19], [20]]", batches( - IntStreamEx.range(21).boxed(), 4).toList().toString()); - assertEquals( - "[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9]]", - sliding(IntStreamEx.range(10).mapToObj(Collections::singletonList), 4).toList().toString()); - - assertEquals(IntStreamEx.range(50, 100).boxed().toList(), dropWhile(IntStreamEx.range(100).boxed(), - i -> i != 50).toList()); - - assertEquals(asList(1, 3, 4, 7, 10), dominators( - StreamEx.of(1, 3, 4, 2, 1, 7, 5, 3, 4, 0, 4, 6, 7, 10, 4, 3, 2, 1), (a, b) -> a >= b).toList()); - - assertEquals(asList(1, 3, 7, 5, 10), distinct( - StreamEx.of(1, 1, 3, 1, 3, 7, 1, 3, 1, 7, 3, 5, 1, 3, 5, 5, 7, 7, 7, 10, 5, 3, 7, 1)).toList()); - - assertEquals(asList("key1=1", "key2=2", "key3=3"), couples(StreamEx.of("key1", 1, "key2", 2, "key3", 3), - (k, v) -> k + "=" + v).toList()); - - assertEquals(asList("key1=1", "1=key2", "key2=2", "2=key3", "key3=3"), pairs( - StreamEx.of("key1", 1, "key2", 2, "key3", 3), (k, v) -> k + "=" + v).toList()); - - assertEquals(asList("1. Foo", "2. Bar", "3. Baz"), withIndices(StreamEx.of("Foo", "Bar", "Baz"), - (idx, e) -> (idx + 1) + ". " + e).toList()); - - assertEquals(asList(1, 2, 3, 4, 10), appendSum(StreamEx.of(1, 2, 3, 4)).toList()); - assertFalse(appendSum(StreamEx.of(1, 2, 3, 4)).has(11)); - - assertEquals(asList(0, 3, 6, 9, 12, 15, 18, 0, 4, 8, 12, 16), twoFilters(IntStreamEx.range(20).boxed(), - x -> x % 3 == 0, x -> x % 4 == 0).toList()); - - assertEquals(asList(5, 10, 1, 6, 7), skipLast(Stream.of(5, 10, 1, 6, 7, 15, -1, 10), 3).toList()); - assertEquals(asList(0, 3, 6, 9, 12, 15, 18), every3(IntStreamEx.range(20).boxed()).toList()); - - //noinspection RedundantTypeArguments -- necessary for Javac 8u92 - assertEquals(asList(0, 1, 2, 3, 3), - StreamEx.of(0, 1, 4, 2, 10, 3, 5, 10, 3, 15).chain(limitSorted(Comparator.naturalOrder(), 5)).toList()); - - assertEquals(asList(1, 3, 7, 9, 2, 4, 11, 17, 5, 10), - StreamEx.of(1, 3, 5, 7, 9, 2, 4, 10, 11, 17).chain(moveToEnd(x -> x % 5 == 0)).toList()); - assertEquals(asList(2, 4, 8, 10, 3, 5, 12, 18, 5, 10), - StreamEx.of(1, 3, 5, 7, 9, 2, 4, 10, 11, 17).chain(moveToEndOrMap(x -> x % 5 == 0, x -> x + 1)).toList()); - assertEquals(asList(11, 21, 41, 51, 30), - StreamEx.of(10, 20, 30, 40, 50).chain(moveToEndOrMap(x -> x == 30, x -> x + 1)).toList()); - } - - @Test - public void testHeadTailTCO() { - assertTrue(couples(IntStreamEx.range(20000).boxed(), (a, b) -> b - a).allMatch(x -> x == 1)); - assertTrue(pairs(IntStreamEx.range(20000).boxed(), (a, b) -> b - a).allMatch(x -> x == 1)); - // 20001+20002+...+40000 - assertEquals(600010000, limit(skip(StreamEx.iterate(1, x -> x + 1), 20000), 20000).mapToInt(Integer::intValue) - .sum()); - // 1+3+5+...+39999 - assertEquals(400000000, limit(every(StreamEx.iterate(1, x -> x + 1), 2), 20000).mapToInt(Integer::intValue) - .sum()); - assertEquals(400000000, limit(filter(StreamEx.iterate(1, x -> x + 1), x -> x % 2 != 0), 20000).mapToInt( - Integer::intValue).sum()); - // 1+2+...+10000 - assertEquals(50005000, (int) limit(scanLeft(StreamEx.iterate(1, x -> x + 1), Integer::sum), 10000).reduce( - (a, b) -> b).get()); - assertEquals(50005000, (int) limit(flatMap(StreamEx.iterate(1, x -> x + 3), (Integer x) -> StreamEx.of(x, x + 1, x + 2)), - 10000).reduce(Integer::sum).get()); - assertEquals(asList(50005000), skip( - appendReduction(IntStreamEx.rangeClosed(1, 10000).boxed(), 0, Integer::sum), 10000).toList()); - assertEquals(499501, mapFirst(IntStreamEx.range(1000).boxed(), x -> x + 1).mapToInt(x -> x).sum()); - AtomicInteger sum = new AtomicInteger(); - assertEquals(10000, peek(IntStreamEx.rangeClosed(1, 10000).boxed(), sum::addAndGet).count()); - assertEquals(50005000, sum.get()); - - - assertEquals(400020000, (int) limit(map(StreamEx.iterate(1, x -> x + 1), x -> x * 2), 20000).reduce( - Integer::sum).get()); - - assertEquals(19999, takeWhile(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).count()); - assertTrue(takeWhile(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).has(19999)); - assertEquals(20000, takeWhileClosed(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).count()); - assertTrue(takeWhileClosed(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).has(20000)); - assertEquals(IntStreamEx.range(20000, 40000).boxed().toList(), dropWhile(IntStreamEx.range(40000).boxed(), - i -> i != 20000).toList()); - assertEquals(5000, batches(IntStreamEx.range(20000).boxed(), 4).count()); - assertEquals(4, batches(IntStreamEx.range(20000).boxed(), 5000).count()); - assertEquals(19997, sliding(IntStreamEx.range(20000).mapToObj(Collections::singletonList), 4).count()); - assertEquals(IntStreamEx.range(40000).boxed().toList(), dominators(IntStreamEx.range(40000).boxed(), - (a, b) -> a >= b).toList()); - assertEquals(15, dominators(IntStreamEx.of(new Random(1)).boxed(), (a, b) -> a >= b).takeWhile( - x -> x < Integer.MAX_VALUE - 100000).count()); - - assertEquals(IntStreamEx.of(new Random(1), 10000).boxed().sorted().toList(), sorted( - IntStreamEx.of(new Random(1), 10000).boxed()).toList()); - - assertEquals(10000, withIndices(IntStreamEx.of(new Random(1), 10000).boxed(), (idx, e) -> idx + ": " + e) - .count()); - - assertEquals(10000, limit(distinctTSO(IntStreamEx.of(new Random(1)).boxed()), 10000).toSet().size()); - assertEquals(IntStreamEx.range(10000).boxed().toList(), sorted(limit( - distinctTSO(IntStreamEx.of(new Random(1), 0, 10000).boxed()), 10000)).toList()); - assertEquals(IntStreamEx.rangeClosed(9999, 0, -1).boxed() - .toList(), reverseTSO(IntStreamEx.range(10000).boxed()).toList()); - assertEquals(IntStreamEx.range(10000).append(IntStreamEx.rangeClosed(9999, 0, -1)).boxed().toList(), - mirrorTSO(IntStreamEx.range(10000).boxed()).toList()); - } - - @Test - public void testHeadTailClose() { - AtomicBoolean origClosed = new AtomicBoolean(); - AtomicBoolean internalClosed = new AtomicBoolean(); - AtomicBoolean finalClosed = new AtomicBoolean(); - StreamEx res = StreamEx.of(1, 2, 3).onClose(() -> origClosed.set(true)).headTail( - (head, stream) -> stream.onClose(() -> internalClosed.set(true)).map(x -> x + head)).onClose( - () -> finalClosed.set(true)); - assertEquals(asList(3, 4), res.toList()); - res.close(); - assertTrue(origClosed.get()); - assertTrue(internalClosed.get()); - assertTrue(finalClosed.get()); - - res = StreamEx.empty().headTail((head, tail) -> tail); - assertEquals(0, res.count()); - res.close(); - } - - // Test simple non-recursive scenarios - @Test - public void testHeadTailSimple() { - repeat(10, i -> { - // Header mapping - String input = "name,type,value\nID,int,5\nSurname,string,Smith\nGiven name,string,John"; - List> expected = asList(EntryStream.of("name", "ID", "type", "int", "value", "5") - .toMap(), EntryStream.of("name", "Surname", "type", "string", "value", "Smith").toMap(), - EntryStream.of("name", "Given name", "type", "string", "value", "John").toMap()); - streamEx(() -> StreamEx.ofLines(new StringReader(input)), s -> assertEquals(expected, s.get().map( - str -> str.split(",")).headTail( - (header, stream) -> stream.map(row -> EntryStream.zip(header, row).toMap())).toList())); - }); - streamEx(() -> StreamEx.of("a", "b", "c", "d"), s -> assertEquals(Collections.singletonMap("a", asList("b", - "c", "d")), s.get().headTail((x, str) -> str.mapToEntry(e -> x, e -> e)).mapToEntry(Entry::getKey, - Entry::getValue).grouping())); - assertEquals(asList("b:c", "c:d"), StreamEx.of(":", "b", "c", "d").headTail( - (head, tail) -> tail.pairMap((left, right) -> left + head + right)).toList()); - assertEquals(asList("b:", "c", "d"), StreamEx.of(":", "b", "c", "d").headTail( - (head, tail) -> tail.mapFirst(first -> first + head)).toList()); - - } - - @Test - public void testSpliterator() { - Spliterator spltr = map(StreamEx.of(1, 2, 3, 4), x -> x * 2).spliterator(); - assertTrue(spltr.hasCharacteristics(Spliterator.ORDERED)); - assertEquals(4, spltr.estimateSize()); - consumeElement(spltr, 2); - assertEquals(3, spltr.estimateSize()); - consumeElement(spltr, 4); - assertEquals(2, spltr.estimateSize()); - consumeElement(spltr, 6); - assertEquals(1, spltr.estimateSize()); - consumeElement(spltr, 8); - assertFalse(spltr.tryAdvance(x -> fail("Should not be called"))); - assertEquals(0, spltr.estimateSize()); - } -} +/* + * Copyright 2015, 2020 StreamEx contributors + * + * 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 one.util.streamex.api; + +import java.io.StringReader; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Deque; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.Spliterator; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.BinaryOperator; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.UnaryOperator; +import java.util.stream.Collector; +import java.util.stream.Stream; + +import org.junit.Test; + +import one.util.streamex.EntryStream; +import one.util.streamex.IntStreamEx; +import one.util.streamex.MoreCollectors; +import one.util.streamex.StreamEx; + +import static java.util.Arrays.asList; +import static one.util.streamex.TestHelpers.consumeElement; +import static one.util.streamex.TestHelpers.emptyStreamEx; +import static one.util.streamex.TestHelpers.repeat; +import static one.util.streamex.TestHelpers.streamEx; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +/** + * Tests/examples for StreamEx.headTail() method + * + * @author Tagir Valeev + */ +public class StreamExHeadTailTest { + // /////////////////////// + // JDK-8 intermediate ops + + // Stream.skip (TSO) + static StreamEx skip(StreamEx input, int n) { + return input.headTail((head, tail) -> n > 0 ? skip(tail, n - 1) : tail.prepend(head)); + } + + // Stream.limit (TSO) + static StreamEx limit(StreamEx input, int n) { + return input.headTail((head, tail) -> n > 1 ? limit(tail, n - 1).prepend(head) : Stream.of(head)); + } + + // Stream.filter (TSO) + static StreamEx filter(StreamEx input, Predicate predicate) { + return input.headTail((head, tail) -> predicate.test(head) ? filter(tail, predicate).prepend(head) : filter(tail, predicate)); + } + + // Stream.distinct + static StreamEx distinct(StreamEx input) { + return input.headTail((head, tail) -> distinct(tail.filter(n -> !Objects.equals(head, n))).prepend(head)); + } + + // Stream.distinct (TSO) + static StreamEx distinctTSO(StreamEx input) { + return distinctTSO(input, new HashSet<>()); + } + + private static StreamEx distinctTSO(StreamEx input, Set observed) { + return input.headTail((head, tail) -> observed.add(head) ? distinctTSO(tail, observed).prepend(head) + : distinctTSO(tail, observed)); + } + + // Stream.map (TSO) + static StreamEx map(StreamEx input, Function mapper) { + return input.headTail((head, tail) -> map(tail, mapper).prepend(mapper.apply(head))); + } + + // Stream.peek (TSO) + static StreamEx peek(StreamEx input, Consumer consumer) { + return input.headTail((head, tail) -> { + consumer.accept(head); + return peek(tail, consumer).prepend(head); + }); + } + + // Stream.flatMap (TSO) + static StreamEx flatMap(StreamEx input, Function> mapper) { + return input.headTail((head, tail) -> flatMap(tail, mapper).prepend(mapper.apply(head))); + } + + // Stream.sorted + static StreamEx sorted(StreamEx input) { + return sorted(input, new ArrayList<>()); + } + + private static StreamEx sorted(StreamEx input, List cur) { + return input.headTail((head, tail) -> { + cur.add(head); + return sorted(tail, cur); + }, () -> { + cur.sort(null); + return cur.stream(); + }); + } + + // /////////////////////// + // JDK-9 intermediate ops + + // Stream.takeWhile (TSO) + static StreamEx takeWhile(StreamEx input, Predicate predicate) { + return input.headTail((head, tail) -> predicate.test(head) ? takeWhile(tail, predicate).prepend(head) : null); + } + + // Stream.dropWhile (TSO) + static StreamEx dropWhile(StreamEx input, Predicate predicate) { + return input.headTail((head, tail) -> predicate.test(head) ? dropWhile(tail, predicate) : tail.prepend(head)); + } + + // /////////////////////// + // Other intermediate ops + + // Filters the input stream of natural numbers (2, 3, 4...) leaving only + // prime numbers (lazy) + static StreamEx sieve(StreamEx input) { + return input.headTail((head, tail) -> sieve(tail.filter(n -> n % head != 0)).prepend(head)); + } + + // Creates a reversed stream + static StreamEx reverse(StreamEx input) { + return input.headTail((head, tail) -> reverse(tail).append(head)); + } + + // Creates a reversed stream (TSO) + static StreamEx reverseTSO(StreamEx input) { + return reverseTSO(input, new ArrayDeque<>()); + } + + private static StreamEx reverseTSO(StreamEx input, Deque buf) { + return input.headTail((head, tail) -> { + buf.addFirst(head); + return reverseTSO(tail, buf); + }, buf::stream); + } + + // Creates a stream which consists of this stream and this reversed stream + static StreamEx mirror(StreamEx input) { + return input.headTail((head, tail) -> mirror(tail).append(head).prepend(head)); + } + + // Creates a reversed stream (TSO) + static StreamEx mirrorTSO(StreamEx input) { + return mirrorTSO(input, new ArrayDeque<>()); + } + + private static StreamEx mirrorTSO(StreamEx input, Deque buf) { + return input.headTail((head, tail) -> { + buf.addFirst(head); + return mirrorTSO(tail, buf).prepend(head); + }, buf::stream); + } + + // Creates an infinitely cycled stream + static StreamEx cycle(StreamEx input) { + return input.headTail((head, tail) -> cycle(tail.append(head)).prepend(head)); + } + + // Creates a n-times cycled stream (TSO) + static StreamEx cycleTSO(StreamEx input, int n) { + return cycleTSO(input, n, new ArrayList<>()); + } + + private static StreamEx cycleTSO(StreamEx input, int n, List buf) { + return input.headTail((head, tail) -> { + buf.add(head); + return cycleTSO(tail, n, buf).prepend(head); + }, () -> IntStreamEx.range(n - 1).flatMapToObj(i -> buf.stream())); + } + + // mapFirst (TSO) + static StreamEx mapFirst(StreamEx input, UnaryOperator operator) { + return input.headTail((head, tail) -> tail.prepend(operator.apply(head))); + } + + // Creates lazy scanLeft stream (TSO) + static StreamEx scanLeft(StreamEx input, BinaryOperator operator) { + return input.headTail((head, tail) -> scanLeft(tail.mapFirst(cur -> operator.apply(head, cur)), operator) + .prepend(head)); + } + + static UnaryOperator> scanLeft(BinaryOperator operator) { + return stream -> scanLeft(stream, operator); + } + + // takeWhileClosed: takeWhile+first element violating the predicate (TSO) + static StreamEx takeWhileClosed(StreamEx input, Predicate predicate) { + return input.headTail((head, tail) -> predicate.test(head) ? takeWhileClosed(tail, predicate).prepend(head) + : Stream.of(head)); + } + + // take every nth stream element (starting from the first) (TSO) + static StreamEx every(StreamEx input, int n) { + return input.headTail((head, tail) -> every(skip(tail, n - 1), n).prepend(head)); + } + + static StreamEx every3(StreamEx input) { + return input.headTail( + (first, tail1) -> tail1.headTail( + (second, tail2) -> tail2.headTail( + (third, tail3) -> every3(tail3))).prepend(first)); + } + + // maps every couple of elements using given mapper (in non-sliding manner) + static StreamEx couples(StreamEx input, BiFunction mapper) { + return input.headTail((left, tail1) -> tail1.headTail((right, tail2) -> couples(tail2, mapper).prepend( + mapper.apply(left, right)))); + } + + // maps every pair of elements using given mapper (in sliding manner) + static StreamEx pairs(StreamEx input, BiFunction mapper) { + return input.headTail((left, tail1) -> tail1.headTail((right, tail2) -> pairs(tail2.prepend(right), mapper) + .prepend(mapper.apply(left, right)))); + } + + // Stream of fixed size batches (TSO) + static StreamEx> batches(StreamEx input, int size) { + return batches(input, size, Collections.emptyList()); + } + + private static StreamEx> batches(StreamEx input, int size, List cur) { + return input.headTail((head, tail) -> cur.size() >= size + ? batches(tail, size, asList(head)).prepend(cur) + : batches(tail, size, StreamEx.of(cur).append(head).toList()), + () -> Stream.of(cur)); + } + + // Stream of single element lists -> stream of sliding windows (TSO) + static StreamEx> sliding(StreamEx> input, int size) { + return input.headTail((head, tail) -> head.size() == size ? sliding( + tail.mapFirst(next -> StreamEx.of(head.subList(1, size), next).toFlatList(l -> l)), size).prepend(head) + : sliding(tail.mapFirst(next -> StreamEx.of(head, next).toFlatList(l -> l)), size)); + } + + // Stream of dominators (removes immediately following elements which the + // current element dominates on) (TSO) + static StreamEx dominators(StreamEx input, BiPredicate isDominator) { + return input.headTail((head, tail) -> dominators(dropWhile(tail, e -> isDominator.test(head, e)), isDominator) + .prepend(head)); + } + + // Stream of mappings of (index, element) (TSO) + static StreamEx withIndices(StreamEx input, BiFunction mapper) { + return withIndices(input, 0, mapper); + } + + private static StreamEx withIndices(StreamEx input, int idx, BiFunction mapper) { + return input.headTail((head, tail) -> withIndices(tail, idx + 1, mapper).prepend(mapper.apply(idx, head))); + } + + // Appends the stream of Integer with their sum + static StreamEx appendSum(StreamEx input) { + return reduceLast(input.append(0), Integer::sum); + } + + private static StreamEx reduceLast(StreamEx input, BinaryOperator op) { + return input.headTail((head, tail) -> reduceLast(tail, op).prepend(head).mapLast(last -> op.apply(head, last))); + } + + // Append the result of reduction of given stream (TCO) + static StreamEx appendReduction(StreamEx input, T identity, BinaryOperator op) { + return input.headTail((head, tail) -> appendReduction(tail, op.apply(identity, head), op).prepend(head), + () -> Stream.of(identity)); + } + + // Returns stream filtered by f1, then concatenated with the original stream filtered by f2 + static StreamEx twoFilters(StreamEx input, Predicate f1, Predicate f2) { + return twoFilters(input, f1, f2, Stream.builder()); + } + + private static StreamEx twoFilters(StreamEx input, Predicate f1, Predicate f2, Stream.Builder buf) { + return input.headTail((head, tail) -> { + StreamEx res = twoFilters(tail, f1, f2, buf); + if (f2.test(head)) { + buf.add(head); + } + return f1.test(head) ? res.prepend(head) : res; + }, buf::build); + } + + static StreamEx skipLast(Stream input, int n) { + return skipLast(StreamEx.of(input), n, new ArrayDeque<>()); + } + + private static StreamEx skipLast(StreamEx input, int n, Deque buf) { + return input.headTail((head, tail) -> { + buf.addLast(head); + return buf.size() > n ? skipLast(tail, n, buf).prepend(buf.pollFirst()) : skipLast(tail, n, buf); + }); + } + + static UnaryOperator> limitSorted(Comparator comparator, int n) { + @SuppressWarnings("unchecked") + Collector> collector = (Collector>) MoreCollectors.least(comparator, n); + return stream -> collectAndStream(stream, collector.supplier().get(), collector.accumulator(), collector + .finisher().andThen(StreamEx::of)); + } + + private static StreamEx collectAndStream(StreamEx input, A buf, BiConsumer accumulator, Function> finisher) { + return input.headTail((head, tail) -> { + accumulator.accept(buf, head); + return collectAndStream(tail, buf, accumulator, finisher); + }, () -> finisher.apply(buf)); + } + + static UnaryOperator> moveToEnd(Predicate pred) { + return stream -> moveToEnd(stream, pred, Stream.builder()); + } + + private static StreamEx moveToEnd(StreamEx input, Predicate pred, Stream.Builder buf) { + return input.headTail((head, tail) -> + pred.test(head) ? moveToEnd(tail, pred, buf.add(head)) : moveToEnd(tail, pred, buf).prepend(head), + buf::build); + } + + static UnaryOperator> moveToEndOrMap(Predicate pred, UnaryOperator mapper) { + return stream -> moveToEndOrMap(stream, pred, mapper, Stream.builder()); + } + + private static StreamEx moveToEndOrMap(StreamEx input, Predicate pred, UnaryOperator mapper, Stream.Builder buf) { + return input.headTail((head, tail) -> + pred.test(head) + ? moveToEndOrMap(tail, pred, mapper, buf.add(head)) + : moveToEndOrMap(tail, pred, mapper, buf).prepend(mapper.apply(head)), + buf::build); + } + + // /////////////////////// + // Terminal ops + + // Returns either the first stream element matching the predicate or just + // the first element if nothing matches + private static T firstMatchingOrFirst(StreamEx stream, Predicate predicate) { + return stream.headTail((head, tail) -> tail.prepend(head).filter(predicate).append(head)).findFirst().get(); + } + + // /////////////////////// + // Tests + + @Test + public void testHeadTailRecursive() { + streamEx(() -> StreamEx.iterate(2, x -> x + 1), s -> assertEquals(asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97), s.get().chain(StreamExHeadTailTest::sieve).takeWhile( + x -> x < 100).toList())); + + emptyStreamEx(Integer.class, s -> { + assertEquals(0L, s.get().headTail((first, head) -> { + throw new IllegalStateException(); + }).count()); + assertFalse(s.get().headTail((first, head) -> { + throw new IllegalStateException(); + }).findFirst().isPresent()); + }); + + streamEx(() -> IntStreamEx.range(100).boxed(), s -> assertEquals(IntStreamEx.rangeClosed(99, 0, -1).boxed() + .toList(), reverse(s.get()).toList())); + streamEx(() -> IntStreamEx.range(100).boxed(), s -> assertEquals(IntStreamEx.rangeClosed(99, 0, -1).boxed() + .toList(), reverseTSO(s.get()).toList())); + + streamEx(() -> StreamEx.of(1, 2), s -> assertEquals(0, s.get().headTail((head, stream) -> null).count())); + + streamEx(() -> StreamEx.iterate(1, x -> x + 1), s -> assertEquals(asList(1, 3, 6, 10, 15, 21, 28, 36, 45, 55, + 66, 78, 91), s.get().chain(scanLeft(Integer::sum)).takeWhile(x -> x < 100).toList())); + + streamEx(() -> StreamEx.iterate(1, x -> x + 1), s -> assertEquals(IntStreamEx.range(1, 100).boxed().toList(), + takeWhile(s.get(), x -> x < 100).toList())); + + streamEx(() -> StreamEx.iterate(1, x -> x + 1), s -> assertEquals(IntStreamEx.rangeClosed(1, 100).boxed() + .toList(), s.get().chain(str -> takeWhileClosed(str, x -> x < 100)).toList())); + + streamEx(() -> IntStreamEx.range(1000).boxed(), s -> assertEquals(IntStreamEx.range(0, 1000, 20).boxed() + .toList(), every(s.get(), 20).toList())); + + // http://stackoverflow.com/q/34395943/4856258 + int[] input = { 1, 2, 3, -1, 3, -10, 9, 100, 1, 100, 0 }; + AtomicInteger counter = new AtomicInteger(); + assertEquals(5, IntStreamEx.of(input).peek(x -> counter.incrementAndGet()).boxed() + .chain(scanLeft(Integer::sum)).indexOf(x -> x < 0).getAsLong()); + assertEquals(6, counter.get()); + + assertEquals(4, (int) firstMatchingOrFirst(StreamEx.of(1, 2, 3, 4, 5), x -> x > 3)); + assertEquals(1, (int) firstMatchingOrFirst(StreamEx.of(1, 2, 3, 4, 5), x -> x > 5)); + assertEquals(1, (int) firstMatchingOrFirst(StreamEx.of(1, 2, 3, 4, 5), x -> x > 0)); + + assertEquals(asList(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3), cycle(StreamEx.of(1, 2, 3, 4, 5)) + .limit(18).toList()); + assertEquals(asList(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5), cycleTSO(StreamEx.of(1, 2, 3, 4, 5), 3) + .toList()); + assertEquals(asList(1, 2, 3, 4, 5, 5, 4, 3, 2, 1), mirror(StreamEx.of(1, 2, 3, 4, 5)).toList()); + + assertEquals(asList(9, 13, 17), StreamEx.of(1, 3, 5, 7, 9).headTail( + (head, tail) -> tail.pairMap((a, b) -> a + b + head)).toList()); + + assertEquals("[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]]", batches( + IntStreamEx.range(20).boxed(), 4).toList().toString()); + assertEquals("[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19], [20]]", batches( + IntStreamEx.range(21).boxed(), 4).toList().toString()); + assertEquals( + "[[0, 1, 2, 3], [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 9]]", + sliding(IntStreamEx.range(10).mapToObj(Collections::singletonList), 4).toList().toString()); + + assertEquals(IntStreamEx.range(50, 100).boxed().toList(), dropWhile(IntStreamEx.range(100).boxed(), + i -> i != 50).toList()); + + assertEquals(asList(1, 3, 4, 7, 10), dominators( + StreamEx.of(1, 3, 4, 2, 1, 7, 5, 3, 4, 0, 4, 6, 7, 10, 4, 3, 2, 1), (a, b) -> a >= b).toList()); + + assertEquals(asList(1, 3, 7, 5, 10), distinct( + StreamEx.of(1, 1, 3, 1, 3, 7, 1, 3, 1, 7, 3, 5, 1, 3, 5, 5, 7, 7, 7, 10, 5, 3, 7, 1)).toList()); + + assertEquals(asList("key1=1", "key2=2", "key3=3"), couples(StreamEx.of("key1", 1, "key2", 2, "key3", 3), + (k, v) -> k + "=" + v).toList()); + + assertEquals(asList("key1=1", "1=key2", "key2=2", "2=key3", "key3=3"), pairs( + StreamEx.of("key1", 1, "key2", 2, "key3", 3), (k, v) -> k + "=" + v).toList()); + + assertEquals(asList("1. Foo", "2. Bar", "3. Baz"), withIndices(StreamEx.of("Foo", "Bar", "Baz"), + (idx, e) -> (idx + 1) + ". " + e).toList()); + + assertEquals(asList(1, 2, 3, 4, 10), appendSum(StreamEx.of(1, 2, 3, 4)).toList()); + assertFalse(appendSum(StreamEx.of(1, 2, 3, 4)).has(11)); + + assertEquals(asList(0, 3, 6, 9, 12, 15, 18, 0, 4, 8, 12, 16), twoFilters(IntStreamEx.range(20).boxed(), + x -> x % 3 == 0, x -> x % 4 == 0).toList()); + + assertEquals(asList(5, 10, 1, 6, 7), skipLast(Stream.of(5, 10, 1, 6, 7, 15, -1, 10), 3).toList()); + assertEquals(asList(0, 3, 6, 9, 12, 15, 18), every3(IntStreamEx.range(20).boxed()).toList()); + + //noinspection RedundantTypeArguments -- necessary for Javac 8u92 + assertEquals(asList(0, 1, 2, 3, 3), + StreamEx.of(0, 1, 4, 2, 10, 3, 5, 10, 3, 15).chain(limitSorted(Comparator.naturalOrder(), 5)).toList()); + + assertEquals(asList(1, 3, 7, 9, 2, 4, 11, 17, 5, 10), + StreamEx.of(1, 3, 5, 7, 9, 2, 4, 10, 11, 17).chain(moveToEnd(x -> x % 5 == 0)).toList()); + assertEquals(asList(2, 4, 8, 10, 3, 5, 12, 18, 5, 10), + StreamEx.of(1, 3, 5, 7, 9, 2, 4, 10, 11, 17).chain(moveToEndOrMap(x -> x % 5 == 0, x -> x + 1)).toList()); + assertEquals(asList(11, 21, 41, 51, 30), + StreamEx.of(10, 20, 30, 40, 50).chain(moveToEndOrMap(x -> x == 30, x -> x + 1)).toList()); + } + + @Test + public void testHeadTailTCO() { + assertTrue(couples(IntStreamEx.range(20000).boxed(), (a, b) -> b - a).allMatch(x -> x == 1)); + assertTrue(pairs(IntStreamEx.range(20000).boxed(), (a, b) -> b - a).allMatch(x -> x == 1)); + // 20001+20002+...+40000 + assertEquals(600010000, limit(skip(StreamEx.iterate(1, x -> x + 1), 20000), 20000).mapToInt(Integer::intValue) + .sum()); + // 1+3+5+...+39999 + assertEquals(400000000, limit(every(StreamEx.iterate(1, x -> x + 1), 2), 20000).mapToInt(Integer::intValue) + .sum()); + assertEquals(400000000, limit(filter(StreamEx.iterate(1, x -> x + 1), x -> x % 2 != 0), 20000).mapToInt( + Integer::intValue).sum()); + // 1+2+...+10000 + assertEquals(50005000, (int) limit(scanLeft(StreamEx.iterate(1, x -> x + 1), Integer::sum), 10000).reduce( + (a, b) -> b).get()); + assertEquals(50005000, (int) limit(flatMap(StreamEx.iterate(1, x -> x + 3), (Integer x) -> StreamEx.of(x, x + 1, x + 2)), + 10000).reduce(Integer::sum).get()); + assertEquals(asList(50005000), skip( + appendReduction(IntStreamEx.rangeClosed(1, 10000).boxed(), 0, Integer::sum), 10000).toList()); + assertEquals(499501, mapFirst(IntStreamEx.range(1000).boxed(), x -> x + 1).mapToInt(x -> x).sum()); + AtomicInteger sum = new AtomicInteger(); + assertEquals(10000, peek(IntStreamEx.rangeClosed(1, 10000).boxed(), sum::addAndGet).count()); + assertEquals(50005000, sum.get()); + + + assertEquals(400020000, (int) limit(map(StreamEx.iterate(1, x -> x + 1), x -> x * 2), 20000).reduce( + Integer::sum).get()); + + assertEquals(19999, takeWhile(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).count()); + assertTrue(takeWhile(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).has(19999)); + assertEquals(20000, takeWhileClosed(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).count()); + assertTrue(takeWhileClosed(StreamEx.iterate(1, x -> x + 1), x -> x < 20000).has(20000)); + assertEquals(IntStreamEx.range(20000, 40000).boxed().toList(), dropWhile(IntStreamEx.range(40000).boxed(), + i -> i != 20000).toList()); + assertEquals(5000, batches(IntStreamEx.range(20000).boxed(), 4).count()); + assertEquals(4, batches(IntStreamEx.range(20000).boxed(), 5000).count()); + assertEquals(19997, sliding(IntStreamEx.range(20000).mapToObj(Collections::singletonList), 4).count()); + assertEquals(IntStreamEx.range(40000).boxed().toList(), dominators(IntStreamEx.range(40000).boxed(), + (a, b) -> a >= b).toList()); + assertEquals(15, dominators(IntStreamEx.of(new Random(1)).boxed(), (a, b) -> a >= b).takeWhile( + x -> x < Integer.MAX_VALUE - 100000).count()); + + assertEquals(IntStreamEx.of(new Random(1), 10000).boxed().sorted().toList(), sorted( + IntStreamEx.of(new Random(1), 10000).boxed()).toList()); + + assertEquals(10000, withIndices(IntStreamEx.of(new Random(1), 10000).boxed(), (idx, e) -> idx + ": " + e) + .count()); + + assertEquals(10000, limit(distinctTSO(IntStreamEx.of(new Random(1)).boxed()), 10000).toSet().size()); + assertEquals(IntStreamEx.range(10000).boxed().toList(), sorted(limit( + distinctTSO(IntStreamEx.of(new Random(1), 0, 10000).boxed()), 10000)).toList()); + assertEquals(IntStreamEx.rangeClosed(9999, 0, -1).boxed() + .toList(), reverseTSO(IntStreamEx.range(10000).boxed()).toList()); + assertEquals(IntStreamEx.range(10000).append(IntStreamEx.rangeClosed(9999, 0, -1)).boxed().toList(), + mirrorTSO(IntStreamEx.range(10000).boxed()).toList()); + } + + @Test + public void testHeadTailClose() { + AtomicBoolean origClosed = new AtomicBoolean(); + AtomicBoolean internalClosed = new AtomicBoolean(); + AtomicBoolean finalClosed = new AtomicBoolean(); + StreamEx res = StreamEx.of(1, 2, 3).onClose(() -> origClosed.set(true)).headTail( + (head, stream) -> stream.onClose(() -> internalClosed.set(true)).map(x -> x + head)).onClose( + () -> finalClosed.set(true)); + assertEquals(asList(3, 4), res.toList()); + res.close(); + assertTrue(origClosed.get()); + assertTrue(internalClosed.get()); + assertTrue(finalClosed.get()); + + res = StreamEx.empty().headTail((head, tail) -> tail); + assertEquals(0, res.count()); + res.close(); + } + + // Test simple non-recursive scenarios + @Test + public void testHeadTailSimple() { + repeat(10, i -> { + // Header mapping + String input = "name,type,value\nID,int,5\nSurname,string,Smith\nGiven name,string,John"; + List> expected = asList(EntryStream.of("name", "ID", "type", "int", "value", "5") + .toMap(), EntryStream.of("name", "Surname", "type", "string", "value", "Smith").toMap(), + EntryStream.of("name", "Given name", "type", "string", "value", "John").toMap()); + streamEx(() -> StreamEx.ofLines(new StringReader(input)), s -> assertEquals(expected, s.get().map( + str -> str.split(",")).headTail( + (header, stream) -> stream.map(row -> EntryStream.zip(header, row).toMap())).toList())); + }); + streamEx(() -> StreamEx.of("a", "b", "c", "d"), s -> assertEquals(Collections.singletonMap("a", asList("b", + "c", "d")), s.get().headTail((x, str) -> str.mapToEntry(e -> x, e -> e)).mapToEntry(Entry::getKey, + Entry::getValue).grouping())); + assertEquals(asList("b:c", "c:d"), StreamEx.of(":", "b", "c", "d").headTail( + (head, tail) -> tail.pairMap((left, right) -> left + head + right)).toList()); + assertEquals(asList("b:", "c", "d"), StreamEx.of(":", "b", "c", "d").headTail( + (head, tail) -> tail.mapFirst(first -> first + head)).toList()); + + } + + @Test + public void testSpliterator() { + Spliterator spltr = map(StreamEx.of(1, 2, 3, 4), x -> x * 2).spliterator(); + assertTrue(spltr.hasCharacteristics(Spliterator.ORDERED)); + assertEquals(4, spltr.estimateSize()); + consumeElement(spltr, 2); + assertEquals(3, spltr.estimateSize()); + consumeElement(spltr, 4); + assertEquals(2, spltr.estimateSize()); + consumeElement(spltr, 6); + assertEquals(1, spltr.estimateSize()); + consumeElement(spltr, 8); + assertFalse(spltr.tryAdvance(x -> fail("Should not be called"))); + assertEquals(0, spltr.estimateSize()); + } +} diff --git a/src/test/java/one/util/streamex/StreamExTest.java b/src/test/java/one/util/streamex/api/StreamExTest.java similarity index 98% rename from src/test/java/one/util/streamex/StreamExTest.java rename to src/test/java/one/util/streamex/api/StreamExTest.java index 532dd92c..c10ef117 100644 --- a/src/test/java/one/util/streamex/StreamExTest.java +++ b/src/test/java/one/util/streamex/api/StreamExTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015, 2019 StreamEx contributors + * Copyright 2015, 2020 StreamEx contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package one.util.streamex; +package one.util.streamex.api; import java.io.BufferedReader; import java.io.File; @@ -80,8 +80,15 @@ import org.junit.rules.TemporaryFolder; import org.junit.runners.MethodSorters; +import one.util.streamex.EntryStream; +import one.util.streamex.IntStreamEx; +import one.util.streamex.Joining; +import one.util.streamex.MoreCollectors; +import one.util.streamex.StreamEx; +import one.util.streamex.TestHelpers.Point; + import static java.util.Arrays.asList; -import static one.util.streamex.TestHelpers.assertThrows; +import static one.util.streamex.TestHelpers.assertStatementThrows; import static one.util.streamex.TestHelpers.checkIllegalStateException; import static one.util.streamex.TestHelpers.checkSpliterator; import static one.util.streamex.TestHelpers.emptySpliteratorWithExactSize; @@ -96,6 +103,7 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -131,9 +139,6 @@ public void testCreate() { assertEquals(asList("a", "a", "a", "a"), StreamEx.constant("a", 4).toList()); assertEquals(asList("c", "d", "e"), StreamEx.of("abcdef".split(""), 2, 5).toList()); - StreamEx stream = StreamEx.of("foo", "bar"); - assertSame(stream.stream(), StreamEx.of(stream).stream()); - assertEquals(asList("a1", "b2", "c3"), StreamEx.zip(asList("a", "b", "c"), asList(1, 2, 3), (s, i) -> s + i) .toList()); assertEquals(asList("a1", "b2", "c3"), StreamEx.zip(new String[]{"a", "b", "c"}, new Integer[]{1, 2, 3}, ( @@ -817,19 +822,6 @@ private static > Optional firstMisplaced(Coll return StreamEx.of(c).parallel().pairMap((a, b) -> a.compareTo(b) > 0 ? a : null).nonNull().findFirst(); } - static class Point { - final double x, y; - - Point(double x, double y) { - this.x = x; - this.y = y; - } - - double distance(Point o) { - return Math.sqrt((x - o.x) * (x - o.x) + (y - o.y) * (y - o.y)); - } - } - @Test public void testPairMap() { assertEquals(0, StreamEx.empty().pairMap(String::concat).count()); @@ -1436,8 +1428,8 @@ public void testRunLenghts() { assertNotEquals(new Object(), entry); assertEquals(entry, new AbstractMap.SimpleImmutableEntry<>(1, 1L)); - assertThrows(UnsupportedOperationException.class, () -> - StreamEx.of("1", "1", "1").runLengths().forEach(e -> e.setValue(5L))); + assertThrows(UnsupportedOperationException.class, + () -> StreamEx.of("1", "1", "1").runLengths().forEach(e -> e.setValue(5L))); } @SuppressWarnings("SimplifiableAssertion") @@ -1624,11 +1616,6 @@ public void testDropWhile() { Optional opt5 = s.get().dropWhile(x -> x.length() > 5).findFirst(); assertEquals(Optional.of("aaa"), opt5); }); - - // Test that in JDK9 operation is propagated to JDK dropWhile method. - boolean hasDropWhile = VerSpec.VER_SPEC.getClass().getSimpleName().equals("Java9Specific"); - Spliterator spliterator = StreamEx.of("aaa", "b", "cccc").dropWhile(x -> x.length() > 1).spliterator(); - assertEquals(hasDropWhile, !spliterator.getClass().getSimpleName().equals("TDOfRef")); } @Test @@ -1885,7 +1872,7 @@ public void testSplit() { streamEx(() -> StreamEx.split("ab.cd...", "\\w"), s -> assertEquals("||.||...", s.get().joining("|"))); streamEx(() -> StreamEx.split("ab.cd...", "\\W"), s -> assertEquals("ab|cd", s.get().joining("|"))); streamEx(() -> StreamEx.split("ab|cd|e", "\\|"), s -> assertEquals("ab,cd,e", s.get().joining(","))); - assertEquals(CharSpliterator.class, StreamEx.split("a#a", "\\#").spliterator().getClass()); + assertThrows(PatternSyntaxException.class, () -> StreamEx.split("a", "\\0")); asList('9', 'A', 'Z', 'z').forEach(ch -> assertEquals(asList("a" + ch + "a"), StreamEx.split("a" + ch + "a", "\\" + ch).toList())); @@ -2158,9 +2145,9 @@ public void testIntoArrayListEnsureCapacityOptimization() { StreamEx.of(asList(1)).into(collection); int maxAvailableSize = Integer.MAX_VALUE - collection.size(); assertThrows(IllegalArgumentException.class, - () -> StreamEx.of(emptySpliteratorWithExactSize(-2)).into(collection)); - assertThrows(OutOfMemoryError.class, - () -> StreamEx.of(emptySpliteratorWithExactSize(Long.MAX_VALUE)).into(collection)); + () -> StreamEx.of(emptySpliteratorWithExactSize(-2)).into(collection)); + assertThrows(OutOfMemoryError.class, + () -> StreamEx.of(emptySpliteratorWithExactSize(Long.MAX_VALUE)).into(collection)); StreamEx.of(emptySpliteratorWithExactSize(maxAvailableSize + 1)).into(collection); StreamEx.of(emptySpliteratorWithExactSize(maxAvailableSize)).into(collection); assertEquals(Integer.MAX_VALUE, list.ensuredCapacity); diff --git a/wiki/CHANGES.md b/wiki/CHANGES.md index ab823dfb..3c22ca50 100644 --- a/wiki/CHANGES.md +++ b/wiki/CHANGES.md @@ -2,14 +2,16 @@ Check also [MIGRATION.md](MIGRATION.md) for possible compatibility problems. +### 0.7.4 +* [#091] Changed: API tests moved to the separate package. + ### 0.7.3 -* [#028] Added: `StreamEx.toCollectionAndThen` +* [#028] Added: `StreamEx.toCollectionAndThen`. * [#039] Added: `AbstractStreamEx.reducingWithZero` and `MoreCollectors.reducingWithZero`. -* [#043] Added: Add `MoreCollectors.entriesToMap` and `MoreCollectors.entriesToCustomMap` methods accepting Entry. +* [#043] Added: `MoreCollectors.entriesToMap` and `MoreCollectors.entriesToCustomMap` methods accepting Entry. * [#093] Optimized: parallel performance of unordered primitive streams and for short-circuiting streams is improved. * [#219] Changed: MoreCollectors now reject eagerly null parameters where possible; `MoreCollectors.last` throws NPE if last stream element is null. -* [#221] Fixed: `rangeClosed(x, x, step)` returned empty stream instead of stream of `x` if step absolute value is - bigger than one. +* [#221] Fixed: `rangeClosed(x, x, step)` returned empty stream instead of stream of `x` if step absolute value is bigger than one. * [#226] Added: `EntryStream.pairMap` (pairMap pulled up to AbstractStreamEx). * [#229] Fixed: Some non-canonical nans were sorted incorrectly with `Double.reverseSorted()`.