Since you're implementing bubble sort, I assume you're more concerned about clarity and readability than about performance (else you would've picked a different sorting algorithm). Starting from this viewpoint, my first recommendation would be to abstract out the swap into a helper method:
public class BubbleSort {
private static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public static void main(String[] args) {
int arr[] = new int[] { 4, 1, 8, 5, 2, 0, 4, 3, 7, 9 };
for (int i : arr) {
System.out.print(i + " ");
}
for (int i = 1; i < arr.length; i++) {
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
System.out.println();
System.out.println("Sorted array");
for (int i : arr) {
System.out.print(i + " ");
}
}
}
There, that's a lot clearer already, isn't it?
My next suggestion actually is a performance optimization: in bubble sort, after every pass, the elements located after the last swap must all be at their proper position already, and thus don't need to be examined any more. So you can rewrite your sorting loop like this:
int end = arr.length; // anything at or above this point is already sorted
while (end > 1) {
int lastSwap = 0; // index of last swapped element
// walk the array, swap adjacent elements that are the wrong way around
for (int i = 1; i < end; i++) {
if (arr[i - 1] > arr[i]) {
swap(arr, i - 1, i);
lastSwap = i;
}
}
end = lastSwap; // all elements after last swap must be sorted
}
As a useful side effect, this optimization causes the outer loop to terminate as soon as the inner loop detects that the array is fully sorted.
Even with this optimization, the bubble sort will still perform poorly if there's a "turtle" element that takes a long time to sink to the beginning of the array. You could fix that by adding a second, reverse inner loop to quickly move such elements where they belong, turning you bubble sort into cocktail sort. Unlike the optimizations above, however, that would change the sequence of swaps performed by the algorithm, making it technically no longer a pure bubble sort. Still, let me show an example:
int start = 0, end = arr.length; // range yet to be sorted
while (end - start > 1) {
int lastSwap = 0;
// upward sorting pass
for (int i = start + 1; i < end; i++) {
if (arr[i - 1] > arr[i]) {
swap(arr, i - 1, i);
lastSwap = i;
}
}
end = lastSwap;
// downward sorting pass
for (int i = end - 1; i > start; i--) {
if (arr[i - 1] > arr[i]) {
swap(arr, i - 1, i);
lastSwap = i;
}
}
start = lastSwap;
}