/* * Copyright 2015 Goldman Sachs. * * 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 com.gs.collections.impl.factory; import java.lang.reflect.Field; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.TreeSet; import com.gs.collections.api.bag.MutableBag; import com.gs.collections.api.block.function.Function2; import com.gs.collections.api.block.procedure.Procedure2; import com.gs.collections.api.factory.set.FixedSizeSetFactory; import com.gs.collections.api.factory.set.ImmutableSetFactory; import com.gs.collections.api.factory.set.MutableSetFactory; import com.gs.collections.api.set.FixedSizeSet; import com.gs.collections.api.set.ImmutableSet; import com.gs.collections.api.set.MutableSet; import com.gs.collections.api.tuple.Pair; import com.gs.collections.impl.bag.mutable.HashBag; import com.gs.collections.impl.list.Interval; import com.gs.collections.impl.list.mutable.FastList; import com.gs.collections.impl.set.mutable.UnifiedSet; import com.gs.collections.impl.test.Verify; import com.gs.collections.impl.test.domain.Key; import com.gs.collections.impl.tuple.Tuples; import org.junit.Assert; import org.junit.Test; import static com.gs.collections.impl.factory.Iterables.*; public class SetsTest { private final List<UnifiedSet<String>> uniqueSets = FastList.newListWith(this.newUnsortedSet("Tom", "Dick", "Harry", null), this.newUnsortedSet("Jane", "Sarah", "Mary"), this.newUnsortedSet("Fido", "Spike", "Spuds")); private final List<UnifiedSet<String>> overlappingSets = FastList.newListWith(this.newUnsortedSet("Tom", "Dick", "Harry"), this.newUnsortedSet("Larry", "Tom", "Dick"), this.newUnsortedSet("Dick", "Larry", "Paul", null)); private final List<UnifiedSet<String>> identicalSets = FastList.newListWith(this.newUnsortedSet("Tom", null, "Dick", "Harry"), this.newUnsortedSet(null, "Harry", "Tom", "Dick"), this.newUnsortedSet("Dick", "Harry", "Tom", null)); private final List<TreeSet<String>> uniqueSortedSets = FastList.newListWith(this.newSortedSet("Tom", "Dick", "Harry"), this.newSortedSet("Jane", "Sarah", "Mary"), this.newSortedSet("Fido", "Spike", "Spuds")); private final List<TreeSet<String>> overlappingSortedSets = FastList.newListWith(this.newSortedSet("Tom", "Dick", "Harry"), this.newSortedSet("Larry", "Tom", "Dick"), this.newSortedSet("Dick", "Larry", "Paul")); private final List<TreeSet<String>> identicalSortedSets = FastList.newListWith(this.newSortedSet("Tom", "Dick", "Harry"), this.newSortedSet("Harry", "Tom", "Dick"), this.newSortedSet("Dick", "Harry", "Tom")); private final List<TreeSet<String>> uniqueReverseSortedSets = FastList.newListWith(this.newReverseSortedSet("Tom", "Dick", "Harry"), this.newReverseSortedSet("Jane", "Sarah", "Mary"), this.newReverseSortedSet("Fido", "Spike", "Spuds")); private final List<TreeSet<String>> overlappingReverseSortedSets = FastList.newListWith(this.newReverseSortedSet("Tom", "Dick", "Harry"), this.newReverseSortedSet("Larry", "Tom", "Dick"), this.newReverseSortedSet("Dick", "Larry", "Paul")); private final List<TreeSet<String>> identicalReverseSortedSets = FastList.newListWith(this.newReverseSortedSet("Tom", "Dick", "Harry"), this.newReverseSortedSet("Harry", "Tom", "Dick"), this.newReverseSortedSet("Dick", "Harry", "Tom")); private <E> UnifiedSet<E> newUnsortedSet(E... elements) { return UnifiedSet.newSetWith(elements); } private <E> TreeSet<E> newSortedSet(E... elements) { return new TreeSet<>(UnifiedSet.newSetWith(elements)); } private <E> TreeSet<E> newReverseSortedSet(E... elements) { TreeSet<E> set = new TreeSet<>(Collections.reverseOrder()); set.addAll(UnifiedSet.newSetWith(elements)); return set; } @Test public void unionUnique() { this.assertUnionProperties( this.<String>containsExactlyProcedure(), Verify::assertSetsEqual, this.uniqueSets.get(0), this.uniqueSets.get(1), this.uniqueSets.get(2), "Tom", "Dick", "Harry", "Jane", "Sarah", "Mary", "Fido", "Spike", "Spuds", null); } @Test public void unionUniqueSorted() { this.assertUnionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.uniqueSortedSets.get(0), this.uniqueSortedSets.get(1), this.uniqueSortedSets.get(2), "Dick", "Fido", "Harry", "Jane", "Mary", "Sarah", "Spike", "Spuds", "Tom"); //TODO: union operations on sorted sets will not pass identity test until SortedSetAdapter is implemented // this.assertUnionProperties(this.<String>containsExactlyInOrderBlock(), // this.<String>setsEqualAndSortedBlock(), // this.uniqueReverseSortedSets.get(0), // this.uniqueReverseSortedSets.get(1), // this.uniqueReverseSortedSets.get(2), // "Tom", "Spuds", "Spike", "Sarah", "Mary", "Jane", "Harry", "Fido", "Dick"); } @Test public void unionOverlapping() { this.assertUnionProperties(this.<String>containsExactlyProcedure(), Verify::assertSetsEqual, this.overlappingSets.get(0), this.overlappingSets.get(1), this.overlappingSets.get(2), "Tom", "Dick", "Harry", "Larry", "Paul", null); } @Test public void unionOverlappingSorted() { this.assertUnionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.overlappingSortedSets.get(0), this.overlappingSortedSets.get(1), this.overlappingSortedSets.get(2), "Dick", "Harry", "Larry", "Paul", "Tom"); //TODO: union operations on sorted sets will not pass identity test until SortedSetAdapter is implemented // this.assertUnionProperties(this.<String>containsExactlyInOrderBlock(), // this.<String>setsEqualAndSortedBlock(), // this.overlappingReverseSortedSets.get(0), // this.overlappingReverseSortedSets.get(1), // this.overlappingReverseSortedSets.get(2), // "Tom", "Paul", "Larry", "Harry", "Dick"); } @Test public void unionIdentical() { this.assertUnionProperties(this.<String>containsExactlyProcedure(), Verify::assertSetsEqual, this.identicalSets.get(0), this.identicalSets.get(1), this.identicalSets.get(2), "Tom", "Dick", "Harry", null); } @Test public void unionIdenticalSorted() { this.assertUnionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.identicalSortedSets.get(0), this.identicalSortedSets.get(1), this.identicalSortedSets.get(2), "Dick", "Harry", "Tom"); //TODO: union operations on sorted sets will not pass identity test until SortedSetAdapter is implemented // this.assertUnionProperties(this.<String>containsExactlyInOrderBlock(), // this.<String>setsEqualAndSortedBlock(), // this.identicalReverseSortedSets.get(0), // this.identicalReverseSortedSets.get(1), // this.identicalReverseSortedSets.get(2), // "Tom", "Harry", "Dick"); } @Test public void unionAllUnique() { MutableSet<String> names = Sets.unionAll(this.uniqueSets.get(0), this.uniqueSets.get(1), this.uniqueSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith("Tom", "Dick", "Harry", "Jane", "Sarah", "Mary", "Fido", "Spike", "Spuds", null), names); } @Test public void unionAllOverlapping() { MutableSet<String> names = Sets.unionAll(this.overlappingSets.get(0), this.overlappingSets.get(1), this.overlappingSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith("Tom", "Dick", "Harry", "Larry", "Paul", null), names); } @Test public void unionAllIdentical() { MutableSet<String> names = Sets.unionAll(this.identicalSets.get(0), this.identicalSets.get(1), this.identicalSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith("Tom", "Dick", "Harry", null), names); } @Test public void intersectUnique() { this.assertIntersectionProperties(this.<String>containsExactlyProcedure(), Verify::assertSetsEqual, this.uniqueSets.get(0), this.uniqueSets.get(1), this.uniqueSets.get(2)); } @Test public void intersectUniqueSorted() { this.assertIntersectionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.uniqueSortedSets.get(0), this.uniqueSortedSets.get(1), this.uniqueSortedSets.get(2)); this.assertIntersectionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.uniqueReverseSortedSets.get(0), this.uniqueReverseSortedSets.get(1), this.uniqueReverseSortedSets.get(2)); } @Test public void intersectOverlapping() { this.assertIntersectionProperties(this.<String>containsExactlyProcedure(), Verify::assertSetsEqual, this.overlappingSets.get(0), this.overlappingSets.get(1), this.overlappingSets.get(2), "Dick"); } @Test public void intersectOverlappingSorted() { this.assertIntersectionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.overlappingSortedSets.get(0), this.overlappingSortedSets.get(1), this.overlappingSortedSets.get(2), "Dick"); this.assertIntersectionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.overlappingReverseSortedSets.get(0), this.overlappingReverseSortedSets.get(1), this.overlappingReverseSortedSets.get(2), "Dick"); } @Test public void intersectIdentical() { this.assertIntersectionProperties(this.<String>containsExactlyProcedure(), Verify::assertSetsEqual, this.identicalSets.get(0), this.identicalSets.get(1), this.identicalSets.get(2), "Tom", "Dick", "Harry", null); } @Test public void intersectIdenticalSorted() { this.assertIntersectionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.identicalSortedSets.get(0), this.identicalSortedSets.get(1), this.identicalSortedSets.get(2), "Dick", "Harry", "Tom"); this.assertIntersectionProperties(this.<String>containsExactlyInOrderProcedure(), this::assertSetsEqualAndSorted, this.identicalReverseSortedSets.get(0), this.identicalReverseSortedSets.get(1), this.identicalReverseSortedSets.get(2), "Tom", "Harry", "Dick"); } @Test public void intersectAllUnique() { MutableSet<String> names = Sets.intersectAll(this.uniqueSets.get(0), this.uniqueSets.get(1), this.uniqueSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith(), names); } @Test public void intersectAllOverlapping() { MutableSet<String> names = Sets.intersectAll(this.overlappingSets.get(0), this.overlappingSets.get(1), this.overlappingSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith("Dick"), names); } @Test public void intersectAllIdentical() { MutableSet<String> names = Sets.intersectAll(this.identicalSets.get(0), this.identicalSets.get(1), this.identicalSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith("Tom", "Dick", "Harry", null), names); } @Test public void differenceUnique() { this.assertForwardAndBackward(this.<String>containsExactlyProcedure(), Sets::difference, this.uniqueSets.get(0), this.uniqueSets.get(1), new String[]{"Tom", "Dick", "Harry", null}, new String[]{"Jane", "Sarah", "Mary"}); } @Test public void differenceUniqueSorted() { this.assertForwardAndBackward(this.<String>containsExactlyInOrderProcedure(), Sets::difference, this.uniqueSortedSets.get(0), this.uniqueSortedSets.get(1), new String[]{"Dick", "Harry", "Tom"}, new String[]{"Jane", "Mary", "Sarah"}); } @Test public void differenceOverlapping() { this.assertForwardAndBackward(this.<String>containsExactlyProcedure(), Sets::difference, this.overlappingSets.get(0), this.overlappingSets.get(1), new String[]{"Harry"}, new String[]{"Larry"}); } @Test public void differenceOverlappingSorted() { this.assertForwardAndBackward(this.<String>containsExactlyInOrderProcedure(), Sets::difference, this.overlappingSortedSets.get(0), this.overlappingSortedSets.get(1), new String[]{"Harry"}, new String[]{"Larry"}); } @Test public void differenceIdentical() { this.assertForwardAndBackward(this.<String>containsExactlyProcedure(), Sets::difference, this.identicalSets.get(0), this.identicalSets.get(1), new String[]{}, new String[]{}); } @Test public void differenceIdenticalSorted() { this.assertForwardAndBackward(this.<String>containsExactlyInOrderProcedure(), Sets::difference, this.identicalSortedSets.get(0), this.identicalSortedSets.get(1), new String[]{}, new String[]{}); } @Test public void differenceAllUnique() { MutableSet<String> names = Sets.differenceAll(this.uniqueSets.get(0), this.uniqueSets.get(1), this.uniqueSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith("Harry", "Tom", "Dick", null), names); Verify.assertSetsEqual( names, Sets.difference(Sets.difference(this.uniqueSets.get(0), this.uniqueSets.get(1)), this.uniqueSets.get(2))); } @Test public void differenceAllOverlapping() { MutableSet<String> names = Sets.differenceAll(this.overlappingSets.get(0), this.overlappingSets.get(1), this.overlappingSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith("Harry"), names); Verify.assertSetsEqual( names, Sets.difference(Sets.difference(this.overlappingSets.get(0), this.overlappingSets.get(1)), this.overlappingSets.get(2))); } @Test public void differenceAllIdentical() { MutableSet<String> names = Sets.differenceAll(this.identicalSets.get(0), this.identicalSets.get(1), this.identicalSets.get(2)); Assert.assertEquals(UnifiedSet.newSetWith(), names); Verify.assertSetsEqual( names, Sets.difference(Sets.difference(this.identicalSets.get(0), this.identicalSets.get(1)), this.identicalSets.get(2))); } @Test public void symmetricDifferenceUnique() { this.assertForwardAndBackward(this.<String>containsExactlyProcedure(), Sets::symmetricDifference, this.uniqueSets.get(0), this.uniqueSets.get(1), new String[]{"Tom", "Dick", "Harry", "Jane", "Mary", "Sarah", null}, new String[]{"Tom", "Dick", "Harry", "Jane", "Mary", "Sarah", null}); } @Test public void symmetricDifferenceUniqueSorted() { this.assertForwardAndBackward(this.<String>containsExactlyInOrderProcedure(), Sets::symmetricDifference, this.uniqueSortedSets.get(0), this.uniqueSortedSets.get(1), new String[]{"Dick", "Harry", "Jane", "Mary", "Sarah", "Tom"}, new String[]{"Dick", "Harry", "Jane", "Mary", "Sarah", "Tom"}); } @Test public void symmetricDifferenceOverlapping() { this.assertForwardAndBackward(this.<String>containsExactlyProcedure(), Sets::symmetricDifference, this.overlappingSets.get(0), this.overlappingSets.get(1), new String[]{"Larry", "Harry"}, new String[]{"Larry", "Harry"}); } @Test public void symmetricDifferenceOverlappingSorted() { this.assertForwardAndBackward(this.<String>containsExactlyInOrderProcedure(), Sets::symmetricDifference, this.overlappingSortedSets.get(0), this.overlappingSortedSets.get(1), new String[]{"Harry", "Larry"}, new String[]{"Harry", "Larry"}); } @Test public void symmetricDifferenceIdentical() { this.assertForwardAndBackward(this.<String>containsExactlyProcedure(), Sets::symmetricDifference, this.identicalSets.get(0), this.identicalSets.get(1), new String[]{}, new String[]{}); } @Test public void symmetricDifferenceIdenticalSorted() { this.assertForwardAndBackward(this.<String>containsExactlyInOrderProcedure(), Sets::symmetricDifference, this.identicalSortedSets.get(0), this.identicalSortedSets.get(1), new String[]{}, new String[]{}); } @Test public void subsetEmpty() { MutableSet<String> emptySet = mSet(); MutableSet<String> singletonSet = mSet("Bertha"); Assert.assertTrue(Sets.isSubsetOf(emptySet, singletonSet)); Assert.assertFalse(Sets.isSubsetOf(singletonSet, emptySet)); } @Test public void subsetNotEmpty() { MutableSet<String> singletonSet = UnifiedSet.newSetWith("Bertha"); MutableSet<String> doubletonSet = UnifiedSet.newSetWith("Bertha", "Myra"); Assert.assertTrue(Sets.isSubsetOf(singletonSet, doubletonSet)); Assert.assertFalse(Sets.isSubsetOf(doubletonSet, singletonSet)); } @Test public void subsetEqual() { MutableSet<String> setA = UnifiedSet.newSetWith("Bertha", null, "Myra"); MutableSet<String> setB = UnifiedSet.newSetWith("Myra", "Bertha", null); Assert.assertTrue(Sets.isSubsetOf(setA, setB)); Assert.assertTrue(Sets.isSubsetOf(setB, setA)); } @Test public void properSubsetEmpty() { MutableSet<String> emptySet = mSet(); MutableSet<String> singletonSet = UnifiedSet.newSetWith("Bertha"); Assert.assertTrue(Sets.isProperSubsetOf(emptySet, singletonSet)); Assert.assertFalse(Sets.isProperSubsetOf(singletonSet, emptySet)); } @Test public void properSubsetNotEmpty() { MutableSet<String> singletonSet = UnifiedSet.newSetWith("Bertha"); MutableSet<String> doubletonSet = UnifiedSet.newSetWith("Bertha", "Myra"); Assert.assertTrue(Sets.isProperSubsetOf(singletonSet, doubletonSet)); Assert.assertFalse(Sets.isProperSubsetOf(doubletonSet, singletonSet)); } @Test public void properSubsetEqual() { MutableSet<String> setA = UnifiedSet.newSetWith("Bertha", null, "Myra"); MutableSet<String> setB = UnifiedSet.newSetWith("Myra", "Bertha", null); Assert.assertFalse(Sets.isProperSubsetOf(setA, setB)); Assert.assertFalse(Sets.isProperSubsetOf(setB, setA)); } private <E> void assertUnionProperties( Procedure2<Set<E>, E[]> setContainsProcedure, Procedure2<Set<E>, Set<E>> setsEqualProcedure, Set<E> setA, Set<E> setB, Set<E> setC, E... elements) { Function2<Set<E>, Set<E>, Set<E>> union = Sets::union; Function2<Set<E>, Set<E>, Set<E>> intersect = Sets::intersect; this.assertCommutativeProperty(setContainsProcedure, union, setA, setB, setC, elements); this.assertAssociativeProperty(setContainsProcedure, union, setA, setB, setC, elements); this.assertDistributiveProperty(setsEqualProcedure, union, intersect, setA, setB, setC); this.assertIdentityProperty(setContainsProcedure, union, setA, setB, setC, elements); } private <E> void assertIntersectionProperties( Procedure2<Set<E>, E[]> setContainsProcedure, Procedure2<Set<E>, Set<E>> setsEqualProcedure, Set<E> setA, Set<E> setB, Set<E> setC, E... elements) { Function2<Set<E>, Set<E>, Set<E>> intersect = Sets::intersect; Function2<Set<E>, Set<E>, Set<E>> union = Sets::union; this.assertCommutativeProperty(setContainsProcedure, intersect, setA, setB, setC, elements); this.assertAssociativeProperty(setContainsProcedure, intersect, setA, setB, setC, elements); this.assertDistributiveProperty(setsEqualProcedure, intersect, union, setA, setB, setC); } private <E> void assertCommutativeProperty( Procedure2<Set<E>, E[]> setContainsProcedure, Function2<Set<E>, Set<E>, Set<E>> function, Set<E> setA, Set<E> setB, Set<E> setC, E... elements) { Set<E> aXbXc = function.value(function.value(setA, setB), setC); Set<E> aXcXb = function.value(function.value(setA, setC), setB); Set<E> bXaXc = function.value(function.value(setB, setA), setC); Set<E> bXcXa = function.value(function.value(setB, setC), setA); Set<E> cXaXb = function.value(function.value(setC, setA), setB); Set<E> cXbXa = function.value(function.value(setC, setB), setA); this.assertAllContainExactly(setContainsProcedure, FastList.newListWith(aXbXc, aXcXb, bXaXc, bXcXa, cXaXb, cXbXa), elements); } private <E> void assertAssociativeProperty( Procedure2<Set<E>, E[]> setContainsProcedure, Function2<Set<E>, Set<E>, Set<E>> function, Set<E> setA, Set<E> setB, Set<E> setC, E... elements) { setContainsProcedure.value(function.value(function.value(setA, setB), setC), elements); setContainsProcedure.value(function.value(setA, function.value(setB, setC)), elements); } private <E> void assertDistributiveProperty( Procedure2<Set<E>, Set<E>> setsEqualProcedure, Function2<Set<E>, Set<E>, Set<E>> function1, Function2<Set<E>, Set<E>, Set<E>> function2, Set<E> setA, Set<E> setB, Set<E> setC) { Set<E> set1 = function1.value(setA, function2.value(setB, setC)); Set<E> set2 = function2.value(function1.value(setA, setB), function1.value(setA, setC)); //TODO: setsEqual will fail on some sorted sets until SortableSetAdapter is implemented //setsEqualProcedure.value(set1, set2); } private <E> void assertIdentityProperty( Procedure2<Set<E>, E[]> setContainsProcedure, Function2<Set<E>, Set<E>, Set<E>> function, Set<E> setA, Set<E> setB, Set<E> setC, E... elements) { Set<E> aXbXc = function.value(function.value(setA, setB), setC); Set<E> empty = new TreeSet<>(); setContainsProcedure.value(function.value(aXbXc, empty), elements); setContainsProcedure.value(function.value(empty, aXbXc), elements); } private <E> void assertAllContainExactly( Procedure2<Set<E>, E[]> setContainsProcedure, Collection<Set<E>> sets, E... elements) { for (Set<E> set : sets) { setContainsProcedure.value(set, elements); } } private <E> void assertSetsEqualAndSorted(Set<E> setA, Set<E> setB) { Verify.assertSetsEqual(setA, setB); Object[] expectedItems = setB.toArray((E[]) new Object[setB.size()]); Assert.assertEquals(FastList.newListWith(expectedItems), FastList.newList(setA)); } private <E> void assertForwardAndBackward( Procedure2<Set<E>, E[]> setContainsProcedure, Function2<Set<E>, Set<E>, Set<E>> function, Set<E> setA, Set<E> setB, E[] forwardResults, E[] backwardResults) { Set<E> results1 = function.value(setA, setB); setContainsProcedure.value(results1, forwardResults); Set<E> results2 = function.value(setB, setA); setContainsProcedure.value(results2, backwardResults); } private <E> Procedure2<Set<E>, E[]> containsExactlyProcedure() { return (set, elements) -> Assert.assertEquals(UnifiedSet.newSetWith(elements), set); } private <E> Procedure2<Set<E>, E[]> containsExactlyInOrderProcedure() { return (set, elements) -> Assert.assertEquals(FastList.newListWith((Object[]) elements), FastList.newList(set)); } @Test public void immutables() { ImmutableSetFactory setFactory = Sets.immutable; Assert.assertEquals(UnifiedSet.newSet(), setFactory.of()); Verify.assertInstanceOf(ImmutableSet.class, setFactory.of()); Assert.assertEquals(UnifiedSet.newSetWith(1), setFactory.of(1)); Verify.assertInstanceOf(ImmutableSet.class, setFactory.of(1)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2), setFactory.of(1, 2)); Verify.assertInstanceOf(ImmutableSet.class, setFactory.of(1, 2)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3), setFactory.of(1, 2, 3)); Verify.assertInstanceOf(ImmutableSet.class, setFactory.of(1, 2, 3)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3, 4), setFactory.of(1, 2, 3, 4)); Verify.assertInstanceOf(ImmutableSet.class, setFactory.of(1, 2, 3, 4)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3, 4, 5), setFactory.of(1, 2, 3, 4, 5)); Verify.assertInstanceOf(ImmutableSet.class, setFactory.of(1, 2, 3, 4, 5)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3, 4, 5), setFactory.ofAll(UnifiedSet.newSetWith(1, 2, 3, 4, 5))); Verify.assertInstanceOf(ImmutableSet.class, setFactory.ofAll(UnifiedSet.newSetWith(1, 2, 3, 4, 5))); } @Test public void mutables() { MutableSetFactory setFactory = Sets.mutable; Assert.assertEquals(UnifiedSet.newSet(), setFactory.of()); Verify.assertInstanceOf(MutableSet.class, setFactory.of()); Assert.assertEquals(UnifiedSet.newSetWith(1), setFactory.of(1)); Verify.assertInstanceOf(MutableSet.class, setFactory.of(1)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2), setFactory.of(1, 2)); Verify.assertInstanceOf(MutableSet.class, setFactory.of(1, 2)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3), setFactory.of(1, 2, 3)); Verify.assertInstanceOf(MutableSet.class, setFactory.of(1, 2, 3)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3, 4), setFactory.of(1, 2, 3, 4)); Verify.assertInstanceOf(MutableSet.class, setFactory.of(1, 2, 3, 4)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3, 4, 5), setFactory.of(1, 2, 3, 4, 5)); Verify.assertInstanceOf(MutableSet.class, setFactory.of(1, 2, 3, 4, 5)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3, 4, 5), setFactory.ofAll(UnifiedSet.newSetWith(1, 2, 3, 4, 5))); Verify.assertInstanceOf(MutableSet.class, setFactory.ofAll(UnifiedSet.newSetWith(1, 2, 3, 4, 5))); } @Test public void fixedSize() { FixedSizeSetFactory setFactory = Sets.fixedSize; Assert.assertEquals(UnifiedSet.newSet(), setFactory.of()); Verify.assertInstanceOf(FixedSizeSet.class, setFactory.of()); Assert.assertEquals(UnifiedSet.newSetWith(1), setFactory.of(1)); Verify.assertInstanceOf(FixedSizeSet.class, setFactory.of(1)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2), setFactory.of(1, 2)); Verify.assertInstanceOf(FixedSizeSet.class, setFactory.of(1, 2)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3), setFactory.of(1, 2, 3)); Verify.assertInstanceOf(FixedSizeSet.class, setFactory.of(1, 2, 3)); Assert.assertEquals(UnifiedSet.newSetWith(1, 2, 3, 4), setFactory.of(1, 2, 3, 4)); Verify.assertInstanceOf(FixedSizeSet.class, setFactory.of(1, 2, 3, 4)); } @Test public void powerSet() { MutableSet<Integer> set = UnifiedSet.newSetWith(1, 2, 3); MutableSet<MutableSet<Integer>> expectedPowerSet = UnifiedSet.<MutableSet<Integer>>newSetWith( UnifiedSet.<Integer>newSet(), UnifiedSet.newSetWith(1), UnifiedSet.newSetWith(2), UnifiedSet.newSetWith(3), UnifiedSet.newSetWith(1, 2), UnifiedSet.newSetWith(1, 3), UnifiedSet.newSetWith(2, 3), UnifiedSet.newSetWith(1, 2, 3)); Assert.assertEquals(expectedPowerSet, Sets.powerSet(set)); } @Test public void powerSet_empty() { Assert.assertEquals( UnifiedSet.newSetWith(UnifiedSet.newSet()), Sets.powerSet(UnifiedSet.newSet())); } @Test public void cartesianProduct() { MutableSet<Integer> set1 = UnifiedSet.newSetWith(1, 2); MutableSet<Integer> set2 = UnifiedSet.newSetWith(2, 3, 4); MutableBag<Pair<Integer, Integer>> expectedCartesianProduct = Bags.mutable.of( Tuples.pair(1, 2), Tuples.pair(2, 2), Tuples.pair(1, 3), Tuples.pair(2, 3), Tuples.pair(1, 4), Tuples.pair(2, 4)); Assert.assertEquals(expectedCartesianProduct, Sets.cartesianProduct(set1, set2).toBag()); } @Test public void cartesianProduct_empty() { Assert.assertEquals( Bags.mutable.of(), HashBag.newBag(Sets.cartesianProduct( UnifiedSet.newSetWith(1, 2), UnifiedSet.newSet()))); } @Test public void castToSet() { Set<Object> set = Sets.immutable.of().castToSet(); Assert.assertNotNull(set); Assert.assertSame(Sets.immutable.of(), set); } @Test public void copySet() { Verify.assertInstanceOf(ImmutableSet.class, Sets.immutable.ofAll(Sets.fixedSize.of())); MutableSet<Integer> set = Sets.fixedSize.of(1); ImmutableSet<Integer> immutableSet = set.toImmutable(); Verify.assertInstanceOf(ImmutableSet.class, Sets.immutable.ofAll(set)); Verify.assertInstanceOf(ImmutableSet.class, Sets.immutable.ofAll(UnifiedSet.newSetWith(1, 2, 3, 4, 5))); Assert.assertSame(Sets.immutable.ofAll(immutableSet.castToSet()), immutableSet); } @Test public void newSet() { for (int i = 1; i <= 5; i++) { Interval interval = Interval.oneTo(i); Verify.assertEqualsAndHashCode(UnifiedSet.newSet(interval), Sets.immutable.ofAll(interval)); } } @Test public void emptySet() { Assert.assertTrue(Sets.immutable.of().isEmpty()); Assert.assertSame(Sets.immutable.of(), Sets.immutable.of()); Verify.assertPostSerializedIdentity(Sets.immutable.of()); } @Test public void newSetWith() { Assert.assertSame(Sets.immutable.of(), Sets.immutable.of(Sets.immutable.of().toArray())); Verify.assertSize(1, Sets.immutable.of(1).castToSet()); Verify.assertSize(1, Sets.immutable.of(1, 1).castToSet()); Verify.assertSize(1, Sets.immutable.of(1, 1, 1).castToSet()); Verify.assertSize(1, Sets.immutable.of(1, 1, 1, 1).castToSet()); Verify.assertSize(1, Sets.immutable.of(1, 1, 1, 1, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 1, 1, 1, 2).castToSet()); Verify.assertSize(2, Sets.immutable.of(2, 1, 1, 1, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 2, 1, 1, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 1, 2, 1, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 1, 1, 2, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 1, 1, 2).castToSet()); Verify.assertSize(2, Sets.immutable.of(2, 1, 1, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 2, 1, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 1, 2, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 1, 2).castToSet()); Verify.assertSize(2, Sets.immutable.of(2, 1, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 2, 1).castToSet()); Verify.assertSize(2, Sets.immutable.of(1, 2).castToSet()); Verify.assertSize(3, Sets.immutable.of(1, 2, 3).castToSet()); Verify.assertSize(3, Sets.immutable.of(1, 2, 3, 1).castToSet()); Verify.assertSize(3, Sets.immutable.of(2, 1, 3, 1).castToSet()); Verify.assertSize(3, Sets.immutable.of(2, 3, 1, 1).castToSet()); Verify.assertSize(3, Sets.immutable.of(2, 1, 1, 3).castToSet()); Verify.assertSize(3, Sets.immutable.of(1, 1, 2, 3).castToSet()); Verify.assertSize(4, Sets.immutable.of(1, 2, 3, 4).castToSet()); Verify.assertSize(4, Sets.immutable.of(1, 2, 3, 4, 1).castToSet()); } @Test public void setKeyPreservation() { Key key = new Key("key"); Key duplicateKey1 = new Key("key"); ImmutableSet<Key> set1 = Sets.immutable.of(key, duplicateKey1); Verify.assertSize(1, set1); Verify.assertContains(key, set1); Assert.assertSame(key, set1.getFirst()); Key duplicateKey2 = new Key("key"); ImmutableSet<Key> set2 = Sets.immutable.of(key, duplicateKey1, duplicateKey2); Verify.assertSize(1, set2); Verify.assertContains(key, set2); Assert.assertSame(key, set2.getFirst()); Key duplicateKey3 = new Key("key"); ImmutableSet<Key> set3 = Sets.immutable.of(key, new Key("not a dupe"), duplicateKey3); Verify.assertSize(2, set3); Verify.assertContainsAll("immutable set", set3, key, new Key("not a dupe")); Assert.assertSame(key, set3.detect(key::equals)); Key duplicateKey4 = new Key("key"); ImmutableSet<Key> set4 = Sets.immutable.of(key, new Key("not a dupe"), duplicateKey3, duplicateKey4); Verify.assertSize(2, set4); Verify.assertContainsAll("immutable set", set4, key, new Key("not a dupe")); Assert.assertSame(key, set4.detect(key::equals)); ImmutableSet<Key> set5 = Sets.immutable.of(key, new Key("not a dupe"), new Key("me neither"), duplicateKey4); Verify.assertSize(3, set5); Verify.assertContainsAll("immutable set", set5, key, new Key("not a dupe"), new Key("me neither")); Assert.assertSame(key, set5.detect(key::equals)); ImmutableSet<Key> set6 = Sets.immutable.of(key, duplicateKey2, duplicateKey3, duplicateKey4); Verify.assertSize(1, set6); Verify.assertContains(key, set6); Assert.assertSame(key, set6.detect(key::equals)); } @Test public void classIsNonInstantiable() { Verify.assertClassNonInstantiable(Sets.class); } @Test public void ofInitialCapacity() { MutableSet<String> set1 = Sets.mutable.ofInitialCapacity(0); this.assertPresizedSetSizeEquals(0, (UnifiedSet<String>) set1); MutableSet<String> set2 = Sets.mutable.ofInitialCapacity(5); this.assertPresizedSetSizeEquals(5, (UnifiedSet<String>) set2); MutableSet<String> set3 = Sets.mutable.ofInitialCapacity(20); this.assertPresizedSetSizeEquals(20, (UnifiedSet<String>) set3); MutableSet<String> set4 = Sets.mutable.ofInitialCapacity(60); this.assertPresizedSetSizeEquals(60, (UnifiedSet<String>) set4); MutableSet<String> set5 = Sets.mutable.ofInitialCapacity(64); this.assertPresizedSetSizeEquals(60, (UnifiedSet<String>) set5); MutableSet<String> set6 = Sets.mutable.ofInitialCapacity(65); this.assertPresizedSetSizeEquals(65, (UnifiedSet<String>) set6); Verify.assertThrows(IllegalArgumentException.class, () -> Sets.mutable.ofInitialCapacity(-12)); } @Test public void withInitialCapacity() { MutableSet<String> set1 = Sets.mutable.withInitialCapacity(0); this.assertPresizedSetSizeEquals(0, (UnifiedSet<String>) set1); MutableSet<String> set2 = Sets.mutable.withInitialCapacity(14); this.assertPresizedSetSizeEquals(14, (UnifiedSet<String>) set2); MutableSet<String> set3 = Sets.mutable.withInitialCapacity(17); this.assertPresizedSetSizeEquals(17, (UnifiedSet<String>) set3); MutableSet<String> set4 = Sets.mutable.withInitialCapacity(25); this.assertPresizedSetSizeEquals(25, (UnifiedSet<String>) set4); MutableSet<String> set5 = Sets.mutable.withInitialCapacity(32); this.assertPresizedSetSizeEquals(32, (UnifiedSet<String>) set5); Verify.assertThrows(IllegalArgumentException.class, () -> Sets.mutable.ofInitialCapacity(-6)); } private void assertPresizedSetSizeEquals(int initialCapacity, UnifiedSet<String> set) { try { Field tableField = UnifiedSet.class.getDeclaredField("table"); tableField.setAccessible(true); Object[] table = (Object[]) tableField.get(set); int size = (int) Math.ceil(initialCapacity / 0.75f); int capacity = 1; while (capacity < size) { capacity <<= 1; } Assert.assertEquals(capacity, table.length); } catch (SecurityException ignored) { Assert.fail("Unable to modify the visibility of the table on UnifiedSet"); } catch (NoSuchFieldException ignored) { Assert.fail("No field named table UnifiedSet"); } catch (IllegalAccessException ignored) { Assert.fail("No access the field table in UnifiedSet"); } } }