Merge sort implementation: sorting feels clunky
That merge would be clearer as a while (index1 &lt; subArray1.length &amp;&amp; index2 &lt; subArray2.length), while bot arrays have elements to be merged in. And you can do 2 System.arraycopys for the remainder afterwards.

while (index1 &lt; subArray1.length &amp;&amp; index2 &lt; subArray2.length){
    if (subArray1[index1] &lt;= subArray2[index2]) {
        sorted[i++] = subArray1[index1++];
    else {
        sorted[i++] = subArray2[index2++];
}

System.arraycopy(subArray1, index1, sorted, i, subArray1.length - index1);
i+=subArray1.length - index1;

System.arraycopy(subArray2, index2, sorted, i, subArray2.length - index2);


At the end either subArray1.length - index1 or subArray2.length - index2 would be 0 but then the arraycopy will be a no-op.