Move Zeros to End in Java
Problem
Moving zeros to the end means compacting every non-zero element toward the front, in its original relative order, and filling whatever's left with zeros.
Given an array of integers, move every zero to the end while keeping the non-zero elements in their original relative order.
Java Program
import java.util.Arrays;
public class MoveZerosToEnd {
public static void main(String[] args) {
int[] arr = {0, 12, 0, 45, 0, 6, 8};
int insertPos = 0;
for (int num : arr) {
if (num != 0) {
arr[insertPos++] = num; // compact non-zero values toward the front
}
}
while (insertPos < arr.length) {
arr[insertPos++] = 0; // fill whatever's left with zeros
}
System.out.println(Arrays.toString(arr));
}
}Output
Core Logic
Copying every non-zero value forward into the next open slot, and filling whatever's left over with zeros, sorts the array into non-zeros-then-zeros in a single pass.
- 1
insertPostracks the next open slot for a non-zero value, starting at0. - 2The loop visits every element; whenever it finds a non-zero value, that value is written to
arr[insertPos]andinsertPosadvances. - 3Because
insertPosnever gets ahead of the current scan position, this never overwrites a value before it's been read. - 4Once the scan finishes, everything from
insertPosto the end of the array is overwritten with0.
[0, 12, 0, 45, 0, 6, 8], the non-zero values 12, 45, 6, and 8 get compacted to the front in that order, and the remaining three slots become zeros.Key Point: This keeps the non-zero values in their original relative order — 12 still comes before 45, which still comes before 6 and 8 — something not every in-place rearrangement guarantees.
Why: Each element is visited once to compact the non-zero values forward, and the remaining slots are filled with zero in place — no extra array needed.
Key Concepts
Approach 2: Java 8
import java.util.Arrays;
public class MoveZerosToEndStream {
public static void main(String[] args) {
int[] arr = {0, 12, 0, 45, 0, 6, 8};
int[] nonZero = Arrays.stream(arr).filter(n -> n != 0).toArray();
int[] result = new int[arr.length]; // every slot already defaults to 0
System.arraycopy(nonZero, 0, result, 0, nonZero.length);
System.out.println(Arrays.toString(result));
}
}
Output
Core Logic
Filtering out the zeros with a stream, then copying the survivors into a fresh array, relies on a new int[] already defaulting every slot to zero.
- 1
Arrays.stream(arr).filter(n -> n != 0)keeps only the non-zero values, in their original order. - 2
.toArray()collects them into a new array holding just the non-zero values. - 3
new int[arr.length]creates the result array — every slot in a freshly allocatedint[]already starts at0in Java, with no explicit fill needed. - 4
System.arraycopy()copies the non-zero values into the front of that zero-filled result array.
[0, 12, 0, 45, 0, 6, 8] keeps [12, 45, 6, 8], which then gets copied into the front of a 7-slot array whose remaining three slots are already 0.Key Point: The trailing zeros here aren't written explicitly at all — they're just the default value Java gives every int[] slot, which this approach relies on instead of assigning.
Why: filter() builds a new array holding just the non-zero values, and the remaining slots in the freshly allocated result array default to zero automatically.