Skip to content

Commit 1514024

Browse files
committed
✨ feat: add unify functions for Collection4j, Byte4j and Array4j #4
1 parent cc178e5 commit 1514024

3 files changed

Lines changed: 197 additions & 5 deletions

File tree

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package org.unify4j.common;
2+
3+
import java.lang.reflect.Array;
4+
import java.util.Arrays;
5+
6+
public class Array4j {
7+
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
8+
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
9+
public static final char[] EMPTY_CHAR_ARRAY = new char[0];
10+
public static final Character[] EMPTY_CHARACTER_ARRAY = new Character[0];
11+
public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];
12+
13+
/**
14+
* Checks if the specified array is empty or null.
15+
* <p>
16+
* An array is considered empty if it is either null or has a length of zero.
17+
*
18+
* @param array The array to check for emptiness.
19+
* @return {@code true} if the array is empty or null, {@code false} otherwise.
20+
*/
21+
public static boolean isEmpty(final Object array) {
22+
return array == null || Array.getLength(array) == 0;
23+
}
24+
25+
/**
26+
* Retrieves the size of the specified array.
27+
* <p>
28+
* If the array is null, the size returned is 0.
29+
*
30+
* @param array The array to determine the size of.
31+
* @return The size of the array. Returns 0 if the array is null.
32+
*/
33+
public static int size(final Object array) {
34+
return array == null ? 0 : Array.getLength(array);
35+
}
36+
37+
/**
38+
* <p>Shallow copies an array of Objects
39+
* </p>
40+
* <p>The objects in the array are not cloned, thus there is no special
41+
* handling for multi-dimensional arrays.
42+
* </p>
43+
* <p>This method returns <code>null</code> if <code>null</code> array input.</p>
44+
*
45+
* @param array the array to shallow clone, may be <code>null</code>
46+
* @param <T> the array type
47+
* @return the cloned array, <code>null</code> if <code>null</code> input
48+
*/
49+
public static <T> T[] shallowCopy(final T[] array) {
50+
if (isEmpty(array)) {
51+
return null;
52+
}
53+
return array.clone();
54+
}
55+
56+
/**
57+
* Adds all the elements of the given arrays into a new array.
58+
* <p>
59+
* The new array contains all of the elements of the first array followed
60+
* by all of the elements of the second array. When an array is returned,
61+
* it is always a new array.
62+
* </p>
63+
* <pre>
64+
* ArrayUtilities.addAll(null, null) = null
65+
* ArrayUtilities.addAll(array1, null) = cloned copy of array1
66+
* ArrayUtilities.addAll(null, array2) = cloned copy of array2
67+
* ArrayUtilities.addAll([], []) = []
68+
* ArrayUtilities.addAll([null], [null]) = [null, null]
69+
* ArrayUtilities.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
70+
* </pre>
71+
*
72+
* @param array1 the first array whose elements are added to the new array, may be <code>null</code>
73+
* @param array2 the second array whose elements are added to the new array, may be <code>null</code>
74+
* @param <T> the array type
75+
* @return The new array, <code>null</code> if <code>null</code> array inputs.
76+
* The type of the new array is the type of the first array.
77+
*/
78+
@SuppressWarnings("unchecked")
79+
public static <T> T[] addAll(final T[] array1, final T[] array2) {
80+
if (isEmpty(array1)) {
81+
return shallowCopy(array2);
82+
} else if (isEmpty(array2)) {
83+
return shallowCopy(array1);
84+
}
85+
// Create a new array with a length equal to the sum of the lengths of array1 and array2.
86+
final T[] newArray = (T[]) Array.newInstance(array1.getClass().getComponentType(), array1.length + array2.length);
87+
// Copy the elements of array1 and array2 into the new array.
88+
System.arraycopy(array1, 0, newArray, 0, array1.length);
89+
System.arraycopy(array2, 0, newArray, array1.length, array2.length);
90+
return newArray;
91+
}
92+
93+
/**
94+
* Removes an item from the given array at the specified position.
95+
* <p>
96+
* This method creates a new array with one fewer element than the original array
97+
* by removing the element at the specified position. If the input array is empty
98+
* or null, it returns the input array as is.
99+
* </p>
100+
*
101+
* @param array the array from which the item is to be removed, may be <code>null</code>
102+
* @param position the position of the item to remove
103+
* @param <T> the type of the array elements
104+
* @return A new array with the specified item removed, or the original array if it's empty or null.
105+
* If the specified position is out of bounds, returns a shallow copy of the original array.
106+
*/
107+
@SuppressWarnings("unchecked")
108+
public static <T> T[] removeItem(T[] array, int position) {
109+
if (isEmpty(array)) {
110+
return array;
111+
}
112+
final int len = Array.getLength(array);
113+
// Create a new array with one fewer element.
114+
T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), len - 1);
115+
// Copy elements before the specified position.
116+
System.arraycopy(array, 0, newArray, 0, position);
117+
// Copy elements after the specified position.
118+
System.arraycopy(array, position + 1, newArray, position, len - position - 1);
119+
return newArray;
120+
}
121+
122+
/**
123+
* Returns a subset of the given array between the specified start (inclusive) and end (exclusive) indices.
124+
* <p>
125+
* This method creates a new array containing elements from the input array, starting from the
126+
* specified start index up to, but not including, the specified end index.
127+
* If the input array is empty or null, it returns the input array as is.
128+
* </p>
129+
*
130+
* @param array the array from which the subset is to be extracted, may be <code>null</code>
131+
* @param start the start index (inclusive) of the subset
132+
* @param end the end index (exclusive) of the subset
133+
* @param <T> the type of the array elements
134+
* @return A new array containing elements from the input array within the specified range.
135+
* Returns the original array if it's empty or null.
136+
* If the specified indices are out of bounds, returns a shallow copy of the original array.
137+
*/
138+
public static <T> T[] getArraySubset(T[] array, int start, int end) {
139+
if (isEmpty(array)) {
140+
return array;
141+
}
142+
return Arrays.copyOfRange(array, start, end);
143+
}
144+
}

plugin/src/main/groovy/org/unify4j/common/Byte4j.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@ public static String encode(final byte[] bytes) {
3838
StringBuilder sb = new StringBuilder(bytes.length << 1);
3939
// Loop through each byte and convert it to two hexadecimal characters
4040
for (byte aByte : bytes) {
41-
sb.append(convertDigit(aByte >> 4));
42-
sb.append(convertDigit(aByte & 0x0f));
41+
sb.append(toDigit(aByte >> 4));
42+
sb.append(toDigit(aByte & 0x0f));
4343
}
4444
return sb.toString();
4545
}
4646

4747
/**
48-
* Converts a value (0 .. 15) to the corresponding hexadecimal digit.
48+
* Converts a value (0 ... 15) to the corresponding hexadecimal digit.
4949
*
5050
* @param value the value to convert
51-
* @return the corresponding hexadecimal character ('0'..'F')
51+
* @return the corresponding hexadecimal character ('0'...'F')
5252
*/
53-
private static char convertDigit(final int value) {
53+
private static char toDigit(final int value) {
5454
return hexes[value & 0x0f];
5555
}
5656

plugin/src/main/groovy/org/unify4j/common/Collection4j.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
public class Collection4j {
1313
protected static final Logger logger = LoggerFactory.getLogger(Collection4j.class);
14+
private static final Set<?> unmodifiableEmptySet = Collections.unmodifiableSet(new HashSet<>());
15+
private static final List<?> unmodifiableEmptyList = Collections.unmodifiableList(new ArrayList<>());
1416

1517
/**
1618
* Checks if the provided collection is null or empty.
@@ -580,6 +582,52 @@ public static <E> boolean isConsistOf(E[] array, int index) {
580582
return !Object4j.isEmpty(array) && index >= 0 && index < array.length;
581583
}
582584

585+
/**
586+
* Creates an immutable list containing the specified elements.
587+
* This method is preferable when creating immutable lists in Java versions
588+
* where Set.of() is not available (e.g., JDK versions before 11).
589+
* It returns an empty immutable list if no elements are provided or if the input array is null.
590+
*
591+
* @param items The elements to be included in the immutable list.
592+
* @param <T> The type of elements in the list.
593+
* @return An immutable list containing the specified elements.
594+
* Returns an empty immutable list if no elements are provided or if the input array is null.
595+
*/
596+
@SuppressWarnings({"unchecked"})
597+
@SafeVarargs
598+
public static <T> List<T> listOf(T... items) {
599+
if (items == null || items.length == 0) {
600+
return (List<T>) unmodifiableEmptyList;
601+
}
602+
List<T> list = new ArrayList<>();
603+
Collections.addAll(list, items);
604+
return Collections.unmodifiableList(list);
605+
}
606+
607+
/**
608+
* Creates an immutable set containing the specified elements.
609+
* This method is preferable when creating immutable sets in Java versions
610+
* where Set.of() is not available (e.g., JDK versions before 11).
611+
* It returns an empty immutable set if no elements are provided or if the input array is null.
612+
* <p>
613+
* Note: For JDK 11 and above, consider using Set.of() instead.
614+
*
615+
* @param items The elements to be included in the immutable set.
616+
* @param <T> The type of elements in the set.
617+
* @return An immutable set containing the specified elements.
618+
* Returns an empty immutable set if no elements are provided or if the input array is null.
619+
*/
620+
@SuppressWarnings({"unchecked"})
621+
@SafeVarargs
622+
public static <T> Set<T> setOf(T... items) {
623+
if (items == null || items.length == 0) {
624+
return (Set<T>) unmodifiableEmptySet;
625+
}
626+
Set<T> set = new LinkedHashSet<>();
627+
Collections.addAll(set, items);
628+
return Collections.unmodifiableSet(set);
629+
}
630+
583631
/**
584632
* Throws UnsupportedOperationException if the list is not of type ArrayList.
585633
*

0 commit comments

Comments
 (0)