I have a method that takes two arrays and merges them with elements in natural order. I was wondering if it is possible to make it generic so it can take arrays of any type and merge them into an array of the same type?
Right now I'm able to construct only an array of Object
public static void main(String[] args) {
Integer[] i1 = {1, 3, 5, 7, 9};
Integer[] i2 = {2, 4, 6, 8, 10, 12, 14};
String[] s1 = {"A", "C", "E", "G"};
String[] s2 = {"B", "D", "F"};
System.out.println(Arrays.toString(mergeAndSortArrays(i1, i2)));
System.out.println(Arrays.toString(mergeAndSortArrays(s1, s2)));
}
public static<T extends Comparable<T>> Object[] mergeAndSortArrays(T[] a, T[] b) {
final Object[] merged = new Object[a.length + b.length];
int aPos = 0, bPos = 0, curIndex = -1;
while (++curIndex < merged.length) {
int comp = a[aPos].compareTo(b[bPos]);
merged[curIndex] = (comp < 0) ? a[aPos++] : b[bPos++];
if (aPos == a.length) {
while (bPos < b.length) {
merged[++curIndex] = b[bPos++];
}
break;
}
if (bPos == b.length) {
while (aPos < a.length) {
merged[++curIndex] = a[aPos++];
}
break;
}
}
return merged;
}
You can't create an array of generic type in Java, but you can use a creator lambda:
public static<T extends Comparable<T>> T[] mergeAndSortArrays(
T[] a,
T[] b,
IntFunction<T[]> arrayCreator
) {
final T[] merged = arrayCreator.apply(a.length + b.length);
...
}
and then:
mergeAndSortArrays(i1, i2, Integer[]::new)
mergeAndSortArrays(s1, s2, String[]::new)
Or alternatively, you have Class<T> itemClass
as method parameter (instead of the lambda) and then use (T[]) Array.newInstance(itemClass, a.length + b.length)
to create new array.
If you want to avoid additional method arguments (like creator lambda or item class), you can use reflection to retrieve array item type:
final Class<?> itemClass = a.getClass().getComponentType();
final T[] merged = (T[]) Array.newInstance(itemClass, a.length + b.length);
And of course you can also use an existing library for this, like Apache Commons:
final T[] merged = org.apache.commons.lang3.ArrayUtils.addAll(a, b);
// ...
If you create the mergedArray out of the type from a, it can look like this.
public static <T extends Comparable<T>> T[] mergeAndSortArrays(T[] a, T[] b) {
final T[] merged = (T[])Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With