From e6d5242edf55713dd7c750ef690db827dbba155c Mon Sep 17 00:00:00 2001 From: javasabr Date: Sun, 9 Nov 2025 18:57:16 +0100 Subject: [PATCH 1/3] extend long/int arrays API --- README.md | 2 +- build.gradle | 2 +- .../rlib/collections/array/Array.java | 54 ++++- .../array/ArrayIterationFunctions.java | 2 + .../collections/array/MutableIntArray.java | 6 +- .../collections/array/MutableLongArray.java | 6 +- ... ReversedArgsArrayIterationFunctions.java} | 6 +- .../collections/array/impl/AbstractArray.java | 11 +- .../array/impl/AbstractIntArray.java | 17 +- .../array/impl/AbstractLongArray.java | 17 +- .../array/impl/AbstractMutableIntArray.java | 37 +++- .../array/impl/AbstractMutableLongArray.java | 37 +++- .../impl/DefaultArrayIterationFunctions.java | 5 +- ...tReversedArgsArrayIterationFunctions.java} | 10 +- .../array/impl/ImmutableArray.java | 75 ++++++- .../rlib/collections/array/ArrayTest.java | 46 ++++- .../array/MutableIntArrayTest.java | 176 ++++++++++++++++ .../array/MutableLongArrayTest.java | 176 ++++++++++++++++ .../array/ReversedArrayIterationsTest.java | 16 +- .../javasabr/rlib/common/util/ArrayUtils.java | 79 ++++++- .../javasabr/rlib/common/util/ClassUtils.java | 63 ++++++ .../rlib/common/util/NumberedEnumMap.java | 5 + .../rlib/common/util/ClassUtilsTest.java | 192 ++++++++++++++++++ .../rlib/common/util/NumberedEnumMapTest.java | 1 + .../java/javasabr/rlib/io/util/FileUtils.java | 3 +- 25 files changed, 968 insertions(+), 76 deletions(-) rename rlib-collections/src/main/java/javasabr/rlib/collections/array/{ReversedArrayIterationFunctions.java => ReversedArgsArrayIterationFunctions.java} (56%) rename rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/{DefaultReversedArrayIterationFunctions.java => DefaultReversedArgsArrayIterationFunctions.java} (71%) create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java create mode 100644 rlib-common/src/test/java/javasabr/rlib/common/util/ClassUtilsTest.java diff --git a/README.md b/README.md index b1e40da9..c3dc81f6 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ repositories { } ext { - rlibVersion = "10.0.alpha6" + rlibVersion = "10.0.alpha7" } dependencies { diff --git a/build.gradle b/build.gradle index 45952844..8c95004e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -rootProject.version = "10.0.alpha6" +rootProject.version = "10.0.alpha7" group = 'javasabr.rlib' allprojects { diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java index 99f11e95..f37f7a98 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java @@ -1,6 +1,7 @@ package javasabr.rlib.collections.array; import java.io.Serializable; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -9,6 +10,7 @@ import java.util.stream.Stream; import javasabr.rlib.collections.array.impl.DefaultArrayIterator; import javasabr.rlib.collections.array.impl.ImmutableArray; +import javasabr.rlib.common.util.ArrayUtils; import javasabr.rlib.common.util.ClassUtils; import org.jspecify.annotations.Nullable; @@ -21,20 +23,44 @@ static Array empty(Class type) { return new ImmutableArray<>(ClassUtils.unsafeCast(type)); } - static Array of(E e1) { - return new ImmutableArray<>(Object.class, e1); + static Array of(E single) { + @SuppressWarnings("unchecked") + Class type = (Class) single.getClass(); + return new ImmutableArray<>(type, single); } static Array of(E e1, E e2) { - return new ImmutableArray<>(Object.class, e1, e2); + Class commonType = ClassUtils.commonType(e1, e2); + return new ImmutableArray<>(commonType, e1, e2); } static Array of(E e1, E e2, E e3) { - return new ImmutableArray<>(Object.class, e1, e2, e3); + Class commonType = ClassUtils.commonType(e1, e2, e3); + return new ImmutableArray<>(commonType, e1, e2, e3); } static Array of(E e1, E e2, E e3, E e4) { - return new ImmutableArray<>(Object.class, e1, e2, e3, e4); + Class commonType = ClassUtils.commonType(e1, e2, e3, e4); + return new ImmutableArray<>(commonType, e1, e2, e3, e4); + } + + static Array of(E e1, E e2, E e3, E e4, E e5) { + Class commonType = ClassUtils.commonType(e1, e2, e3, e4, e5); + return new ImmutableArray<>(commonType, e1, e2, e3, e4, e5); + } + + static Array of(E e1, E e2, E e3, E e4, E e5, E e6) { + Class commonType = ClassUtils.commonType(e1, e2, e3, e4, e5, e6); + return new ImmutableArray<>(commonType, e1, e2, e3, e4, e5, e6); + } + + @SafeVarargs + static Array of(E... elements) { + //noinspection unchecked + Class type = (Class) elements + .getClass() + .getComponentType(); + return new ImmutableArray<>(type, elements); } @SafeVarargs @@ -51,7 +77,21 @@ static Array optionals(Class type, Optional... elements) { .collect(ArrayCollectors.toArray(type)); } - static Array copyOf(MutableArray array) { + /** + * Creates array with the same element repeated 'count' times + */ + static Array repeated(E element, int count) { + @SuppressWarnings("unchecked") + Class type = (Class) element.getClass(); + E[] array = ArrayUtils.create(type, count); + Arrays.fill(array, element); + return ImmutableArray.trustWrap(array); + } + + static Array copyOf(Array array) { + if (array instanceof ImmutableArray) { + return array; + } return new ImmutableArray<>(array.type(), array.toArray()); } @@ -203,8 +243,6 @@ default Iterator iterator() { */ Stream stream(); - ReversedArrayIterationFunctions reversedIterations(); - ArrayIterationFunctions iterations(); UnsafeArray asUnsafe(); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java index 4ab33d9f..985d3af8 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java @@ -9,6 +9,8 @@ public interface ArrayIterationFunctions { + ReversedArgsArrayIterationFunctions reversedArgs(); + @Nullable E findAny(A arg1, BiPredicate filter); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableIntArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableIntArray.java index d340c4bb..d119cd65 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableIntArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableIntArray.java @@ -11,10 +11,14 @@ public interface MutableIntArray extends IntArray { /** * @return the element previously at the specified position */ - int removeByInex(int index); + int removeByIndex(int index); boolean remove(int value); + boolean removeAll(IntArray array); + + boolean removeAll(int[] array); + void replace(int index, int value); void clear(); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableLongArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableLongArray.java index fb71df23..dfea7d28 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableLongArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/MutableLongArray.java @@ -11,10 +11,14 @@ public interface MutableLongArray extends LongArray { /** * @return the element previously at the specified position */ - long removeByInex(int index); + long removeByIndex(int index); boolean remove(long value); + boolean removeAll(LongArray array); + + boolean removeAll(long[] array); + void replace(int index, long value); void clear(); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArgsArrayIterationFunctions.java similarity index 56% rename from rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArrayIterationFunctions.java rename to rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArgsArrayIterationFunctions.java index f056cbe0..b01e44af 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArgsArrayIterationFunctions.java @@ -5,14 +5,14 @@ import javasabr.rlib.functions.TriConsumer; import org.jspecify.annotations.Nullable; -public interface ReversedArrayIterationFunctions { +public interface ReversedArgsArrayIterationFunctions { @Nullable E findAny(A arg1, BiPredicate filter); - ReversedArrayIterationFunctions forEach(A arg1, BiConsumer consumer); + ReversedArgsArrayIterationFunctions forEach(A arg1, BiConsumer consumer); - ReversedArrayIterationFunctions forEach(A arg1, B arg2, TriConsumer consumer); + ReversedArgsArrayIterationFunctions forEach(A arg1, B arg2, TriConsumer consumer); boolean anyMatch(A arg1, BiPredicate filter); } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java index f4003e05..590e93ed 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java @@ -9,7 +9,6 @@ import java.util.function.Function; import javasabr.rlib.collections.array.Array; import javasabr.rlib.collections.array.ArrayIterationFunctions; -import javasabr.rlib.collections.array.ReversedArrayIterationFunctions; import javasabr.rlib.collections.array.UnsafeArray; import javasabr.rlib.common.util.ArrayUtils; import javasabr.rlib.common.util.ClassUtils; @@ -174,13 +173,13 @@ public void forEach(Consumer action) { } @Override - public ReversedArrayIterationFunctions reversedIterations() { - return new DefaultReversedArrayIterationFunctions<>(this); + public ArrayIterationFunctions iterations() { + return createIterations(); } - @Override - public ArrayIterationFunctions iterations() { - return new DefaultArrayIterationFunctions<>(this); + protected ArrayIterationFunctions createIterations() { + return new DefaultArrayIterationFunctions<>(this, + new DefaultReversedArgsArrayIterationFunctions<>(this)); } @Override diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java index ffe1fdc8..60acf4b1 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java @@ -5,6 +5,7 @@ import java.util.NoSuchElementException; import javasabr.rlib.collections.array.IntArray; import javasabr.rlib.collections.array.UnsafeIntArray; +import javasabr.rlib.common.util.ArrayUtils; import lombok.AccessLevel; import lombok.experimental.Accessors; import lombok.experimental.FieldDefaults; @@ -110,32 +111,28 @@ public int[] toArray() { @Override public boolean equals(Object another) { - if (!(another instanceof IntArray array)) { return false; } - - int[] wrapped = array - .asUnsafe() - .wrapped(); - + int[] wrapped = array.asUnsafe().wrapped(); return Arrays.equals(wrapped(), 0, size(), wrapped, 0, array.size()); } @Override public int hashCode() { - int[] wrapped = wrapped(); - int result = 1; - for (int i = 0, wrappedLength = size(); i < wrappedLength; i++) { result = 31 * result + wrapped[i]; } - return result; } + @Override + public String toString() { + return ArrayUtils.toString(wrapped(), 0, size(), ",", false, true); + } + @Override public UnsafeIntArray asUnsafe() { return this; diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java index 0c419f31..f4b44645 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java @@ -5,6 +5,7 @@ import java.util.NoSuchElementException; import javasabr.rlib.collections.array.LongArray; import javasabr.rlib.collections.array.UnsafeLongArray; +import javasabr.rlib.common.util.ArrayUtils; import lombok.AccessLevel; import lombok.experimental.Accessors; import lombok.experimental.FieldDefaults; @@ -110,32 +111,28 @@ public long[] toArray() { @Override public boolean equals(Object another) { - if (!(another instanceof LongArray array)) { return false; } - - long[] wrapped = array - .asUnsafe() - .wrapped(); - + long[] wrapped = array.asUnsafe().wrapped(); return Arrays.equals(wrapped(), 0, size(), wrapped, 0, array.size()); } @Override public int hashCode() { - long[] wrapped = wrapped(); - int result = 1; - for (int i = 0, wrappedLength = size(); i < wrappedLength; i++) { result = 31 * result + Long.hashCode(wrapped[i]); } - return result; } + @Override + public String toString() { + return ArrayUtils.toString(wrapped(), 0, size(), ",", false, true); + } + @Override public UnsafeLongArray asUnsafe() { return this; diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableIntArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableIntArray.java index ad3f7f8a..05b76381 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableIntArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableIntArray.java @@ -64,7 +64,7 @@ public UnsafeMutableIntArray unsafeSet(int index, int value) { } @Override - public int removeByInex(int index) { + public int removeByIndex(int index) { checkIndex(index); return unsafeRemoveByInex(index); } @@ -75,24 +75,47 @@ public boolean remove(int value) { if (index < 0) { return false; } - remove(index); + unsafeRemoveByInex(index); return true; } @Override - public int unsafeRemoveByInex(int index) { + public boolean removeAll(IntArray array) { + if (array.isEmpty()) { + return false; + } + int removed = 0; + for (int value : array) { + if (remove(value)) { + removed++; + } + } + return removed > 0; + } - int numMoved = size() - index - 1; + @Override + public boolean removeAll(int[] array) { + if (array.length < 1) { + return false; + } + int removed = 0; + for (int value : array) { + if (remove(value)) { + removed++; + } + } + return removed > 0; + } + @Override + public int unsafeRemoveByInex(int index) { + int numMoved = size() - index - 1; int[] wrapped = wrapped(); int value = wrapped[index]; - if (numMoved > 0) { System.arraycopy(wrapped, index + 1, wrapped, index, numMoved); } - wrapped[decrementAnGetSize()] = 0; - return value; } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableLongArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableLongArray.java index 85587c8c..30b53043 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableLongArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractMutableLongArray.java @@ -64,7 +64,7 @@ public UnsafeMutableLongArray unsafeSet(int index, long value) { } @Override - public long removeByInex(int index) { + public long removeByIndex(int index) { checkIndex(index); return unsafeRemoveByInex(index); } @@ -75,24 +75,47 @@ public boolean remove(long value) { if (index < 0) { return false; } - remove(index); + unsafeRemoveByInex(index); return true; } @Override - public long unsafeRemoveByInex(int index) { + public boolean removeAll(LongArray array) { + if (array.isEmpty()) { + return false; + } + int removed = 0; + for (long value : array) { + if (remove(value)) { + removed++; + } + } + return removed > 0; + } - int numMoved = size() - index - 1; + @Override + public boolean removeAll(long[] array) { + if (array.length < 1) { + return false; + } + int removed = 0; + for (long value : array) { + if (remove(value)) { + removed++; + } + } + return removed > 0; + } + @Override + public long unsafeRemoveByInex(int index) { + int numMoved = size() - index - 1; long[] wrapped = wrapped(); long value = wrapped[index]; - if (numMoved > 0) { System.arraycopy(wrapped, index + 1, wrapped, index, numMoved); } - wrapped[decrementAnGetSize()] = 0; - return value; } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java index ffb2d822..d3d5c54a 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java @@ -3,13 +3,16 @@ import java.util.function.BiConsumer; import java.util.function.BiPredicate; import javasabr.rlib.collections.array.ArrayIterationFunctions; +import javasabr.rlib.collections.array.ReversedArgsArrayIterationFunctions; import javasabr.rlib.collections.array.UnsafeArray; import javasabr.rlib.functions.ObjIntPredicate; import javasabr.rlib.functions.ObjObjLongConsumer; import javasabr.rlib.functions.TriConsumer; import org.jspecify.annotations.Nullable; -public record DefaultArrayIterationFunctions(UnsafeArray array) implements ArrayIterationFunctions { +public record DefaultArrayIterationFunctions( + UnsafeArray array, + ReversedArgsArrayIterationFunctions reversedArgs) implements ArrayIterationFunctions { @Override public @Nullable E findAny(T arg1, BiPredicate filter) { diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultReversedArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultReversedArgsArrayIterationFunctions.java similarity index 71% rename from rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultReversedArrayIterationFunctions.java rename to rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultReversedArgsArrayIterationFunctions.java index 20799ace..cd71f735 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultReversedArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultReversedArgsArrayIterationFunctions.java @@ -2,13 +2,13 @@ import java.util.function.BiConsumer; import java.util.function.BiPredicate; -import javasabr.rlib.collections.array.ReversedArrayIterationFunctions; +import javasabr.rlib.collections.array.ReversedArgsArrayIterationFunctions; import javasabr.rlib.collections.array.UnsafeArray; import javasabr.rlib.functions.TriConsumer; import org.jspecify.annotations.Nullable; -public record DefaultReversedArrayIterationFunctions(UnsafeArray array) implements - ReversedArrayIterationFunctions { +public record DefaultReversedArgsArrayIterationFunctions(UnsafeArray array) implements + ReversedArgsArrayIterationFunctions { @Override public @Nullable E findAny(T arg1, BiPredicate filter) { @@ -26,7 +26,7 @@ public record DefaultReversedArrayIterationFunctions(UnsafeArray array) im } @Override - public ReversedArrayIterationFunctions forEach(T arg1, BiConsumer consumer) { + public ReversedArgsArrayIterationFunctions forEach(T arg1, BiConsumer consumer) { @Nullable E[] wrapped = array.wrapped(); int size = array.size(); for (int i = 0; i < size; i++) { @@ -36,7 +36,7 @@ public ReversedArrayIterationFunctions forEach(T arg1, BiConsumer ReversedArrayIterationFunctions forEach(F arg1, S arg2, TriConsumer consumer) { + public ReversedArgsArrayIterationFunctions forEach(F arg1, S arg2, TriConsumer consumer) { @Nullable E[] wrapped = array.wrapped(); int size = array.size(); for (int i = 0; i < size; i++) { diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/ImmutableArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/ImmutableArray.java index 717ec00c..1b5baa8b 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/ImmutableArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/ImmutableArray.java @@ -2,6 +2,7 @@ import java.util.stream.Stream; import javasabr.rlib.collections.array.UnsafeArray; +import javasabr.rlib.common.util.ArrayUtils; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; import org.jspecify.annotations.Nullable; @@ -9,12 +10,84 @@ @FieldDefaults(level = AccessLevel.PROTECTED, makeFinal = true) public class ImmutableArray extends AbstractArray implements UnsafeArray { + public static ImmutableArray trustWrap(E[] array) { + return new ImmutableArray<>(array); + } + E[] wrapped; + private ImmutableArray(E[] wrapped) { + super((Class) wrapped.getClass().getComponentType()); + this.wrapped = wrapped; + } + + public ImmutableArray(Class type, E e1) { + super(type); + E[] array = ArrayUtils.create(type, 1); + array[0] = e1; + this.wrapped = array; + } + + public ImmutableArray(Class type, E e1, E e2) { + super(type); + E[] array = ArrayUtils.create(type, 2); + array[0] = e1; + array[1] = e2; + this.wrapped = array; + } + + public ImmutableArray(Class type, E e1, E e2, E e3) { + super(type); + E[] array = ArrayUtils.create(type, 3); + array[0] = e1; + array[1] = e2; + array[2] = e3; + this.wrapped = array; + } + + public ImmutableArray(Class type, E e1, E e2, E e3, E e4) { + super(type); + E[] array = ArrayUtils.create(type, 4); + array[0] = e1; + array[1] = e2; + array[2] = e3; + array[3] = e4; + this.wrapped = array; + } + + public ImmutableArray(Class type, E e1, E e2, E e3, E e4, E e5) { + super(type); + E[] array = ArrayUtils.create(type, 5); + array[0] = e1; + array[1] = e2; + array[2] = e3; + array[3] = e4; + array[4] = e5; + this.wrapped = array; + } + + public ImmutableArray(Class type, E e1, E e2, E e3, E e4, E e5, E e6) { + super(type); + E[] array = ArrayUtils.create(type, 6); + array[0] = e1; + array[1] = e2; + array[2] = e3; + array[3] = e4; + array[4] = e5; + array[5] = e6; + this.wrapped = array; + } + @SafeVarargs public ImmutableArray(Class type, E... elements) { super(type); - this.wrapped = elements; + if (ArrayUtils.getComponentType(elements) == type) { + this.wrapped = elements; + return; + } + E[] array = ArrayUtils.create(type, elements.length); + System.arraycopy(elements, 0, array, 0, elements.length); + this.wrapped = array; } @Override diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java index e9956e6f..9f4a7fc4 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java @@ -42,6 +42,50 @@ void arrayOfTest() { // then: Assertions.assertTrue(array.contains("Second")); Assertions.assertFalse(array.contains("test")); + + // when: + Array array1 = Array.of("First"); + Array array2 = Array.of("First", "Second"); + Array array3 = Array.of("First", "Second", "Third"); + Array array4 = Array.of("First", "Second", "Third", "Fourth"); + Array array5 = Array.of("First", "Second", "Third", "Fourth", "Fifth"); + Array array6 = Array.of("First", "Second", "Third", "Fourth", "Fifth", "Sixth"); + Array array7 = Array.of("First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh"); + Array array8 = Array.typed(String.class,"First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh"); + Array array9 = Array.of("First", "Second", 55, "Fourth", 20D, "Sixth", "Seventh"); + + // then: + assertThat(array1.toArray()) + .isEqualTo(new String[]{"First"}); + assertThat(array2.toArray()) + .isEqualTo(new String[]{"First", "Second"}); + assertThat(array3.toArray()) + .isEqualTo(new String[]{"First", "Second", "Third"}); + assertThat(array4.toArray()) + .isEqualTo(new String[]{"First", "Second", "Third", "Fourth"}); + assertThat(array5.toArray()) + .isEqualTo(new String[]{"First", "Second", "Third", "Fourth", "Fifth"}); + assertThat(array6.toArray()) + .isEqualTo(new String[]{"First", "Second", "Third", "Fourth", "Fifth", "Sixth"}); + assertThat(array7.toArray()) + .isEqualTo(new String[]{"First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh"}); + assertThat(array8.toArray()) + .isEqualTo(new String[]{"First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh"}); + assertThat(array9.toArray()) + .isEqualTo(new Object[]{"First", "Second", 55, "Fourth", 20D, "Sixth", "Seventh"}); + } + + @Test + void arrayRepeatedTest() { + // when: + Array array1 = Array.repeated("value", 4); + Array array2 = Array.repeated(20, 5); + + // then: + assertThat(array1.toArray()) + .isEqualTo(new String[]{"value", "value", "value", "value"}); + assertThat(array2.toArray()) + .isEqualTo(new Integer[]{20, 20, 20, 20, 20}); } @ParameterizedTest @@ -189,7 +233,7 @@ private static Stream generateArrays() { } private static Stream generateArraysWithDuplicates() { - Array array = Array.typed(String.class, "First", "Second", "Third", " ", "First", "Second", "Third"); + Array array = Array.of("First", "Second", "Third", " ", "First", "Second", "Third"); MutableArray mutableArray = ArrayFactory.mutableArray(String.class); mutableArray.addAll(array); MutableArray copyOnModifyArray = ArrayFactory.copyOnModifyArray(String.class); diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java new file mode 100644 index 00000000..57b4396d --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java @@ -0,0 +1,176 @@ +package javasabr.rlib.collections.array; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class MutableIntArrayTest { + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly add elements") + void shouldCorrectlyAddElements(MutableIntArray mutableArray) { + + // when: + mutableArray.add(10); + + // then: + Assertions.assertEquals(1, mutableArray.size()); + Assertions.assertEquals(10, mutableArray.get(0)); + + // when: + mutableArray.add(20); + + // then: + Assertions.assertEquals(2, mutableArray.size()); + Assertions.assertEquals(20, mutableArray.get(1)); + + // when: + mutableArray.add(30); + + // then: + Assertions.assertEquals(3, mutableArray.size()); + Assertions.assertEquals(30, mutableArray.get(2)); + Assertions.assertEquals(IntArray.of(10, 20, 30), mutableArray); + + // when: + for(int i = 0; i < 100; i++) { + mutableArray.add(100 + i); + } + + // then: + Assertions.assertEquals(103, mutableArray.size()); + Assertions.assertEquals(199, mutableArray.get(102)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly remove elements") + void shouldCorrectlyRemoveElements(MutableIntArray mutableArray) { + + // given: + for(int i = 0; i < 101; i++) { + mutableArray.add(100 + i); + } + + // when: + mutableArray.remove(100); + + // then: + Assertions.assertEquals(100, mutableArray.size()); + Assertions.assertEquals(101, mutableArray.get(0)); + + // when: + mutableArray.remove(110); + + // then: + Assertions.assertEquals(99, mutableArray.size()); + Assertions.assertEquals(101, mutableArray.get(0)); + Assertions.assertEquals(109, mutableArray.get(8)); + Assertions.assertEquals(111, mutableArray.get(9)); + + // when: + mutableArray.remove(200); + + // then: + Assertions.assertEquals(98, mutableArray.size()); + Assertions.assertEquals(199, mutableArray.get(97)); + Assertions.assertEquals(198, mutableArray.get(96)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly replace elements") + void shouldCorrectlyReplaceElements(MutableIntArray mutableArray) { + + // given: + for(int i = 0; i < 101; i++) { + mutableArray.add(100 + i); + } + + // when: + mutableArray.replace(0, 200); + + // then: + Assertions.assertEquals(101, mutableArray.size()); + Assertions.assertEquals(200, mutableArray.get(0)); + + // when: + mutableArray.replace(11, 211); + + // then: + Assertions.assertEquals(101, mutableArray.size()); + Assertions.assertEquals(211, mutableArray.get(11)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly add batch elements") + void shouldCorrectlyAddBatchElements(MutableIntArray mutableArray) { + + // given: + for(int i = 0; i < 21; i++) { + mutableArray.add(100 + i); + } + + var anotherArray = IntArray.of(31, 32, 33, 34, 35, 36); + var anotherNativeArray = new int[] {41, 42, 43, 44, 45, 46}; + + // when: + mutableArray.addAll(anotherArray); + + // then: + Assertions.assertEquals(27, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + Assertions.assertEquals(31, mutableArray.get(21)); + Assertions.assertEquals(36, mutableArray.get(26)); + + // when: + mutableArray.addAll(anotherNativeArray); + + // then: + Assertions.assertEquals(33, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + Assertions.assertEquals(31, mutableArray.get(21)); + Assertions.assertEquals(36, mutableArray.get(26)); + Assertions.assertEquals(41, mutableArray.get(27)); + Assertions.assertEquals(46, mutableArray.get(32)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly remove batch elements") + void shouldCorrectlyRemoveBatchElements(MutableIntArray mutableArray) { + + // given: + for(int i = 0; i < 21; i++) { + mutableArray.add(100 + i); + } + + var anotherArray = IntArray.of(31, 32, 33, 34, 35, 36); + var anotherNativeArray = new int[] {41, 42, 43, 44, 45, 46}; + + mutableArray.addAll(anotherArray); + mutableArray.addAll(anotherNativeArray); + + // when: + mutableArray.removeAll(anotherArray); + + // then: + Assertions.assertEquals(27, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + Assertions.assertEquals(41, mutableArray.get(21)); + Assertions.assertEquals(46, mutableArray.get(26)); + } + + private static Stream generateMutableArrays() { + return Stream.of( + Arguments.of(ArrayFactory.mutableIntArray())); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java new file mode 100644 index 00000000..c76ec0cd --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java @@ -0,0 +1,176 @@ +package javasabr.rlib.collections.array; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class MutableLongArrayTest { + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly add elements") + void shouldCorrectlyAddElements(MutableLongArray mutableArray) { + + // when: + mutableArray.add(10); + + // then: + Assertions.assertEquals(1, mutableArray.size()); + Assertions.assertEquals(10, mutableArray.get(0)); + + // when: + mutableArray.add(20); + + // then: + Assertions.assertEquals(2, mutableArray.size()); + Assertions.assertEquals(20, mutableArray.get(1)); + + // when: + mutableArray.add(30); + + // then: + Assertions.assertEquals(3, mutableArray.size()); + Assertions.assertEquals(30, mutableArray.get(2)); + Assertions.assertEquals(LongArray.of(10, 20, 30), mutableArray); + + // when: + for(int i = 0; i < 100; i++) { + mutableArray.add(100 + i); + } + + // then: + Assertions.assertEquals(103, mutableArray.size()); + Assertions.assertEquals(199, mutableArray.get(102)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly remove elements") + void shouldCorrectlyRemoveElements(MutableLongArray mutableArray) { + + // given: + for(int i = 0; i < 101; i++) { + mutableArray.add(100 + i); + } + + // when: + mutableArray.remove(100); + + // then: + Assertions.assertEquals(100, mutableArray.size()); + Assertions.assertEquals(101, mutableArray.get(0)); + + // when: + mutableArray.remove(110); + + // then: + Assertions.assertEquals(99, mutableArray.size()); + Assertions.assertEquals(101, mutableArray.get(0)); + Assertions.assertEquals(109, mutableArray.get(8)); + Assertions.assertEquals(111, mutableArray.get(9)); + + // when: + mutableArray.remove(200); + + // then: + Assertions.assertEquals(98, mutableArray.size()); + Assertions.assertEquals(199, mutableArray.get(97)); + Assertions.assertEquals(198, mutableArray.get(96)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly replace elements") + void shouldCorrectlyReplaceElements(MutableLongArray mutableArray) { + + // given: + for(int i = 0; i < 101; i++) { + mutableArray.add(100 + i); + } + + // when: + mutableArray.replace(0, 200); + + // then: + Assertions.assertEquals(101, mutableArray.size()); + Assertions.assertEquals(200, mutableArray.get(0)); + + // when: + mutableArray.replace(11, 211); + + // then: + Assertions.assertEquals(101, mutableArray.size()); + Assertions.assertEquals(211, mutableArray.get(11)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly add batch elements") + void shouldCorrectlyAddBatchElements(MutableLongArray mutableArray) { + + // given: + for(int i = 0; i < 21; i++) { + mutableArray.add(100 + i); + } + + var anotherArray = LongArray.of(31, 32, 33, 34, 35, 36); + var anotherNativeArray = new long[] {41, 42, 43, 44, 45, 46}; + + // when: + mutableArray.addAll(anotherArray); + + // then: + Assertions.assertEquals(27, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + Assertions.assertEquals(31, mutableArray.get(21)); + Assertions.assertEquals(36, mutableArray.get(26)); + + // when: + mutableArray.addAll(anotherNativeArray); + + // then: + Assertions.assertEquals(33, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + Assertions.assertEquals(31, mutableArray.get(21)); + Assertions.assertEquals(36, mutableArray.get(26)); + Assertions.assertEquals(41, mutableArray.get(27)); + Assertions.assertEquals(46, mutableArray.get(32)); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should correctly remove batch elements") + void shouldCorrectlyRemoveBatchElements(MutableLongArray mutableArray) { + + // given: + for(int i = 0; i < 21; i++) { + mutableArray.add(100 + i); + } + + var anotherArray = LongArray.of(31, 32, 33, 34, 35, 36); + var anotherNativeArray = new long[] {41, 42, 43, 44, 45, 46}; + + mutableArray.addAll(anotherArray); + mutableArray.addAll(anotherNativeArray); + + // when: + mutableArray.removeAll(anotherArray); + + // then: + Assertions.assertEquals(27, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + Assertions.assertEquals(41, mutableArray.get(21)); + Assertions.assertEquals(46, mutableArray.get(26)); + } + + private static Stream generateMutableArrays() { + return Stream.of( + Arguments.of(ArrayFactory.mutableLongArray())); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java index c6555f44..5b44a6f1 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java @@ -14,7 +14,8 @@ class ReversedArrayIterationsTest { void shouldFindAnyCorrectly(Array array) { // when/then: Assertions.assertNull(array - .reversedIterations() + .iterations() + .reversedArgs() .findAny("notexist", Objects::equals)); Assertions.assertNotNull(array .iterations() @@ -34,7 +35,8 @@ void shouldDoForEachCorrectly(Array array) { "prefix_5"); // when: - array.reversedIterations() + array.iterations() + .reversedArgs() .forEach("prefix_", (arg1, element) -> result.add(arg1 + element)); // then: @@ -54,7 +56,9 @@ void shouldDoForEach2Correctly(Array array) { "prefix__middle_5"); // when: - array.reversedIterations() + array + .iterations() + .reversedArgs() .forEach("prefix_", "_middle_", (arg1, arg2, element) -> result.add(arg1 + arg2 + element)); // then: @@ -66,10 +70,12 @@ void shouldDoForEach2Correctly(Array array) { void shouldAnyMatchCorrectly(Array array) { // when/then: Assertions.assertFalse(array - .reversedIterations() + .iterations() + .reversedArgs() .anyMatch("10", String::equals)); Assertions.assertTrue(array - .reversedIterations() + .iterations() + .reversedArgs() .anyMatch("5", String::equals)); } diff --git a/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java b/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java index 2a870f44..029f506e 100644 --- a/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java +++ b/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java @@ -663,15 +663,35 @@ public static String toString(int @Nullable [] array) { */ public static String toString( int @Nullable [] array, - final String separator, - final boolean needType, - final boolean needBrackets) { + String separator, + boolean needType, + boolean needBrackets) { + int length = array == null ? 0 : array.length; + return toString(array, 0, length, separator, needType, needBrackets); + } + + /** + * Convert the array to a string presentation. + * + * @param array the array. + * @param separator the separator. + * @param needType true if need adding type of array. + * @param needBrackets true if need adding brackets. + * @return the string presentation of the array. + */ + public static String toString( + int @Nullable [] array, + int offset, + int length, + String separator, + boolean needType, + boolean needBrackets) { if (array == null) { array = EMPTY_INT_ARRAY; } - final StringBuilder builder = new StringBuilder(); + StringBuilder builder = new StringBuilder(); if (needType) { builder.append("int"); @@ -680,9 +700,54 @@ public static String toString( builder.append('['); } - for (int i = 0, length = array.length - 1; i <= length; i++) { - builder.append(String.valueOf(array[i])); - if (i == length) { + for (int i = offset, limit = offset + length - 1; i <= limit; i++) { + builder.append(array[i]); + if (i == limit) { + break; + } + builder.append(separator); + } + + if (needBrackets) { + builder.append(']'); + } + + return builder.toString(); + } + + /** + * Convert the array to a string presentation. + * + * @param array the array. + * @param separator the separator. + * @param needType true if need adding type of array. + * @param needBrackets true if need adding brackets. + * @return the string presentation of the array. + */ + public static String toString( + long @Nullable [] array, + int offset, + int length, + String separator, + boolean needType, + boolean needBrackets) { + + if (array == null) { + array = EMPTY_LONG_ARRAY; + } + + StringBuilder builder = new StringBuilder(); + + if (needType) { + builder.append("int"); + } + if (needBrackets) { + builder.append('['); + } + + for (int i = offset, limit = offset + length - 1; i <= limit; i++) { + builder.append(array[i]); + if (i == limit) { break; } builder.append(separator); diff --git a/rlib-common/src/main/java/javasabr/rlib/common/util/ClassUtils.java b/rlib-common/src/main/java/javasabr/rlib/common/util/ClassUtils.java index 54763194..f7c54be4 100644 --- a/rlib-common/src/main/java/javasabr/rlib/common/util/ClassUtils.java +++ b/rlib-common/src/main/java/javasabr/rlib/common/util/ClassUtils.java @@ -17,6 +17,69 @@ @NullMarked public final class ClassUtils { + public static Class commonType(E e1, E e2) { + Class type = e1.getClass(); + while (!type.isInstance(e2)) { + type = type.getSuperclass(); + } + return (Class) type; + } + + public static Class commonType(E e1, E e2, E e3) { + Class type = e1.getClass(); + while (!type.isInstance(e2) || !type.isInstance(e3)) { + type = type.getSuperclass(); + } + return (Class) type; + } + + public static Class commonType(E e1, E e2, E e3, E e4) { + Class type = e1.getClass(); + while (!type.isInstance(e2) || !type.isInstance(e3) || !type.isInstance(e4)) { + type = type.getSuperclass(); + } + return (Class) type; + } + + public static Class commonType(E e1, E e2, E e3, E e4, E e5) { + Class type = e1.getClass(); + while (!type.isInstance(e2) || !type.isInstance(e3) || !type.isInstance(e4) || !type.isInstance(e5)) { + type = type.getSuperclass(); + } + return (Class) type; + } + + public static Class commonType(E e1, E e2, E e3, E e4, E e5, E e6) { + Class type = e1.getClass(); + while (!type.isInstance(e2) || !type.isInstance(e3) || !type.isInstance(e4) || !type.isInstance(e5) || !type.isInstance(e6)) { + type = type.getSuperclass(); + } + return (Class) type; + } + + public static Class commonType(Object... objects) { + if (objects.length < 1) { + return Object.class; + } + Class type = objects[0].getClass(); + if (objects.length < 2) { + return type; + } + while (!isCommonType(type, objects, 1)) { + type = type.getSuperclass(); + } + return type; + } + + private static boolean isCommonType(Class type, Object[] objects, int offset) { + for (int i = offset; i < objects.length; i++) { + if (!type.isInstance(objects[i])) { + return false; + } + } + return true; + } + /** * Try to find a class by name. * diff --git a/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java b/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java index 612298dd..8ccfd169 100644 --- a/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java +++ b/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java @@ -36,6 +36,11 @@ public T resolve(int number) { } } + public T resolve(int number, T def) { + T resolved = resolve(number); + return resolved == null ? def : resolved; + } + public T require(int number) { T constant = resolve(number); if (constant == null) { diff --git a/rlib-common/src/test/java/javasabr/rlib/common/util/ClassUtilsTest.java b/rlib-common/src/test/java/javasabr/rlib/common/util/ClassUtilsTest.java new file mode 100644 index 00000000..1d9c26fd --- /dev/null +++ b/rlib-common/src/test/java/javasabr/rlib/common/util/ClassUtilsTest.java @@ -0,0 +1,192 @@ +package javasabr.rlib.common.util; + +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +class ClassUtilsTest { + + @Test + void shouldResolveCommonTypeWith2Args() { + // when: + Class commonType = ClassUtils.commonType("val1", "val2"); + + // then: + Assertions.assertThat(commonType).isEqualTo(String.class); + + // when: + commonType = ClassUtils.commonType("val1", 50); + + // then: + Assertions.assertThat(commonType).isEqualTo(Object.class); + + // when: + commonType = ClassUtils.commonType(15D, 50); + + // then: + Assertions.assertThat(commonType).isEqualTo(Number.class); + } + + @Test + void shouldResolveCommonTypeWith3Args() { + // when: + Class commonType = ClassUtils.commonType("val1", "val2", "val3"); + + // then: + Assertions.assertThat(commonType).isEqualTo(String.class); + + // when: + commonType = ClassUtils.commonType("val1", 50, "val3"); + + // then: + Assertions.assertThat(commonType).isEqualTo(Object.class); + + // when: + commonType = ClassUtils.commonType(15D, 50, 60F); + + // then: + Assertions.assertThat(commonType).isEqualTo(Number.class); + + // when: + commonType = ClassUtils.commonType( + new HashMap<>(), + new TreeMap<>(), + new ConcurrentHashMap<>()); + + // then: + Assertions.assertThat(commonType).isEqualTo(AbstractMap.class); + } + + @Test + void shouldResolveCommonTypeWith4Args() { + // when: + Class commonType = ClassUtils.commonType("val1", "val2", "val3", "val4"); + + // then: + Assertions.assertThat(commonType).isEqualTo(String.class); + + // when: + commonType = ClassUtils.commonType("val1", 50, "val3", 25D); + + // then: + Assertions.assertThat(commonType).isEqualTo(Object.class); + + // when: + commonType = ClassUtils.commonType(15D, 50, 60F, 25); + + // then: + Assertions.assertThat(commonType).isEqualTo(Number.class); + + // when: + commonType = ClassUtils.commonType( + new HashMap<>(), + new TreeMap<>(), + new ConcurrentHashMap<>(), + new HashMap<>()); + + // then: + Assertions.assertThat(commonType).isEqualTo(AbstractMap.class); + } + + @Test + void shouldResolveCommonTypeWith5Args() { + // when: + Class commonType = ClassUtils.commonType("val1", "val2", "val3", "val4", "val5"); + + // then: + Assertions.assertThat(commonType).isEqualTo(String.class); + + // when: + commonType = ClassUtils.commonType("val1", 50, "val3", 25D, 15); + + // then: + Assertions.assertThat(commonType).isEqualTo(Object.class); + + // when: + commonType = ClassUtils.commonType(15D, 50, 60F, 25, 22D); + + // then: + Assertions.assertThat(commonType).isEqualTo(Number.class); + + // when: + commonType = ClassUtils.commonType( + new HashMap<>(), + new TreeMap<>(), + new ConcurrentHashMap<>(), + new HashMap<>(), + new TreeMap<>()); + + // then: + Assertions.assertThat(commonType).isEqualTo(AbstractMap.class); + } + + @Test + void shouldResolveCommonTypeWith6Args() { + // when: + Class commonType = ClassUtils.commonType("val1", "val2", "val3", "val4", "val5", "val6"); + + // then: + Assertions.assertThat(commonType).isEqualTo(String.class); + + // when: + commonType = ClassUtils.commonType("val1", 50, "val3", 25D, 15, "val6"); + + // then: + Assertions.assertThat(commonType).isEqualTo(Object.class); + + // when: + commonType = ClassUtils.commonType(15D, 50, 60F, 25, 22D, 33); + + // then: + Assertions.assertThat(commonType).isEqualTo(Number.class); + + // when: + commonType = ClassUtils.commonType( + new HashMap<>(), + new TreeMap<>(), + new ConcurrentHashMap<>(), + new HashMap<>(), + new TreeMap<>(), + new ConcurrentHashMap<>()); + + // then: + Assertions.assertThat(commonType).isEqualTo(AbstractMap.class); + } + + @Test + void shouldResolveCommonTypeWithVarargs() { + // when: + Class commonType = ClassUtils.commonType("val1", "val2", "val3", "val4", "val5", "val6", "val7"); + + // then: + Assertions.assertThat(commonType).isEqualTo(String.class); + + // when: + commonType = ClassUtils.commonType("val1", 50, "val3", 25D, 15, "val6", 13F); + + // then: + Assertions.assertThat(commonType).isEqualTo(Object.class); + + // when: + commonType = ClassUtils.commonType(15D, 50, 60F, 25, 22D, 33, 77F); + + // then: + Assertions.assertThat(commonType).isEqualTo(Number.class); + + // when: + commonType = ClassUtils.commonType( + new HashMap<>(), + new TreeMap<>(), + new ConcurrentHashMap<>(), + new HashMap<>(), + new TreeMap<>(), + new ConcurrentHashMap<>(), + new HashMap<>()); + + // then: + Assertions.assertThat(commonType).isEqualTo(AbstractMap.class); + } +} diff --git a/rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java b/rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java index 35b79730..8a68335d 100644 --- a/rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java +++ b/rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java @@ -39,6 +39,7 @@ void shouldResolveEnumByNumber() { assertThat(TestEnum.MAP.resolve(900)).isNull(); assertThat(TestEnum.MAP.resolve(-50)).isNull(); assertThat(TestEnum.MAP.resolve(24)).isNull(); + assertThat(TestEnum.MAP.resolve(24, TestEnum.CONSTANT4)).isEqualTo(TestEnum.CONSTANT4); } @Test diff --git a/rlib-io/src/main/java/javasabr/rlib/io/util/FileUtils.java b/rlib-io/src/main/java/javasabr/rlib/io/util/FileUtils.java index a3f1d611..b0a7e422 100644 --- a/rlib-io/src/main/java/javasabr/rlib/io/util/FileUtils.java +++ b/rlib-io/src/main/java/javasabr/rlib/io/util/FileUtils.java @@ -239,7 +239,8 @@ public static boolean hasExtensions(String path, String @Nullable [] extensions) public static boolean hasExtensions(String path, @Nullable Array extensions) { return extensions != null && extensions - .reversedIterations() + .iterations() + .reversedArgs() .anyMatch(path, String::endsWith); } From 33f64ed19e6c9f1b854e87847f78cb1f1c957d83 Mon Sep 17 00:00:00 2001 From: javasabr Date: Sun, 9 Nov 2025 19:35:28 +0100 Subject: [PATCH 2/3] add more tests --- .../rlib/collections/array/IntArray.java | 9 ++ .../rlib/collections/array/LongArray.java | 9 ++ .../array/impl/AbstractIntArray.java | 18 ++- .../array/impl/AbstractLongArray.java | 18 ++- .../rlib/collections/array/ArrayTest.java | 26 --- .../rlib/collections/array/IntArrayTest.java | 148 ++++++++++++++++++ .../rlib/collections/array/LongArrayTest.java | 147 +++++++++++++++++ .../collections/array/MutableArrayTest.java | 27 +++- .../array/MutableIntArrayTest.java | 27 +++- .../array/MutableLongArrayTest.java | 27 +++- 10 files changed, 406 insertions(+), 50 deletions(-) create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/array/IntArrayTest.java create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/array/LongArrayTest.java diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java index 9cd085a1..268f2381 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java @@ -1,6 +1,7 @@ package javasabr.rlib.collections.array; import java.io.Serializable; +import java.util.Arrays; import java.util.RandomAccess; import java.util.stream.IntStream; import javasabr.rlib.collections.array.impl.ImmutableIntArray; @@ -40,12 +41,20 @@ static IntArray copyOf(IntArray intArray) { return new ImmutableIntArray(intArray.toArray()); } + static IntArray repeated(int value, int count) { + int[] values = new int[count]; + Arrays.fill(values, value); + return new ImmutableIntArray(values); + } + int size(); boolean contains(int value); boolean containsAll(IntArray array); + boolean containsAll(int[] array); + /** * @return the first element or {@link java.util.NoSuchElementException} */ diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java index d3c57f50..10db626e 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java @@ -1,6 +1,7 @@ package javasabr.rlib.collections.array; import java.io.Serializable; +import java.util.Arrays; import java.util.RandomAccess; import java.util.stream.LongStream; import javasabr.rlib.collections.array.impl.ImmutableLongArray; @@ -40,12 +41,20 @@ static LongArray copyOf(LongArray intArray) { return new ImmutableLongArray(intArray.toArray()); } + static LongArray repeated(long value, int count) { + long[] values = new long[count]; + Arrays.fill(values, value); + return new ImmutableLongArray(values); + } + int size(); boolean contains(long value); boolean containsAll(LongArray array); + boolean containsAll(long[] array); + /** * @return the first element or {@link java.util.NoSuchElementException} */ diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java index 60acf4b1..e493b9d9 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractIntArray.java @@ -64,10 +64,7 @@ public boolean containsAll(IntArray array) { return false; } - int[] wrapped = array - .asUnsafe() - .wrapped(); - + int[] wrapped = array.asUnsafe().wrapped(); for (int i = 0, length = array.size(); i < length; i++) { if (!contains(wrapped[i])) { return false; @@ -77,6 +74,19 @@ public boolean containsAll(IntArray array) { return true; } + @Override + public boolean containsAll(int[] array) { + if (array.length < 1) { + return false; + } + for (int value : array) { + if (!contains(value)) { + return false; + } + } + return true; + } + @Override public int indexOf(int value) { int[] wrapped = wrapped(); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java index f4b44645..5b340d94 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLongArray.java @@ -63,17 +63,25 @@ public boolean containsAll(LongArray array) { if (array.isEmpty()) { return false; } - - long[] wrapped = array - .asUnsafe() - .wrapped(); - + long[] wrapped = array.asUnsafe().wrapped(); for (int i = 0, length = array.size(); i < length; i++) { if (!contains(wrapped[i])) { return false; } } + return true; + } + @Override + public boolean containsAll(long[] array) { + if (array.length < 1) { + return false; + } + for (long value : array) { + if (!contains(value)) { + return false; + } + } return true; } diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java index 9f4a7fc4..3c71f479 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java @@ -17,32 +17,6 @@ public class ArrayTest { @Test void arrayOfTest() { - - // when: - Array array = Array.of("First", "Second", "Third", " "); - - // then: - Assertions.assertEquals(4, array.size()); - Assertions.assertEquals("First", array.get(0)); - Assertions.assertEquals("Second", array.get(1)); - Assertions.assertEquals("Third", array.get(2)); - Assertions.assertEquals(" ", array.get(3)); - Assertions.assertEquals("First", array.first()); - Assertions.assertEquals(" ", array.last()); - - // then: - Assertions.assertArrayEquals( - new String[]{ - "First", - "Second", - "Third", - " " - }, array.stream().toArray()); - - // then: - Assertions.assertTrue(array.contains("Second")); - Assertions.assertFalse(array.contains("test")); - // when: Array array1 = Array.of("First"); Array array2 = Array.of("First", "Second"); diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/IntArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/IntArrayTest.java new file mode 100644 index 00000000..f5360900 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/IntArrayTest.java @@ -0,0 +1,148 @@ +package javasabr.rlib.collections.array; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * @author JavaSaBr + */ +public class IntArrayTest { + + @Test + void arrayOfTest() { + // when: + IntArray array1 = IntArray.of(5); + IntArray array2 = IntArray.of(5, 8); + IntArray array3 = IntArray.of(5, 8, 13); + IntArray array4 = IntArray.of(5, 8, 13, 25); + IntArray array5 = IntArray.of(5, 8, 13, 25, 33); + + // then: + assertThat(array1.toArray()) + .isEqualTo(new int[]{5}); + assertThat(array2.toArray()) + .isEqualTo(new int[]{5, 8}); + assertThat(array3.toArray()) + .isEqualTo(new int[]{5, 8, 13}); + assertThat(array4.toArray()) + .isEqualTo(new int[]{5, 8, 13, 25}); + assertThat(array5.toArray()) + .isEqualTo(new int[]{5, 8, 13, 25, 33}); + } + + @Test + void arrayRepeatedTest() { + // when: + IntArray repeated = IntArray.repeated(20, 5); + + // then: + assertThat(repeated.toArray()) + .isEqualTo(new int[]{20, 20, 20, 20, 20}); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyTakeValues(IntArray array) { + + // then: + Assertions.assertEquals(4, array.size()); + Assertions.assertEquals(5, array.get(0)); + Assertions.assertEquals(8, array.get(1)); + Assertions.assertEquals(13, array.get(2)); + Assertions.assertEquals(25, array.get(3)); + Assertions.assertEquals(5, array.first()); + Assertions.assertEquals(25, array.last()); + + // then: + Assertions.assertArrayEquals(new int[]{5, 8, 13, 25}, array.stream().toArray()); + + // then: + Assertions.assertTrue(array.contains(8)); + Assertions.assertFalse(array.contains(99)); + } + + @ParameterizedTest + @MethodSource("generateArraysWithDuplicates") + void shouldFindElementIndex(IntArray array) { + // when/then: + Assertions.assertEquals(0, array.indexOf(5)); + Assertions.assertEquals(3, array.indexOf(25)); + Assertions.assertEquals(-1, array.indexOf(99)); + } + + @ParameterizedTest + @MethodSource("generateArraysWithDuplicates") + void shouldFindLastElementIndex(IntArray array) { + // when/then: + Assertions.assertEquals(4, array.lastIndexOf(5)); + Assertions.assertEquals(6, array.lastIndexOf(13)); + Assertions.assertEquals(-1, array.lastIndexOf(99)); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyTransformToNativeArray(IntArray array) { + // when/then: + Assertions.assertArrayEquals(new int[]{5, 8, 13, 25}, array.stream().toArray()); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContains(IntArray array) { + // when/then: + assertThat(array.contains(5)).isTrue(); + assertThat(array.contains(25)).isTrue(); + assertThat(array.contains(99)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContainsAllByArray(IntArray array) { + // given: + IntArray check1 = IntArray.of(5); + IntArray check2 = IntArray.of(8, 13); + IntArray check3 = IntArray.of(8, 13, 99); + // when/then: + assertThat(array.containsAll(check1)).isTrue(); + assertThat(array.containsAll(check2)).isTrue(); + assertThat(array.containsAll(check3)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContainsAllByNativeArray(IntArray array) { + // given: + int[] check1 = new int[]{5}; + int[] check2 = new int[]{8, 13}; + int[] check3 = new int[]{8, 13, 99}; + // when/then: + assertThat(array.containsAll(check1)).isTrue(); + assertThat(array.containsAll(check2)).isTrue(); + assertThat(array.containsAll(check3)).isFalse(); + } + + private static Stream generateArrays() { + IntArray array = IntArray.of(5, 8, 13, 25); + MutableIntArray mutableArray = ArrayFactory.mutableIntArray(); + mutableArray.addAll(array); + return Stream.of( + Arguments.of(array), + Arguments.of(mutableArray)); + } + + private static Stream generateArraysWithDuplicates() { + IntArray array = IntArray.of(5, 8, 13, 25, 5, 8, 13); + MutableIntArray mutableArray = ArrayFactory.mutableIntArray(); + mutableArray.addAll(array); + return Stream.of( + Arguments.of(array), + Arguments.of(mutableArray)); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/LongArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/LongArrayTest.java new file mode 100644 index 00000000..12145ec4 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/LongArrayTest.java @@ -0,0 +1,147 @@ +package javasabr.rlib.collections.array; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * @author JavaSaBr + */ +public class LongArrayTest { + + @Test + void arrayOfTest() { + // when: + LongArray array1 = LongArray.of(5); + LongArray array2 = LongArray.of(5, 8); + LongArray array3 = LongArray.of(5, 8, 13); + LongArray array4 = LongArray.of(5, 8, 13, 25); + LongArray array5 = LongArray.of(5, 8, 13, 25, 33); + + // then: + assertThat(array1.toArray()) + .isEqualTo(new long[]{5}); + assertThat(array2.toArray()) + .isEqualTo(new long[]{5, 8}); + assertThat(array3.toArray()) + .isEqualTo(new long[]{5, 8, 13}); + assertThat(array4.toArray()) + .isEqualTo(new long[]{5, 8, 13, 25}); + assertThat(array5.toArray()) + .isEqualTo(new long[]{5, 8, 13, 25, 33}); + } + + @Test + void arrayRepeatedTest() { + // when: + LongArray repeated = LongArray.repeated(20, 5); + + // then: + assertThat(repeated.toArray()) + .isEqualTo(new long[]{20, 20, 20, 20, 20}); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyTakeValues(LongArray array) { + + // then: + Assertions.assertEquals(4, array.size()); + Assertions.assertEquals(5, array.get(0)); + Assertions.assertEquals(8, array.get(1)); + Assertions.assertEquals(13, array.get(2)); + Assertions.assertEquals(25, array.get(3)); + Assertions.assertEquals(5, array.first()); + Assertions.assertEquals(25, array.last()); + + // then: + Assertions.assertArrayEquals(new long[]{5, 8, 13, 25}, array.stream().toArray()); + + // then: + Assertions.assertTrue(array.contains(8)); + Assertions.assertFalse(array.contains(99)); + } + + @ParameterizedTest + @MethodSource("generateArraysWithDuplicates") + void shouldFindElementIndex(LongArray array) { + // when/then: + Assertions.assertEquals(0, array.indexOf(5)); + Assertions.assertEquals(3, array.indexOf(25)); + Assertions.assertEquals(-1, array.indexOf(99)); + } + + @ParameterizedTest + @MethodSource("generateArraysWithDuplicates") + void shouldFindLastElementIndex(LongArray array) { + // when/then: + Assertions.assertEquals(4, array.lastIndexOf(5)); + Assertions.assertEquals(6, array.lastIndexOf(13)); + Assertions.assertEquals(-1, array.lastIndexOf(99)); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyTransformToNativeArray(LongArray array) { + // when/then: + Assertions.assertArrayEquals(new long[]{5, 8, 13, 25}, array.stream().toArray()); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContains(LongArray array) { + // when/then: + assertThat(array.contains(5)).isTrue(); + assertThat(array.contains(25)).isTrue(); + assertThat(array.contains(99)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContainsAllByArray(LongArray array) { + // given: + LongArray check1 = LongArray.of(5); + LongArray check2 = LongArray.of(8, 13); + LongArray check3 = LongArray.of(8, 13, 99); + // when/then: + assertThat(array.containsAll(check1)).isTrue(); + assertThat(array.containsAll(check2)).isTrue(); + assertThat(array.containsAll(check3)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContainsAllByNativeArray(LongArray array) { + // given: + long[] check1 = new long[]{5}; + long[] check2 = new long[]{8, 13}; + long[] check3 = new long[]{8, 13, 99}; + // when/then: + assertThat(array.containsAll(check1)).isTrue(); + assertThat(array.containsAll(check2)).isTrue(); + assertThat(array.containsAll(check3)).isFalse(); + } + + private static Stream generateArrays() { + LongArray array = LongArray.of(5, 8, 13, 25); + MutableLongArray mutableArray = ArrayFactory.mutableLongArray(); + mutableArray.addAll(array); + return Stream.of( + Arguments.of(array), + Arguments.of(mutableArray)); + } + + private static Stream generateArraysWithDuplicates() { + LongArray array = LongArray.of(5, 8, 13, 25, 5, 8, 13); + MutableLongArray mutableArray = ArrayFactory.mutableLongArray(); + mutableArray.addAll(array); + return Stream.of( + Arguments.of(array), + Arguments.of(mutableArray)); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java index 02b35dfb..4f6876a5 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java @@ -14,7 +14,6 @@ class MutableArrayTest { @MethodSource("generateMutableArrays") @DisplayName("should correctly add elements") void shouldCorrectlyAddElements(MutableArray mutableArray) { - // when: mutableArray.add("First"); @@ -51,7 +50,6 @@ void shouldCorrectlyAddElements(MutableArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly remove elements") void shouldCorrectlyRemoveElements(MutableArray mutableArray) { - // given: for(int i = 0; i < 101; i++) { mutableArray.add("value_" + i); @@ -86,7 +84,6 @@ void shouldCorrectlyRemoveElements(MutableArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly replace elements") void shouldCorrectlyReplaceElements(MutableArray mutableArray) { - // given: for(int i = 0; i < 101; i++) { mutableArray.add("value_" + i); @@ -111,7 +108,6 @@ void shouldCorrectlyReplaceElements(MutableArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly add batch elements") void shouldCorrectlyAddBatchElements(MutableArray mutableArray) { - // given: for(int i = 0; i < 21; i++) { mutableArray.add("value_" + i); @@ -163,7 +159,6 @@ void shouldCorrectlyAddBatchElements(MutableArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly remove batch elements") void shouldCorrectlyRemoveBatchElements(MutableArray mutableArray) { - // given: for(int i = 0; i < 21; i++) { mutableArray.add("value_" + i); @@ -191,6 +186,28 @@ void shouldCorrectlyRemoveBatchElements(MutableArray mutableArray) { Assertions.assertEquals("na6", mutableArray.get(32)); } + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should clear array") + void shouldClearArray(MutableArray mutableArray) { + // when: + for(int i = 0; i < 21; i++) { + mutableArray.add("value_" + i); + } + + // then: + Assertions.assertEquals(21, mutableArray.size()); + Assertions.assertEquals("value_0", mutableArray.get(0)); + Assertions.assertEquals("value_20", mutableArray.get(20)); + + // when: + mutableArray.clear(); + + // then: + Assertions.assertEquals(0, mutableArray.size()); + Assertions.assertArrayEquals(new String[0], mutableArray.toArray()); + } + private static Stream generateMutableArrays() { return Stream.of( Arguments.of(ArrayFactory.mutableArray(String.class)), diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java index 57b4396d..e3ceac1c 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java @@ -13,7 +13,6 @@ class MutableIntArrayTest { @MethodSource("generateMutableArrays") @DisplayName("should correctly add elements") void shouldCorrectlyAddElements(MutableIntArray mutableArray) { - // when: mutableArray.add(10); @@ -50,7 +49,6 @@ void shouldCorrectlyAddElements(MutableIntArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly remove elements") void shouldCorrectlyRemoveElements(MutableIntArray mutableArray) { - // given: for(int i = 0; i < 101; i++) { mutableArray.add(100 + i); @@ -85,7 +83,6 @@ void shouldCorrectlyRemoveElements(MutableIntArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly replace elements") void shouldCorrectlyReplaceElements(MutableIntArray mutableArray) { - // given: for(int i = 0; i < 101; i++) { mutableArray.add(100 + i); @@ -110,7 +107,6 @@ void shouldCorrectlyReplaceElements(MutableIntArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly add batch elements") void shouldCorrectlyAddBatchElements(MutableIntArray mutableArray) { - // given: for(int i = 0; i < 21; i++) { mutableArray.add(100 + i); @@ -146,7 +142,6 @@ void shouldCorrectlyAddBatchElements(MutableIntArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly remove batch elements") void shouldCorrectlyRemoveBatchElements(MutableIntArray mutableArray) { - // given: for(int i = 0; i < 21; i++) { mutableArray.add(100 + i); @@ -169,6 +164,28 @@ void shouldCorrectlyRemoveBatchElements(MutableIntArray mutableArray) { Assertions.assertEquals(46, mutableArray.get(26)); } + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should clear array") + void shouldClearArray(MutableIntArray mutableArray) { + // when: + for(int i = 0; i < 21; i++) { + mutableArray.add(100 + i); + } + + // then: + Assertions.assertEquals(21, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + + // when: + mutableArray.clear(); + + // then: + Assertions.assertEquals(0, mutableArray.size()); + Assertions.assertArrayEquals(new int[0], mutableArray.toArray()); + } + private static Stream generateMutableArrays() { return Stream.of( Arguments.of(ArrayFactory.mutableIntArray())); diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java index c76ec0cd..e307467a 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java @@ -13,7 +13,6 @@ class MutableLongArrayTest { @MethodSource("generateMutableArrays") @DisplayName("should correctly add elements") void shouldCorrectlyAddElements(MutableLongArray mutableArray) { - // when: mutableArray.add(10); @@ -50,7 +49,6 @@ void shouldCorrectlyAddElements(MutableLongArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly remove elements") void shouldCorrectlyRemoveElements(MutableLongArray mutableArray) { - // given: for(int i = 0; i < 101; i++) { mutableArray.add(100 + i); @@ -85,7 +83,6 @@ void shouldCorrectlyRemoveElements(MutableLongArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly replace elements") void shouldCorrectlyReplaceElements(MutableLongArray mutableArray) { - // given: for(int i = 0; i < 101; i++) { mutableArray.add(100 + i); @@ -110,7 +107,6 @@ void shouldCorrectlyReplaceElements(MutableLongArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly add batch elements") void shouldCorrectlyAddBatchElements(MutableLongArray mutableArray) { - // given: for(int i = 0; i < 21; i++) { mutableArray.add(100 + i); @@ -146,7 +142,6 @@ void shouldCorrectlyAddBatchElements(MutableLongArray mutableArray) { @MethodSource("generateMutableArrays") @DisplayName("should correctly remove batch elements") void shouldCorrectlyRemoveBatchElements(MutableLongArray mutableArray) { - // given: for(int i = 0; i < 21; i++) { mutableArray.add(100 + i); @@ -169,6 +164,28 @@ void shouldCorrectlyRemoveBatchElements(MutableLongArray mutableArray) { Assertions.assertEquals(46, mutableArray.get(26)); } + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should clear array") + void shouldClearArray(MutableLongArray mutableArray) { + // when: + for(int i = 0; i < 21; i++) { + mutableArray.add(100 + i); + } + + // then: + Assertions.assertEquals(21, mutableArray.size()); + Assertions.assertEquals(100, mutableArray.get(0)); + Assertions.assertEquals(120, mutableArray.get(20)); + + // when: + mutableArray.clear(); + + // then: + Assertions.assertEquals(0, mutableArray.size()); + Assertions.assertArrayEquals(new long[0], mutableArray.toArray()); + } + private static Stream generateMutableArrays() { return Stream.of( Arguments.of(ArrayFactory.mutableLongArray())); From a492669efb22d6742c7062de7de7f11bf1212bfd Mon Sep 17 00:00:00 2001 From: javasabr Date: Sun, 9 Nov 2025 20:00:38 +0100 Subject: [PATCH 3/3] add more tests --- .../collections/array/MutableArrayTest.java | 51 +++++++++++++++++++ .../array/MutableIntArrayTest.java | 49 ++++++++++++++++++ .../array/MutableLongArrayTest.java | 49 ++++++++++++++++++ 3 files changed, 149 insertions(+) diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java index 4f6876a5..e6611468 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableArrayTest.java @@ -208,10 +208,61 @@ void shouldClearArray(MutableArray mutableArray) { Assertions.assertArrayEquals(new String[0], mutableArray.toArray()); } + @ParameterizedTest + @MethodSource("generateArraysWithTrimToSize") + @DisplayName("should trim to size wrapped array") + void shouldTrimToSizeWrappedArray(MutableArray mutableArray) { + // given: + UnsafeMutableArray unsafe = mutableArray.asUnsafe(); + + // when: + for(int i = 0; i < 100; i++) { + mutableArray.add("value_" + i); + } + + // then: + Assertions.assertEquals(100, mutableArray.size()); + + // when: + for(int i = 0; i < 30; i++) { + mutableArray.remove(i); + } + + // then: + Assertions.assertEquals(70, mutableArray.size()); + Assertions.assertEquals(109, unsafe.wrapped().length); + + // when: + unsafe.trimToSize(); + + // then: + Assertions.assertEquals(70, unsafe.wrapped().length); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should render to string correctly") + void shouldRenderToStringCorrectly(MutableArray mutableArray) { + // when: + for(int i = 0; i < 10; i++) { + mutableArray.add("val_" + i); + } + // then: + Assertions.assertEquals( + "[val_0, val_1, val_2, val_3, val_4, val_5, val_6, val_7, val_8, val_9]", + mutableArray.toString()); + } + private static Stream generateMutableArrays() { return Stream.of( Arguments.of(ArrayFactory.mutableArray(String.class)), Arguments.of(ArrayFactory.copyOnModifyArray(String.class)), Arguments.of(ArrayFactory.stampedLockBasedArray(String.class))); } + + private static Stream generateArraysWithTrimToSize() { + return Stream.of( + Arguments.of(ArrayFactory.mutableArray(String.class)), + Arguments.of(ArrayFactory.stampedLockBasedArray(String.class))); + } } diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java index e3ceac1c..33c0daa3 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableIntArrayTest.java @@ -162,6 +162,12 @@ void shouldCorrectlyRemoveBatchElements(MutableIntArray mutableArray) { Assertions.assertEquals(120, mutableArray.get(20)); Assertions.assertEquals(41, mutableArray.get(21)); Assertions.assertEquals(46, mutableArray.get(26)); + + // when: + mutableArray.removeAll(anotherNativeArray); + + // then: + Assertions.assertEquals(21, mutableArray.size()); } @ParameterizedTest @@ -186,6 +192,49 @@ void shouldClearArray(MutableIntArray mutableArray) { Assertions.assertArrayEquals(new int[0], mutableArray.toArray()); } + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should trim to size wrapped array") + void shouldTrimToSizeWrappedArray(MutableIntArray mutableArray) { + // given: + UnsafeMutableIntArray unsafe = mutableArray.asUnsafe(); + + // when: + for(int i = 0; i < 100; i++) { + mutableArray.add(100 + i); + } + + // then: + Assertions.assertEquals(100, mutableArray.size()); + + // when: + for(int i = 0; i < 30; i++) { + mutableArray.removeByIndex(i); + } + + // then: + Assertions.assertEquals(70, mutableArray.size()); + Assertions.assertEquals(109, unsafe.wrapped().length); + + // when: + unsafe.trimToSize(); + + // then: + Assertions.assertEquals(70, unsafe.wrapped().length); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should render to string correctly") + void shouldRenderToStringCorrectly(MutableIntArray mutableArray) { + // when: + for(int i = 0; i < 10; i++) { + mutableArray.add(20 + i); + } + // then: + Assertions.assertEquals("[20,21,22,23,24,25,26,27,28,29]", mutableArray.toString()); + } + private static Stream generateMutableArrays() { return Stream.of( Arguments.of(ArrayFactory.mutableIntArray())); diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java index e307467a..5ee8a1e0 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableLongArrayTest.java @@ -162,6 +162,12 @@ void shouldCorrectlyRemoveBatchElements(MutableLongArray mutableArray) { Assertions.assertEquals(120, mutableArray.get(20)); Assertions.assertEquals(41, mutableArray.get(21)); Assertions.assertEquals(46, mutableArray.get(26)); + + // when: + mutableArray.removeAll(anotherNativeArray); + + // then: + Assertions.assertEquals(21, mutableArray.size()); } @ParameterizedTest @@ -186,6 +192,49 @@ void shouldClearArray(MutableLongArray mutableArray) { Assertions.assertArrayEquals(new long[0], mutableArray.toArray()); } + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should trim to size wrapped array") + void shouldTrimToSizeWrappedArray(MutableLongArray mutableArray) { + // given: + UnsafeMutableLongArray unsafe = mutableArray.asUnsafe(); + + // when: + for(int i = 0; i < 100; i++) { + mutableArray.add(100 + i); + } + + // then: + Assertions.assertEquals(100, mutableArray.size()); + + // when: + for(int i = 0; i < 30; i++) { + mutableArray.removeByIndex(i); + } + + // then: + Assertions.assertEquals(70, mutableArray.size()); + Assertions.assertEquals(109, unsafe.wrapped().length); + + // when: + unsafe.trimToSize(); + + // then: + Assertions.assertEquals(70, unsafe.wrapped().length); + } + + @ParameterizedTest + @MethodSource("generateMutableArrays") + @DisplayName("should render to string correctly") + void shouldRenderToStringCorrectly(MutableLongArray mutableArray) { + // when: + for(int i = 0; i < 10; i++) { + mutableArray.add(20 + i); + } + // then: + Assertions.assertEquals("[20,21,22,23,24,25,26,27,28,29]", mutableArray.toString()); + } + private static Stream generateMutableArrays() { return Stream.of( Arguments.of(ArrayFactory.mutableLongArray()));