New Tests & Fixes

- Added: Tests for the new Stream replace functions to ensure no bugs
are left.
- Fixed: Custom HashSet reduce function with a default value was
checking incorrectly for present keys.
This commit is contained in:
2021-12-10 03:23:28 +01:00
parent c4964806f0
commit c6afdb8762
8 changed files with 147 additions and 23 deletions
@@ -1023,7 +1023,12 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE
public <E> E[] toArray(E[] a) {
if(a == null) a = (E[])new Object[size];
else if(a.length < size) a = (E[])ObjectArrays.newArray(a.getClass().getComponentType(), size);
#if TYPE_OBJECT
System.arraycopy(data, 0, a, 0, size);
#else
for(int i = 0;i<size;i++)
a[i] = (E)KEY_TO_OBJ(data[i]);
#endif
return a;
}
@@ -160,6 +160,7 @@ public class ARRAY_MAP KEY_VALUE_GENERIC_TYPE extends ABSTRACT_MAP KEY_VALUE_GEN
* @throws IllegalStateException if the keys and values do not match in lenght
*/
public ARRAY_MAP(KEY_TYPE[] keys, VALUE_TYPE[] values, int length) {
this(length);
if(keys.length != values.length) throw new IllegalStateException("Input Arrays are not equal size");
putAll(keys, values, 0, length);
}
@@ -570,7 +570,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
/**
* Starts a Map Builder that allows you to create maps as Constants a lot easier
* Keys & Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* Keys and Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* @Type(T)
* @ValueType(V)
* @return a MapBuilder
@@ -581,7 +581,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
/**
* Starts a Map Builder that allows you to create maps as Constants a lot easier
* Keys & Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* Keys and Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* @param size the expected minimum size of Elements in the Map, default is 16
* @Type(T)
* @ValueType(V)
@@ -592,13 +592,13 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Starts a Map builder and puts in the Key & Value into it
* Keys & Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* Starts a Map builder and puts in the Key and Value into it
* Keys and Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* @param key the key that should be added
* @param value the value that should be added
* @Type(T)
* @ValueType(V)
* @return a MapBuilder with the key & value stored in it.
* @return a MapBuilder with the key and value stored in it.
*/
public GENERIC_KEY_VALUE_BRACES BuilderCache KEY_VALUE_GENERIC_TYPE put(KEY_TYPE key, VALUE_TYPE value) {
return new BuilderCache KEY_VALUE_GENERIC_TYPE().put(key, value);
@@ -606,13 +606,13 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
#if !TYPE_OBJECT || !VALUE_OBJECT
/**
* Starts a Map builder and puts in the Key & Value into it
* Keys & Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* Starts a Map builder and puts in the Key and Value into it
* Keys and Values are stored as Array and then inserted using the putAllMethod when the mapType is choosen
* @param key the key that should be added
* @param value the value that should be added
* @Type(T)
* @ValueType(V)
* @return a MapBuilder with the key & value stored in it.
* @return a MapBuilder with the key and value stored in it.
*/
public GENERIC_KEY_VALUE_BRACES BuilderCache KEY_VALUE_GENERIC_TYPE put(CLASS_TYPE key, CLASS_VALUE_TYPE value) {
return new BuilderCache KEY_VALUE_GENERIC_TYPE().put(key, value);
@@ -1449,7 +1449,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a Hash Map
* Builds the Keys and Values into a Hash Map
* @return a HASH_MAP
*/
public HASH_MAP KEY_VALUE_GENERIC_TYPE map() {
@@ -1457,7 +1457,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a Linked Hash Map
* Builds the Keys and Values into a Linked Hash Map
* @return a LINKED_HASH_MAP
*/
public LINKED_HASH_MAP KEY_VALUE_GENERIC_TYPE linkedMap() {
@@ -1465,7 +1465,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a Immutable Hash Map
* Builds the Keys and Values into a Immutable Hash Map
* @return a IMMUTABLE_HASH_MAP
*/
public IMMUTABLE_HASH_MAP KEY_VALUE_GENERIC_TYPE immutable() {
@@ -1473,8 +1473,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a Custom Hash Map
* @param strategy the that controls the keys & values
* Builds the Keys and Values into a Custom Hash Map
* @param strategy the that controls the keys and values
* @return a CUSTOM_HASH_MAP
*/
public CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE customMap(STRATEGY KEY_GENERIC_TYPE strategy) {
@@ -1482,8 +1482,8 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a Linked Custom Hash Map
* @param strategy the that controls the keys & values
* Builds the Keys and Values into a Linked Custom Hash Map
* @param strategy the that controls the keys and values
* @return a LINKED_CUSTOM_HASH_MAP
*/
public LINKED_CUSTOM_HASH_MAP KEY_VALUE_GENERIC_TYPE customLinkedMap(STRATEGY KEY_GENERIC_TYPE strategy) {
@@ -1491,7 +1491,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a Array Map
* Builds the Keys and Values into a Array Map
* @return a ARRAY_MAP
*/
public ARRAY_MAP KEY_VALUE_GENERIC_TYPE arrayMap() {
@@ -1499,7 +1499,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a RedBlack TreeMap
* Builds the Keys and Values into a RedBlack TreeMap
* @return a RB_TREE_MAP
*/
public RB_TREE_MAP KEY_VALUE_GENERIC_TYPE rbTreeMap() {
@@ -1507,7 +1507,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a RedBlack TreeMap
* Builds the Keys and Values into a RedBlack TreeMap
* @param comp the Comparator that sorts the Tree
* @return a RB_TREE_MAP
*/
@@ -1516,7 +1516,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a AVL TreeMap
* Builds the Keys and Values into a AVL TreeMap
* @return a AVL_TREE_MAP
*/
public AVL_TREE_MAP KEY_VALUE_GENERIC_TYPE avlTreeMap() {
@@ -1524,7 +1524,7 @@ public interface MAP KEY_VALUE_GENERIC_TYPE extends Map<CLASS_TYPE, CLASS_VALUE_
}
/**
* Builds the Keys & Values into a AVL TreeMap
* Builds the Keys and Values into a AVL TreeMap
* @param comp the Comparator that sorts the Tree
* @return a AVL_TREE_MAP
*/
@@ -536,7 +536,7 @@ public class CUSTOM_HASH_SET KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_T
KEY_TYPE state = identity;
if(containsNull) state = operator.APPLY_VALUE(state, keys[nullIndex]);
for(int i = nullIndex-1;i>=0;i--) {
if(!strategy.equals(keys[i], EMPTY_KEY_VALUE)) continue;
if(strategy.equals(keys[i], EMPTY_KEY_VALUE)) continue;
state = operator.APPLY_VALUE(state, keys[i]);
}
return state;
@@ -1,5 +1,6 @@
package speiger.src.collections.ints.base;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.stream.IntStream;
@@ -8,6 +9,11 @@ import org.junit.Test;
import speiger.src.collections.ints.collections.IntIterable;
import speiger.src.collections.ints.collections.IntIterator;
import speiger.src.collections.ints.lists.IntArrayList;
import speiger.src.collections.ints.utils.IntArrays;
import speiger.src.collections.ints.utils.IntIterators;
import speiger.src.collections.objects.utils.ObjectArrays;
import speiger.src.collections.objects.utils.ObjectIterators;
import speiger.src.collections.tests.IterableTest;
@SuppressWarnings("javadoc")
@@ -15,6 +21,7 @@ public abstract class BaseIntIterableTest
{
protected static final int[] EMPTY_ARRAY = new int[0];
protected static final int[] TEST_ARRAY = IntStream.range(0, 100).toArray();
protected static final int[] DISTINCT_ARRAY = IntStream.range(0, 100).flatMap(T -> Arrays.stream(new int[]{T, T})).toArray();
protected abstract IntIterable create(int[] data);
@@ -65,4 +72,103 @@ public abstract class BaseIntIterableTest
}
}
}
@Test
public void testStreamCount() {
if(getValidIterableTests().contains(IterableTest.STREAM_COUNT)) {
long expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).count();
int size = create(TEST_ARRAY).count(T -> T % 2 == 0);
Assert.assertEquals(expected, size);
}
}
@Test
public void testStreamFilter() {
if(getValidIterableTests().contains(IterableTest.STREAM_FILTER)) {
int[] expected = IntStream.of(TEST_ARRAY).filter(T -> T % 2 == 0).toArray();
int[] actual = IntIterators.pour(create(TEST_ARRAY).filter(T -> T % 2 == 0).iterator()).toIntArray();
IntArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual);
}
}
@Test
public void testStreamFindFirst() {
if(getValidIterableTests().contains(IterableTest.STREAM_FIND_FIRST)) {
int expected = IntStream.of(TEST_ARRAY).filter(T -> T / 50 > 0).findFirst().getAsInt();
int actual = create(TEST_ARRAY).findFirst(T -> T / 50 > 0);
Assert.assertEquals(expected, actual);
}
}
@Test
public void teastStreamDistinct() {
if(getValidIterableTests().contains(IterableTest.STREAM_DISTINCT)) {
int[] expected = IntStream.of(DISTINCT_ARRAY).distinct().toArray();
int[] actual = IntIterators.pour(create(DISTINCT_ARRAY).distinct().iterator()).toIntArray();
IntArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual);
}
}
@Test
public void testStreamLimit() {
if(getValidIterableTests().contains(IterableTest.STREAM_LIMIT)) {
int[] expected = IntStream.of(TEST_ARRAY).limit(25).toArray();
int[] actual = IntIterators.pour(create(TEST_ARRAY).limit(25).iterator()).toIntArray();
Assert.assertEquals(expected.length, actual.length);
}
}
@Test
public void testStreamMap() {
if(getValidIterableTests().contains(IterableTest.STREAM_MAP)) {
Integer[] expected = IntStream.of(TEST_ARRAY).mapToObj(Integer::new).toArray(Integer[]::new);
Integer[] actual = ObjectIterators.pour(create(TEST_ARRAY).map(Integer::new).iterator()).toArray(Integer[]::new);
ObjectArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual);
}
}
@Test
public void testStreamMatches() {
if(getValidIterableTests().contains(IterableTest.STREAM_MATCHES)) {
IntIterable iterable = create(TEST_ARRAY);
Assert.assertTrue(iterable.matchesAll(T -> T >= 0));
Assert.assertFalse(iterable.matchesAll(T -> T < 0));
Assert.assertTrue(iterable.matchesAny(T -> T % 2 != 0));
Assert.assertFalse(iterable.matchesAny(T -> T % 2 >= 2));
Assert.assertTrue(iterable.matchesNone(T -> T % 2 >= 2));
Assert.assertFalse(iterable.matchesNone(T -> T % 2 != 0));
}
}
@Test
public void testStreamPeek() {
if(getValidIterableTests().contains(IterableTest.STREAM_PEEK)) {
int[] peekCount = new int[2];
create(TEST_ARRAY).peek(T -> peekCount[0]++).forEach(T -> peekCount[1]++);
Assert.assertEquals(TEST_ARRAY.length, peekCount[0]);
Assert.assertEquals(TEST_ARRAY.length, peekCount[1]);
}
}
@Test
public void testStreamPour() {
if(getValidIterableTests().contains(IterableTest.STREAM_POUR)) {
int[] expected = TEST_ARRAY;
int[] actual = create(TEST_ARRAY).pour(new IntArrayList()).toIntArray();
IntArrays.stableSort(actual);
Assert.assertArrayEquals(expected, actual);
}
}
@Test
public void testStreamReduce() {
if(getValidIterableTests().contains(IterableTest.STREAM_REDUCE)) {
int expected = IntStream.of(TEST_ARRAY).reduce(0, Integer::sum);
int actual = create(TEST_ARRAY).reduce(0, Integer::sum);
Assert.assertEquals(expected, actual);
}
}
}
@@ -7,5 +7,15 @@ public enum IterableTest
ITERATOR_FOR_EACH,
ITERATOR_LOOP,
ITERATOR_REMOVAL,
ITERATOR_SKIP;
ITERATOR_SKIP,
STREAM_COUNT,
STREAM_FILTER,
STREAM_FIND_FIRST,
STREAM_DISTINCT,
STREAM_LIMIT,
STREAM_MAP,
STREAM_MATCHES,
STREAM_PEEK,
STREAM_POUR,
STREAM_REDUCE;
}