forked from Speiger/Primitive-Collections
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:
parent
c4964806f0
commit
c6afdb8762
|
@ -10,6 +10,8 @@
|
|||
- Added: Unmodifiable and Synchronized Wrapper Collections can now be cloned. They clone the underlying map which doesn't break functionality. (Had a usecase for it)
|
||||
- Added: A boxed putAll array variant.
|
||||
- Fixed: EnumMaps didn't keep track of their size and now got proper care and implementations as needed. There might be more work required but at least the core functionality is now up to date.
|
||||
- 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.
|
||||
|
||||
### Version 0.4.5
|
||||
- Added: removeAll/retainAll(Collection c, Consumer r) which receives all the elements that got deleted from the collection
|
||||
|
|
|
@ -18,7 +18,7 @@ repositories {
|
|||
}
|
||||
|
||||
archivesBaseName = 'Primitive Collections'
|
||||
version = '0.4.5';
|
||||
version = '0.4.6';
|
||||
|
||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue