/* * 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.set.mutable; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; import com.gs.collections.api.LazyIterable; import com.gs.collections.api.RichIterable; import com.gs.collections.api.bag.sorted.MutableSortedBag; import com.gs.collections.api.block.function.Function; import com.gs.collections.api.list.MutableList; import com.gs.collections.api.set.MutableSet; import com.gs.collections.api.set.UnsortedSetIterable; import com.gs.collections.api.tuple.Pair; import com.gs.collections.impl.Counter; import com.gs.collections.impl.IntegerWithCast; import com.gs.collections.impl.bag.sorted.mutable.TreeBag; import com.gs.collections.impl.block.factory.Predicates; import com.gs.collections.impl.block.factory.Predicates2; import com.gs.collections.impl.block.factory.Procedures; import com.gs.collections.impl.block.procedure.CollectionAddProcedure; import com.gs.collections.impl.collection.mutable.AbstractCollectionTestCase; import com.gs.collections.impl.factory.Lists; import com.gs.collections.impl.list.Interval; import com.gs.collections.impl.list.fixed.ArrayAdapter; import com.gs.collections.impl.list.mutable.FastList; import com.gs.collections.impl.test.Verify; import com.gs.collections.impl.utility.Iterate; import org.junit.Assert; import org.junit.Test; import static com.gs.collections.impl.factory.Iterables.iSet; import static com.gs.collections.impl.factory.Iterables.mList; /** * JUnit test for {@link AbstractMutableSet}. */ public abstract class AbstractMutableSetTestCase extends AbstractCollectionTestCase { protected static final Integer COLLISION_1 = 0; protected static final Integer COLLISION_2 = 17; protected static final Integer COLLISION_3 = 34; protected static final Integer COLLISION_4 = 51; protected static final Integer COLLISION_5 = 68; protected static final Integer COLLISION_6 = 85; protected static final Integer COLLISION_7 = 102; protected static final Integer COLLISION_8 = 119; protected static final Integer COLLISION_9 = 136; protected static final Integer COLLISION_10 = 152; protected static final MutableList<Integer> COLLISIONS = FastList.newListWith(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_4, COLLISION_5); protected static final MutableList<Integer> MORE_COLLISIONS = FastList.newList(COLLISIONS) .with(COLLISION_6, COLLISION_7, COLLISION_8, COLLISION_9); protected static final int SIZE = 8; protected static final String[] FREQUENT_COLLISIONS = {"\u9103\ufffe", "\u9104\uffdf", "\u9105\uffc0", "\u9106\uffa1", "\u9107\uff82", "\u9108\uff63", "\u9109\uff44", "\u910a\uff25", "\u910b\uff06", "\u910c\ufee7"}; @Override protected abstract <T> MutableSet<T> newWith(T... littleElements); @Override @Test public void asSynchronized() { Verify.assertInstanceOf(SynchronizedMutableSet.class, this.newWith().asSynchronized()); } @Override @Test public void addAll() { super.addAll(); UnifiedSet<Integer> expected = UnifiedSet.newSetWith(1, 2, 3); MutableSet<Integer> collection = this.newWith(); Assert.assertTrue(collection.addAll(FastList.newListWith(1, 2, 3))); Assert.assertEquals(expected, collection); Assert.assertFalse(collection.addAll(FastList.newListWith(1, 2, 3))); Assert.assertEquals(expected, collection); } @Override @Test public void addAllIterable() { super.addAllIterable(); UnifiedSet<Integer> expected = UnifiedSet.newSetWith(1, 2, 3); MutableSet<Integer> collection = this.newWith(); Assert.assertTrue(collection.addAllIterable(FastList.newListWith(1, 2, 3))); Assert.assertEquals(expected, collection); Assert.assertFalse(collection.addAllIterable(FastList.newListWith(1, 2, 3))); Assert.assertEquals(expected, collection); } @Test public void union() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> union = set.union(UnifiedSet.newSetWith("a", "b", "c", "1")); Verify.assertSize(set.size() + 3, union); Assert.assertTrue(union.containsAllIterable(Interval.oneTo(set.size()).collect(String::valueOf))); Verify.assertContainsAll(union, "a", "b", "c"); Assert.assertEquals(set, set.union(UnifiedSet.newSetWith("1"))); } @Test public void unionInto() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> union = set.unionInto(UnifiedSet.newSetWith("a", "b", "c", "1"), UnifiedSet.<String>newSet()); Verify.assertSize(set.size() + 3, union); Assert.assertTrue(union.containsAllIterable(Interval.oneTo(set.size()).collect(String::valueOf))); Verify.assertContainsAll(union, "a", "b", "c"); Assert.assertEquals(set, set.unionInto(UnifiedSet.newSetWith("1"), UnifiedSet.<String>newSet())); } @Test public void intersect() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> intersect = set.intersect(UnifiedSet.newSetWith("a", "b", "c", "1")); Verify.assertSize(1, intersect); Assert.assertEquals(UnifiedSet.newSetWith("1"), intersect); Verify.assertEmpty(set.intersect(UnifiedSet.newSetWith("not present"))); } @Test public void intersectInto() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> intersect = set.intersectInto(UnifiedSet.newSetWith("a", "b", "c", "1"), UnifiedSet.<String>newSet()); Verify.assertSize(1, intersect); Assert.assertEquals(UnifiedSet.newSetWith("1"), intersect); Verify.assertEmpty(set.intersectInto(UnifiedSet.newSetWith("not present"), UnifiedSet.<String>newSet())); } @Test public void difference() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> difference = set.difference(UnifiedSet.newSetWith("2", "3", "4", "not present")); Assert.assertEquals(UnifiedSet.newSetWith("1"), difference); Assert.assertEquals(set, set.difference(UnifiedSet.newSetWith("not present"))); } @Test public void differenceInto() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> difference = set.differenceInto(UnifiedSet.newSetWith("2", "3", "4", "not present"), UnifiedSet.<String>newSet()); Assert.assertEquals(UnifiedSet.newSetWith("1"), difference); Assert.assertEquals(set, set.differenceInto(UnifiedSet.newSetWith("not present"), UnifiedSet.<String>newSet())); } @Test public void symmetricDifference() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> difference = set.symmetricDifference(UnifiedSet.newSetWith("2", "3", "4", "5", "not present")); Verify.assertContains("1", difference); Assert.assertTrue(difference.containsAllIterable(Interval.fromTo(set.size() + 1, 5).collect(String::valueOf))); for (int i = 2; i <= set.size(); i++) { Verify.assertNotContains(String.valueOf(i), difference); } Verify.assertSize(set.size() + 1, set.symmetricDifference(UnifiedSet.newSetWith("not present"))); } @Test public void symmetricDifferenceInto() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<String> difference = set.symmetricDifferenceInto( UnifiedSet.newSetWith("2", "3", "4", "5", "not present"), UnifiedSet.<String>newSet()); Verify.assertContains("1", difference); Assert.assertTrue(difference.containsAllIterable(Interval.fromTo(set.size() + 1, 5).collect(String::valueOf))); for (int i = 2; i <= set.size(); i++) { Verify.assertNotContains(String.valueOf(i), difference); } Verify.assertSize( set.size() + 1, set.symmetricDifferenceInto(UnifiedSet.newSetWith("not present"), UnifiedSet.<String>newSet())); } @Test public void isSubsetOf() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); Assert.assertTrue(set.isSubsetOf(UnifiedSet.newSetWith("1", "2", "3", "4", "5"))); } @Test public void isProperSubsetOf() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); Assert.assertTrue(set.isProperSubsetOf(UnifiedSet.newSetWith("1", "2", "3", "4", "5"))); Assert.assertFalse(set.isProperSubsetOf(set)); } @Test public void powerSet() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); MutableSet<UnsortedSetIterable<String>> powerSet = set.powerSet(); Verify.assertSize((int) StrictMath.pow(2, set.size()), powerSet); Verify.assertContains(UnifiedSet.<String>newSet(), powerSet); Verify.assertContains(set, powerSet); } @Test public void cartesianProduct() { MutableSet<String> set = this.newWith("1", "2", "3", "4"); LazyIterable<Pair<String, String>> cartesianProduct = set.cartesianProduct(UnifiedSet.newSetWith("One", "Two")); Verify.assertIterableSize(set.size() * 2, cartesianProduct); Assert.assertEquals( set, cartesianProduct .select(Predicates.attributeEqual((Function<Pair<?, String>, String>) Pair::getTwo, "One")) .collect((Function<Pair<String, ?>, String>) Pair::getOne).toSet()); } @Override @Test public void asUnmodifiable() { Verify.assertInstanceOf(UnmodifiableMutableSet.class, this.newWith().asUnmodifiable()); } @Override @Test public void select() { super.select(); Verify.assertContainsAll(this.newWith(1, 2, 3, 4, 5).select(Predicates.lessThan(3)), 1, 2); Verify.assertContainsAll( this.newWith(-1, 2, 3, 4, 5).select(Predicates.lessThan(3), FastList.<Integer>newList()), -1, 2); } @Override @Test public void reject() { super.reject(); Verify.assertContainsAll(this.newWith(1, 2, 3, 4).reject(Predicates.lessThan(3)), 3, 4); Verify.assertContainsAll( this.newWith(1, 2, 3, 4).reject(Predicates.lessThan(3), FastList.<Integer>newList()), 3, 4); } @Override @Test public void getFirst() { super.getFirst(); Assert.assertNotNull(this.newWith(1, 2, 3).getFirst()); Assert.assertNull(this.newWith().getFirst()); } @Override @Test public void getLast() { Assert.assertNotNull(this.newWith(1, 2, 3).getLast()); Assert.assertNull(this.newWith().getLast()); } @Test public void unifiedSetKeySetToArrayDest() { MutableSet<Integer> set = this.newWith(1, 2, 3, 4); // deliberately to small to force the method to allocate one of the correct size Integer[] dest = new Integer[2]; Integer[] result = set.toArray(dest); Verify.assertSize(4, result); Arrays.sort(result); Assert.assertArrayEquals(new Integer[]{1, 2, 3, 4}, result); } @Test public void unifiedSetToString() { MutableSet<Integer> set = this.newWith(1, 2); String s = set.toString(); Assert.assertTrue("[1, 2]".equals(s) || "[2, 1]".equals(s)); } @Test public void testClone() { MutableSet<String> set = this.newWith(); MutableSet<String> clone = set.clone(); Assert.assertNotSame(clone, set); Verify.assertEqualsAndHashCode(clone, set); } @Override @Test public void isEmpty() { super.isEmpty(); MutableSet<String> set = this.newWith(); this.assertIsEmpty(true, set); set.add("stuff"); this.assertIsEmpty(false, set); set.remove("stuff"); this.assertIsEmpty(true, set); set.add("Bon"); set.add("Jovi"); this.assertIsEmpty(false, set); set.remove("Jovi"); this.assertIsEmpty(false, set); set.clear(); this.assertIsEmpty(true, set); } private void assertIsEmpty(boolean isEmpty, MutableSet<?> set) { Assert.assertEquals(isEmpty, set.isEmpty()); Assert.assertEquals(!isEmpty, set.notEmpty()); } @Test public void add() { MutableSet<IntegerWithCast> set = this.newWith(); MutableList<IntegerWithCast> collisions = COLLISIONS.collect(IntegerWithCast::new); set.addAll(collisions); set.removeAll(collisions); for (Integer integer : COLLISIONS) { Assert.assertTrue(set.add(new IntegerWithCast(integer))); Assert.assertFalse(set.add(new IntegerWithCast(integer))); } Assert.assertEquals(collisions.toSet(), set); } @Override @Test public void removeIf() { super.removeIf(); MutableSet<IntegerWithCast> set = this.newWith(); MutableList<IntegerWithCast> collisions = COLLISIONS.collect(IntegerWithCast::new); set.addAll(collisions); collisions.reverseForEach(each -> { Assert.assertFalse(set.remove(null)); Assert.assertTrue(set.remove(each)); Assert.assertFalse(set.remove(each)); Assert.assertFalse(set.remove(null)); Assert.assertFalse(set.remove(new IntegerWithCast(COLLISION_10))); }); Assert.assertEquals(UnifiedSet.<IntegerWithCast>newSet(), set); collisions.forEach(Procedures.cast(each -> { MutableSet<IntegerWithCast> set2 = this.newWith(); set2.addAll(collisions); Assert.assertFalse(set2.remove(null)); Assert.assertTrue(set2.remove(each)); Assert.assertFalse(set2.remove(each)); Assert.assertFalse(set2.remove(null)); Assert.assertFalse(set2.remove(new IntegerWithCast(COLLISION_10))); })); // remove the second-to-last item in a fully populated single chain to cause the last item to move MutableSet<Integer> set3 = this.newWith(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_4); Assert.assertTrue(set3.remove(COLLISION_3)); Assert.assertEquals(UnifiedSet.newSetWith(COLLISION_1, COLLISION_2, COLLISION_4), set3); Assert.assertTrue(set3.remove(COLLISION_2)); Assert.assertEquals(UnifiedSet.newSetWith(COLLISION_1, COLLISION_4), set3); // search a chain for a non-existent element MutableSet<Integer> chain = this.newWith(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_4); Assert.assertFalse(chain.remove(COLLISION_5)); // search a deep chain for a non-existent element MutableSet<Integer> deepChain = this.newWith(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_4, COLLISION_5, COLLISION_6, COLLISION_7); Assert.assertFalse(deepChain.remove(COLLISION_8)); // search for a non-existent element MutableSet<Integer> empty = this.newWith(); Assert.assertFalse(empty.remove(COLLISION_1)); } @Override @Test public void retainAll() { super.retainAll(); MutableList<Integer> collisions = MORE_COLLISIONS.clone(); collisions.add(COLLISION_10); int size = MORE_COLLISIONS.size(); for (int i = 0; i < size; i++) { MutableList<Integer> list = MORE_COLLISIONS.subList(0, i); MutableSet<Integer> set = this.<Integer>newWith().withAll(list); Assert.assertFalse(set.retainAll(collisions)); Assert.assertEquals(list.toSet(), set); } for (Integer item : MORE_COLLISIONS) { MutableSet<Integer> integers = this.<Integer>newWith().withAll(MORE_COLLISIONS); @SuppressWarnings("BoxingBoxedValue") Integer keyCopy = new Integer(item); Assert.assertTrue(integers.retainAll(mList(keyCopy))); Assert.assertEquals(iSet(keyCopy), integers); Assert.assertNotSame(keyCopy, Iterate.getOnly(integers)); } // retain all on a bucket with a single element MutableSet<Integer> singleCollisionBucket = this.newWith(COLLISION_1, COLLISION_2); singleCollisionBucket.remove(COLLISION_2); Assert.assertTrue(singleCollisionBucket.retainAll(FastList.newListWith(COLLISION_2))); } @Override @Test public void equalsAndHashCode() { super.equalsAndHashCode(); UnifiedSet<Integer> expected = UnifiedSet.newSetWith(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_4); Assert.assertNotEquals(expected, this.newWith(COLLISION_2, COLLISION_3, COLLISION_4, COLLISION_5)); Assert.assertNotEquals(expected, this.newWith(COLLISION_1, COLLISION_3, COLLISION_4, COLLISION_5)); Assert.assertNotEquals(expected, this.newWith(COLLISION_1, COLLISION_2, COLLISION_4, COLLISION_5)); Assert.assertNotEquals(expected, this.newWith(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_5)); Assert.assertEquals(expected, this.newWith(COLLISION_1, COLLISION_2, COLLISION_3, COLLISION_4)); } @Override @Test public void tap() { super.tap(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableList<Integer> tapResult = Lists.mutable.of(); MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Assert.assertSame(set, set.tap(tapResult::add)); Assert.assertEquals(set.toList(), tapResult); } // test iterating on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Counter counter = new Counter(); Assert.assertSame(set, set.tap(x -> counter.increment())); Assert.assertEquals(1, counter.getCount()); } @Override @Test public void forEach() { super.forEach(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); MutableSet<Integer> result = UnifiedSet.newSet(); set.forEach(CollectionAddProcedure.on(result)); Assert.assertEquals(set, result); } // test iterating on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Counter counter = new Counter(); set.forEach(Procedures.cast(each -> counter.increment())); Assert.assertEquals(1, counter.getCount()); } @Override @Test public void forEachWith() { super.forEachWith(); Object sentinel = new Object(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); MutableSet<Integer> result = UnifiedSet.newSet(); set.forEachWith((argument1, argument2) -> { Assert.assertSame(sentinel, argument2); result.add(argument1); }, sentinel); Assert.assertEquals(set, result); } // test iterating on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Counter counter = new Counter(); set.forEachWith((argument1, argument2) -> argument2.increment(), counter); Assert.assertEquals(1, counter.getCount()); } @Override @Test public void forEachWithIndex() { super.forEachWithIndex(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); MutableSet<Integer> result = UnifiedSet.newSet(); MutableList<Integer> indexes = Lists.mutable.of(); set.forEachWithIndex((each, index) -> { result.add(each); indexes.add(index); }); Assert.assertEquals(set, result); Assert.assertEquals(Interval.zeroTo(i - 1), indexes); } // test iterating on a bucket with only one element UnifiedSet<Integer> set = UnifiedSet.newSetWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Counter counter = new Counter(); set.forEachWithIndex((each, index) -> counter.increment()); Assert.assertEquals(1, counter.getCount()); } @Override @Test public void anySatisfy() { super.anySatisfy(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Assert.assertTrue(set.anySatisfy(MORE_COLLISIONS.subList(0, i).getLast()::equals)); Assert.assertFalse(set.anySatisfy(Predicates.greaterThan(MORE_COLLISIONS.subList(0, i).getLast()))); } // test anySatisfy on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Assert.assertTrue(set.anySatisfy(COLLISION_1::equals)); Assert.assertFalse(set.anySatisfy(COLLISION_2::equals)); // Rehashing Case A: a bucket with only one entry and a low capacity forcing a rehash, where the triggering element goes in the bucket // set up a chained bucket MutableSet<Integer> caseA = this.newWith(COLLISION_1, COLLISION_2); // clear the bucket to one element caseA.remove(COLLISION_2); // increase the occupied count to the threshold caseA.add(Integer.valueOf(1)); caseA.add(Integer.valueOf(2)); // add the colliding value back and force the rehash caseA.add(COLLISION_2); Assert.assertTrue(caseA.anySatisfy(COLLISION_2::equals)); } @Override @Test public void anySatisfyWith() { super.anySatisfyWith(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Assert.assertTrue(set.anySatisfyWith(Object::equals, MORE_COLLISIONS.subList(0, i).getLast())); Assert.assertFalse(set.anySatisfyWith(Predicates2.greaterThan(), MORE_COLLISIONS.subList(0, i).getLast())); } // test anySatisfyWith on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Assert.assertTrue(set.anySatisfyWith(Object::equals, COLLISION_1)); Assert.assertFalse(set.anySatisfyWith(Object::equals, COLLISION_2)); // Rehashing Case A: a bucket with only one entry and a low capacity forcing a rehash, where the triggering element goes in the bucket // set up a chained bucket MutableSet<Integer> caseA = this.newWith(COLLISION_1, COLLISION_2); // clear the bucket to one element caseA.remove(COLLISION_2); // increase the occupied count to the threshold caseA.add(Integer.valueOf(1)); caseA.add(Integer.valueOf(2)); // add the colliding value back and force the rehash caseA.add(COLLISION_2); Assert.assertTrue(caseA.anySatisfyWith(Object::equals, COLLISION_2)); } @Override @Test public void allSatisfy() { super.allSatisfy(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Assert.assertTrue(set.allSatisfy(Predicates.greaterThanOrEqualTo(MORE_COLLISIONS.subList(0, i).getFirst()))); Assert.assertFalse(set.allSatisfy(Predicates.lessThan(MORE_COLLISIONS.subList(0, i).get(i - 1)))); } // test allSatisfy on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Assert.assertTrue(set.allSatisfy(COLLISION_1::equals)); Assert.assertFalse(set.allSatisfy(COLLISION_2::equals)); // Rehashing Case A: a bucket with only one entry and a low capacity forcing a rehash, where the triggering element goes in the bucket // set up a chained bucket MutableSet<Integer> caseA = this.newWith(COLLISION_1, COLLISION_2); // clear the bucket to one element caseA.remove(COLLISION_2); // increase the occupied count to the threshold caseA.add(Integer.valueOf(1)); caseA.add(Integer.valueOf(2)); // add the colliding value back and force the rehash caseA.add(COLLISION_2); Assert.assertTrue(caseA.allSatisfy(Predicates.lessThanOrEqualTo(COLLISION_2))); } @Override @Test public void allSatisfyWith() { super.allSatisfyWith(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Assert.assertTrue(set.allSatisfyWith(Predicates2.greaterThanOrEqualTo(), MORE_COLLISIONS.subList(0, i).getFirst())); Assert.assertFalse(set.allSatisfyWith(Predicates2.lessThan(), MORE_COLLISIONS.subList(0, i).get(i - 1))); } // test allSatisfyWith on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Assert.assertTrue(set.allSatisfyWith(Object::equals, COLLISION_1)); Assert.assertFalse(set.allSatisfyWith(Object::equals, COLLISION_2)); // Rehashing Case A: a bucket with only one entry and a low capacity forcing a rehash, where the triggering element goes in the bucket // set up a chained bucket MutableSet<Integer> caseA = this.newWith(COLLISION_1, COLLISION_2); // clear the bucket to one element caseA.remove(COLLISION_2); // increase the occupied count to the threshold caseA.add(Integer.valueOf(1)); caseA.add(Integer.valueOf(2)); // add the colliding value back and force the rehash caseA.add(COLLISION_2); Assert.assertTrue(caseA.allSatisfyWith(Predicates2.lessThanOrEqualTo(), COLLISION_2)); } @Override @Test public void noneSatisfy() { super.noneSatisfy(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Assert.assertTrue(set.noneSatisfy(Predicates.lessThan(MORE_COLLISIONS.subList(0, i).getFirst()))); Assert.assertFalse(set.noneSatisfy(Predicates.greaterThanOrEqualTo(MORE_COLLISIONS.subList(0, i).get(i - 1)))); } // test noneSatisfy on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Assert.assertFalse(set.noneSatisfy(COLLISION_1::equals)); Assert.assertTrue(set.noneSatisfy(COLLISION_2::equals)); // Rehashing Case A: a bucket with only one entry and a low capacity forcing a rehash, where the triggering element goes in the bucket // set up a chained bucket MutableSet<Integer> caseA = this.newWith(COLLISION_1, COLLISION_2); // clear the bucket to one element caseA.remove(COLLISION_2); // increase the occupied count to the threshold caseA.add(Integer.valueOf(1)); caseA.add(Integer.valueOf(2)); // add the colliding value back and force the rehash caseA.add(COLLISION_2); Assert.assertTrue(caseA.noneSatisfy(Predicates.greaterThan(COLLISION_2))); } @Override @Test public void noneSatisfyWith() { super.noneSatisfyWith(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Assert.assertTrue(set.noneSatisfyWith(Predicates2.lessThan(), MORE_COLLISIONS.subList(0, i).getFirst())); Assert.assertFalse(set.noneSatisfyWith(Predicates2.greaterThanOrEqualTo(), MORE_COLLISIONS.subList(0, i).get(i - 1))); } // test noneSatisfyWith on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Assert.assertFalse(set.noneSatisfyWith(Object::equals, COLLISION_1)); Assert.assertTrue(set.noneSatisfyWith(Object::equals, COLLISION_2)); // Rehashing Case A: a bucket with only one entry and a low capacity forcing a rehash, where the triggering element goes in the bucket // set up a chained bucket MutableSet<Integer> caseA = this.newWith(COLLISION_1, COLLISION_2); // clear the bucket to one element caseA.remove(COLLISION_2); // increase the occupied count to the threshold caseA.add(Integer.valueOf(1)); caseA.add(Integer.valueOf(2)); // add the colliding value back and force the rehash caseA.add(COLLISION_2); Assert.assertTrue(caseA.noneSatisfyWith(Predicates2.greaterThan(), COLLISION_2)); } @Override @Test public void detect() { super.detect(); int size = MORE_COLLISIONS.size(); for (int i = 1; i < size; i++) { MutableSet<Integer> set = this.newWith(); set.addAll(MORE_COLLISIONS.subList(0, i)); Verify.assertItemAtIndex(set.detect(MORE_COLLISIONS.get(i - 1)::equals), i - 1, MORE_COLLISIONS); } // test detect on a bucket with only one element MutableSet<Integer> set = this.newWith(COLLISION_1, COLLISION_2); set.remove(COLLISION_2); Assert.assertEquals(COLLISION_1, set.detect(COLLISION_1::equals)); Assert.assertNull(set.detect(COLLISION_2::equals)); for (int i = 0; i < COLLISIONS.size(); i++) { MutableSet<Integer> rehashingSet = this.newWith(); rehashingSet.addAll(COLLISIONS.subList(0, i)); Integer last = COLLISIONS.subList(0, i).getLast(); rehashingSet.remove(last); int rehashingSetSize = rehashingSet.size(); for (int j = 0; j < rehashingSetSize; j++) { rehashingSet.add(Integer.valueOf(j + 1)); } rehashingSet.add(last); Assert.assertEquals(last, rehashingSet.detect(Predicates.equal(last))); Assert.assertNull(rehashingSet.detect(Integer.valueOf(5)::equals)); } } @Test(expected = NoSuchElementException.class) public void iterator_increment_past_end() { MutableSet<Integer> set = this.newWith(); Iterator<Integer> iterator = set.iterator(); iterator.next(); iterator.next(); } @Test(expected = IllegalStateException.class) public void iterator_remove_without_next() { Iterator<Integer> iterator = this.<Integer>newWith().iterator(); iterator.remove(); } @Override @Test public void toArray() { super.toArray(); MutableSet<Integer> integers = this.newWith(1); Integer[] target = new Integer[3]; target[0] = 2; target[1] = 2; target[2] = 2; integers.toArray(target); Assert.assertArrayEquals(new Integer[]{1, null, 2}, target); } @Override @Test public void toSortedBag_natural_ordering() { RichIterable<Integer> integers = this.newWith(1, 2, 5, 3, 4); MutableSortedBag<Integer> bag = integers.toSortedBag(); Verify.assertSortedBagsEqual(TreeBag.newBagWith(1, 2, 3, 4, 5), bag); } @Override @Test public void toSortedBag_with_comparator() { RichIterable<Integer> integers = this.newWith(2, 4, 1, 3); MutableSortedBag<Integer> bag = integers.toSortedBag(Collections.<Integer>reverseOrder()); Verify.assertSortedBagsEqual(TreeBag.newBagWith(Collections.<Integer>reverseOrder(), 4, 3, 2, 1), bag); } @Override @Test(expected = NullPointerException.class) public void toSortedBag_with_null() { this.newWith(3, 4, null, 1, 2).toSortedBag(); } @Override @Test public void toSortedBagBy() { RichIterable<Integer> integers = this.newWith(2, 4, 1, 3); MutableSortedBag<Integer> bag = integers.toSortedBagBy(String::valueOf); Verify.assertSortedBagsEqual(TreeBag.newBagWith(1, 2, 3, 4), bag); } @Test public void frequentCollisions() { String[] expected = ArrayAdapter.adapt(FREQUENT_COLLISIONS) .subList(0, FREQUENT_COLLISIONS.length - 2) .toArray(new String[FREQUENT_COLLISIONS.length - 2]); MutableSet<String> set1 = this.newWith(); MutableSet<String> set2 = this.newWith(); Collections.addAll(set1, FREQUENT_COLLISIONS); Collections.addAll(set2, expected); set1.retainAll(set2); Verify.assertArrayEquals(expected, set1.toArray()); } }