Looking at the actual source code might help to clarify your problem:
In Java 8 the ArrayList.removeRange()
looks like this:
protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null;
}
size = newSize;
}
In Java 9 the ArrayList.removeRange()
changed to this:
protected void removeRange(int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IndexOutOfBoundsException(
outOfBoundsMsg(fromIndex, toIndex));
}
modCount++;
shiftTailOverGap(elementData, fromIndex, toIndex);
}
private void shiftTailOverGap(Object[] es, int lo, int hi) {
System.arraycopy(es, hi, es, lo, size - hi);
for (int to = size, i = (size -= hi - lo); i < to; i++)
es[i] = null;
}
As you can see in the snippets above both implementations use System.arraycopy()
to remove the items of the list. But only since Java 9 there is the check which throws the IndexOutOfBoundsException
if fromIndex > toIndex
.
Since System.arraycopy()
is implemented native the source code might be different on different platforms. According to the javadoc it should behave this way:
Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination array. [...]
If the src
and dest
arguments refer to the same array object, then the copying is performed as if the components at positions srcPos
through srcPos+length-1
were first copied to a temporary array with length
components and then the contents of the temporary array were copied into positions destPos
through destPos+length-1
of the destination array.
For IndexOutOfBoundException
it says:
If any of the following is true, an IndexOutOfBoundsException
is thrown and the destination is not modified:
- The
srcPos
argument is negative.
- The
destPos
argument is negative.
- The
length
argument is negative.
srcPos+length
is greater than src.length
, the length of the source array.
destPos+length
is greater than dest.length
, the length of the destination array.
So if you are running your example with Java 8 or below you might get this result:
before remove : [a, b, c, d, e]
after remove (3, 1) : [a, b, c, b, c, d, e]
If you run your example with Java 9 or above you will get this exception:
before remove : [a, b, c, d, e]
Exception in thread "main" java.lang.IndexOutOfBoundsException: From Index: 3 > To Index: 1
at java.base/java.util.ArrayList.removeRange(ArrayList.java:769)
at TestRemoveRange.main(TestRemoveRange.java:16)