/* __ __ __ __ __ ___ * \ \ / / \ \ / / __/ * \ \/ / /\ \ \/ / / * \____/__/ \__\____/__/.ɪᴏ * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ */ package io.vavr.collection; import io.vavr.Tuple; import org.junit.Test; import java.math.BigDecimal; import java.util.*; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; import static java.util.Comparator.comparingInt; import static java.util.stream.Collectors.toList; import static io.vavr.TestComparators.toStringComparator; public class PriorityQueueTest extends AbstractTraversableTest { private final io.vavr.collection.List<Integer> values = io.vavr.collection.List.of(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5, 0, 2, 8, 8, 4, 1, 9, 7, 1, 6, 9, 3, 9, 9, 3, 7, 5, 1, 0); @Override protected <T> Collector<T, ArrayList<T>, PriorityQueue<T>> collector() { return PriorityQueue.collector(); } @Override protected <T> PriorityQueue<T> empty() { return PriorityQueue.empty(Comparators.naturalComparator()); } @Override protected <T> PriorityQueue<T> of(T element) { return PriorityQueue.ofAll(Comparators.naturalComparator(), io.vavr.collection.List.of(element)); } @Override @SuppressWarnings("unchecked") protected final <T> PriorityQueue<T> of(T... elements) { return PriorityQueue.ofAll(Comparators.naturalComparator(), io.vavr.collection.List.of(elements)); } @Override protected <T> PriorityQueue<T> ofAll(Iterable<? extends T> elements) { return PriorityQueue.ofAll(Comparators.naturalComparator(), elements); } @Override protected <T extends Comparable<? super T>> Traversable<T> ofJavaStream(java.util.stream.Stream<? extends T> javaStream) { return PriorityQueue.ofAll(Comparators.naturalComparator(), javaStream); } @Override protected PriorityQueue<Boolean> ofAll(boolean... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected PriorityQueue<Byte> ofAll(byte... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected PriorityQueue<Character> ofAll(char... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected PriorityQueue<Double> ofAll(double... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected PriorityQueue<Float> ofAll(float... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected PriorityQueue<Integer> ofAll(int... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected PriorityQueue<Long> ofAll(long... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected PriorityQueue<Short> ofAll(short... elements) { return PriorityQueue.ofAll(io.vavr.collection.List.ofAll(elements)); } @Override protected <T> PriorityQueue<T> tabulate(int n, Function<? super Integer, ? extends T> f) { return PriorityQueue.tabulate(n, f); } @Override protected <T> PriorityQueue<T> fill(int n, Supplier<? extends T> s) { return PriorityQueue.fill(n, s); } @Override protected boolean useIsEqualToInsteadOfIsSameAs() { return true; } @Override protected int getPeekNonNilPerformingAnAction() { return 1; } @Override protected boolean emptyShouldBeSingleton() { return false; } private static Comparator<Integer> composedComparator() { final Comparator<Integer> bitCountComparator = comparingInt(Integer::bitCount); return bitCountComparator.thenComparing(Comparators.naturalComparator()); } @Test @Override public void shouldScanLeftWithNonComparable() { // The resulting type would need a comparator } @Test @Override public void shouldScanRightWithNonComparable() { // The resulting type would need a comparator } @Override public void shouldPreserveSingletonInstanceOnDeserialization() { // The empty PriorityQueue encapsulates a comparator and therefore cannot be a singleton } @Test public void shouldScanWithNonComparable() { // makes no sense because sorted sets contain ordered elements } @Test public void shouldCreateFromStream() { final PriorityQueue<Integer> source = PriorityQueue.ofAll(values.toJavaStream()); assertThat(source).isEqualTo(ofAll(values)); } @Test public void shouldReturnOrdered() { final PriorityQueue<Integer> source = of(3, 1, 4); assertThat(source.isOrdered()).isTrue(); } // -- static narrow @Test public void shouldNarrowPriorityQueue() { final PriorityQueue<Double> doubles = PriorityQueue.of(toStringComparator(), 1.0d); final PriorityQueue<Number> numbers = PriorityQueue.narrow(doubles); final int actual = numbers.enqueue(new BigDecimal("2.0")).sum().intValue(); assertThat(actual).isEqualTo(3); } // -- toList @Test public void toListIsSortedAccordingToComparator() { final Comparator<Integer> comparator = composedComparator(); final PriorityQueue<Integer> queue = PriorityQueue.ofAll(comparator, values); assertThat(queue.toList()).isEqualTo(values.sorted(comparator)); } // -- merge @Test public void shouldMergeTwoPriorityQueues() { final PriorityQueue<Integer> source = of(3, 1, 4, 1, 5); final PriorityQueue<Integer> target = of(9, 2, 6, 5, 3); assertThat(source.merge(target)).isEqualTo(of(3, 1, 4, 1, 5, 9, 2, 6, 5, 3)); assertThat(PriorityQueue.of(3).merge(PriorityQueue.of(1))).isEqualTo(of(3, 1)); } // -- distinct @Test public void shouldComputeDistinctOfNonEmptyTraversableUsingKeyExtractor() { final Comparator<String> comparator = comparingInt(o -> o.charAt(1)); assertThat(PriorityQueue.of(comparator, "5c", "1a", "3a", "1a", "2a", "4b", "3b").distinct().map(s -> s.substring(1))).isEqualTo(of("a", "b", "c")); } // -- removeAll @Test public void shouldRemoveAllElements() { assertThat(of(3, 1, 4, 1, 5, 9, 2, 6).removeAll(of(1, 9, 1, 2))).isEqualTo(of(3, 4, 5, 6)); } // -- enqueueAll @Test public void shouldEnqueueAllElements() { assertThat(of(3, 1, 4).enqueueAll(of(1, 5, 9, 2))).isEqualTo(of(3, 1, 4, 1, 5, 9, 2)); } // -- peek @Test(expected = NoSuchElementException.class) public void shouldFailPeekOfEmpty() { empty().peek(); } // -- dequeue @Test public void shouldDeque() { assertThat(of(3, 1, 4, 1, 5).dequeue()).isEqualTo(Tuple.of(1, of(3, 4, 1, 5))); } @Test(expected = NoSuchElementException.class) public void shouldFailDequeueOfEmpty() { empty().dequeue(); } // -- toPriorityQueue @Test public void shouldKeepInstanceOfPriorityQueue() { final PriorityQueue<Integer> queue = PriorityQueue.of(1, 3, 2); assertThat(queue.toPriorityQueue()).isSameAs(queue); } // -- property based tests @Test public void shouldBehaveExactlyLikeAnotherPriorityQueue() { for (int i = 0; i < 10; i++) { final Random random = getRandom(-1); final java.util.PriorityQueue<Integer> mutablePriorityQueue = new java.util.PriorityQueue<>(); PriorityQueue<Integer> functionalPriorityQueue = PriorityQueue.empty(); final int size = 100_000; for (int j = 0; j < size; j++) { /* Insert */ if (random.nextInt() % 3 == 0) { assertMinimumsAreEqual(mutablePriorityQueue, functionalPriorityQueue); final int value = random.nextInt(size) - (size / 2); mutablePriorityQueue.add(value); functionalPriorityQueue = functionalPriorityQueue.enqueue(value); } assertMinimumsAreEqual(mutablePriorityQueue, functionalPriorityQueue); /* Delete */ if (random.nextInt() % 5 == 0) { if (!mutablePriorityQueue.isEmpty()) { mutablePriorityQueue.poll(); } if (!functionalPriorityQueue.isEmpty()) { functionalPriorityQueue = functionalPriorityQueue.tail(); } assertMinimumsAreEqual(mutablePriorityQueue, functionalPriorityQueue); } } final Collection<Integer> oldValues = mutablePriorityQueue.stream().sorted().collect(toList()); final Collection<Integer> newValues = functionalPriorityQueue.toJavaList(); assertThat(oldValues).isEqualTo(newValues); } } // -- spliterator @Test public void shouldHaveSortedSpliterator() { assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.SORTED)).isTrue(); } @Test public void shouldHaveOrderedSpliterator() { assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)).isTrue(); } @Test public void shouldHaveSizedSpliterator() { assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED)).isTrue(); } @Test public void shouldNotHaveDistinctSpliterator() { assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.DISTINCT)).isFalse(); } @Test public void shouldReturnSizeWhenSpliterator() { assertThat(of(1, 2, 3).spliterator().getExactSizeIfKnown()).isEqualTo(3); } // -- isSequential() @Test public void shouldReturnFalseWhenIsSequentialCalled() { assertThat(of(1, 2, 3).isSequential()).isFalse(); } private void assertMinimumsAreEqual(java.util.PriorityQueue<Integer> oldQueue, PriorityQueue<Integer> newQueue) { assertThat(oldQueue.isEmpty()).isEqualTo(newQueue.isEmpty()); if (!newQueue.isEmpty()) { assertThat(oldQueue.peek()).isEqualTo(newQueue.head()); } } }