HOWTO · Java
How to Shift an Array in Java
This article demonstrates shifting an array in Java.
On this page
Shifting an array can mean two different operations. A rotation moves elements around a circle and keeps every element; a right rotation by two moves the final two elements to the front. Removing leading elements instead returns a shorter sequence and discards those values. Choose rotation when the array must retain its contents, and choose skipping when the goal is to process only the suffix.
The examples below use right rotation unless stated otherwise. A positive distance rotates right, a negative distance rotates left, and distances larger than the array length can be reduced modulo its length. Arrays have fixed length, so code that returns a new array leaves the caller’s original array intact only if it does not reassign or modify it.
The examples are self-contained Java programs, with output shown for the juggling example.
Choose whether you mean rotation or removing leading elements
Use a loop or a temporary array when you need a primitive array such as int[]. Use Collections.rotate() when your data is already a List, or when a reference-type array can be viewed as a list. Use the juggling algorithm when you need to mutate an array without allocating another array and can accept more complex code. Use skip() when you want to discard the first n stream elements; it is not a rotation and does not preserve the original length.
Rotate an array in place with a loop
This approach performs one right shift at a time. It saves the last value before moving the other values right, then places the saved value at index zero. The example starts with five integers and rotates right by two positions. It modifies the supplied array, takes constant extra space, and runs in O(n × k) time for an array of length n and normalized distance k.
Run this example:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] values = {1, 2, 3, 4, 5};
int distance = 2;
if (values.length > 0) {
int steps = Math.floorMod(distance, values.length);
for (int step = 0; step < steps; step++) {
int last = values[values.length - 1];
for (int i = values.length - 1; i > 0; i--) {
values[i] = values[i - 1];
}
values[0] = last;
}
}
System.out.println(Arrays.toString(values));
}
}
Math.floorMod normalizes positive and negative distances to a value from zero through one less than the array length. The length check avoids modulo by zero and leaves an empty array unchanged. A normalized distance of zero also leaves the array unchanged. This repeated-shift method is simple for small distances; for large arrays or distances, the next two array approaches move each element only once.
Rotate into a temporary array
Allocate a second array when you want a direct index mapping and can afford O(n) additional storage. For a right rotation, normalize the distance to steps first so negative and oversized distances work. An element at old index i goes to ((long) i + steps) % n; the long intermediate prevents overflow when adding valid int indices. Return immediately for an empty array before using the modulus.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] values = {1, 2, 3, 4, 5};
int distance = 2;
int[] rotated = new int[values.length];
if (values.length > 0) {
int steps = Math.floorMod(distance, values.length);
for (int i = 0; i < values.length; i++) {
int destination = (int) (((long) i + steps) % values.length);
rotated[destination] = values[i];
}
}
System.out.println(Arrays.toString(rotated));
}
}
The destination formula wraps indices past the final slot back to the beginning. The long sum remains within range for any valid Java array length; modulo then produces a destination from zero through values.length - 1. Adding the same normalized steps modulo the array length is a one-to-one mapping, so every source index maps to a distinct destination and the relative order is preserved. The source array remains unchanged; use the returned array in place of the original if that is the desired ownership behavior.
Rotate a list with Collections.rotate()
Collections.rotate() operates on a List, and a positive distance rotates right while a negative distance rotates left. For a reference-type array, Arrays.asList(array) creates a fixed-size list backed by that same array: elements can be replaced and rotation works, but adding or removing list elements is unsupported. Converting the list back to an array gives a separate array. Primitive arrays such as int[] cannot become a List<Integer> through Arrays.asList; box the values or use an array-specific algorithm instead.
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] values = {1, 2, 3, 4, 5};
List<Integer> list = Arrays.asList(values);
Collections.rotate(list, 2);
Integer[] rotated = list.toArray(new Integer[0]);
System.out.println(Arrays.toString(rotated));
}
}
Here the list and values refer to the same element storage, so rotation also changes the array’s element order. The separately created rotated array contains the rotated values as well. This is concise for object arrays and lists, but it boxes primitive data if you convert it to wrapper objects.
Rotate in place with the juggling algorithm
The juggling algorithm partitions the array into cycles. For a left rotation by d positions, each current index reads from the index current + d, wrapping back to zero at the array length. In code, compute that wrapped index without overflowing: use current >= n - d ? current - (n - d) : current + d. Since d is normalized to the range from zero through n - 1, this produces an index from zero through n - 1; when d is zero, it returns current unchanged. The number of independent cycles is gcd(n, d): each cycle carries values along its path until it returns to its starting index. This performs O(n) moves with O(1) extra storage, which can be useful when allocating another array is undesirable.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] values = {1, 2, 3, 4, 5};
int rightDistance = 2;
int n = values.length;
if (n > 0) {
int rightSteps = Math.floorMod(rightDistance, n);
int leftDistance = (n - rightSteps) % n;
int cycles = gcd(n, leftDistance);
for (int start = 0; start < cycles; start++) {
int saved = values[start];
int current = start;
while (true) {
int next = current >= n - leftDistance
? current - (n - leftDistance)
: current + leftDistance;
if (next == start) break;
values[current] = values[next];
current = next;
}
values[current] = saved;
}
}
System.out.println(Arrays.toString(values));
}
private static int gcd(int a, int b) {
while (b != 0) {
int remainder = a % b;
a = b;
b = remainder;
}
return a;
}
}
[4, 5, 1, 2, 3]
The code first normalizes the requested right distance to rightSteps, then converts it to the equivalent left distance with (n - rightSteps) % n. For a five-element array, right distances 2 and -2 normalize to two and three right steps, producing left distances three and two respectively; Integer.MIN_VALUE is also safe because it is normalized before subtraction. A left rotation reads from the next index in each cycle, wrapping from the end of the array to the beginning. The conditional calculation in the code avoids adding current and leftDistance when that sum would exceed n - 1; in either branch it yields an index from zero through n - 1, even when the unwrapped sum would exceed Integer.MAX_VALUE. gcd(n, leftDistance) is the number of cycles. When the normalized distance is zero, gcd(n, 0) is n, and the conditional calculation returns current, so each value is written back unchanged. The length guard handles an empty array before calculating a modulus. The loop and temporary-array methods are easier to maintain; prefer juggling when its constant extra space is a real requirement.
Skip leading elements with the Stream API
Use skip() when leading values should be omitted from the result, not wrapped to the end. It returns a stream containing the remaining elements, so converting that stream to an array produces a shorter array and does not change the source. A skip count equal to or greater than the number of elements produces an empty result. skip() requires a non-negative count; validate or clamp a caller-provided count if it may be negative.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] values = {1, 2, 3, 4, 5};
long count = 2;
int[] remainder = Arrays.stream(values).skip(count).toArray();
System.out.println(Arrays.toString(remainder));
}
}
Arrays.stream(values) creates an integer stream, skip(count) omits its first count elements, and toArray() collects what remains into a new primitive array. This is convenient for a suffix operation, but it allocates a result and cannot substitute for rotation when every element must be retained.