在Java中反转一个数组

51
如果我有这样一个数组:
1 4 9 16 9 7 4 9 11 

最佳的方法是如何将数组反转,使其看起来像这样:

11 9 4 7 9 16 9 4 1 

我有以下代码,但感觉有点繁琐:

public int[] reverse3(int[] nums) {
    return new int[] { nums[8], nums[7], nums[6], nums[5], num[4],
                       nums[3], nums[2], nums[1], nums[0] };
}

有没有更简单的方法?


5
使用循环将前半部分的每个元素与后半部分的元素交换。 - Peter Lawrey
如果我使用void,那么这个方法就不能使用return语句了,对吗? - PHZE OXIDE
这是正确的。你可以保留可能返回的现有数组,也可以返回一个副本。 - Peter Lawrey
根据你已经有的想法,我敢猜测你在开发方面非常有经验,所以我会指出一个简单的替代方法。只需要在反向循环中实现你想做的事情,而不是实际上反转数组。for (int i = someArray.length - 1; i > 0; i--) { doStuff(someArray[i]); } reversedArray[j++] = firstArray[i]; } - Letharion
15个回答

71

Collections.reverse()可以为您完成此任务,如果您将数字放入IntegersList中。

List<Integer> list = Arrays.asList(1, 4, 9, 16, 9, 7, 4, 9, 11);
System.out.println(list);
Collections.reverse(list);
System.out.println(list);

输出:

[1, 4, 9, 16, 9, 7, 4, 9, 11]
[11, 9, 4, 7, 9, 16, 9, 4, 1]

你能再解释一下吗?谢谢。 - PHZE OXIDE
1
请查看答案的编辑。 - Vikdor
1
为什么要实例化一个新的ArrayList?Arrays.asList()已经返回一个List了。 - Kirill Rakhman
谢谢@cypressious,我一直以为Arrays.asList会返回一个不可修改的列表。现在明白了。 - Vikdor
Arrays.asList 实际上返回的是一个“冻结”列表,意味着您无法从新创建的列表中添加或删除任何元素。但是,您可以进行就地元素修改。 - sunny_dev

69
如果您想就地反转数组:
Collections.reverse(Arrays.asList(array));

自从Arrays.asList返回到原始数组的写入代理之后,它就可以工作了。

21
虽然这是一个老问题,但我花了一些时间才弄清楚...... 这对于提问者不起作用,因为int[]是一个对象,而Arrays.asList(array)将返回List<int[]>而不是List<int>(无论如何都是不可能的)。实际上,它是一个只有一个条目并且相反相同的列表。对于所有原始类型数组都是如此。 - Dennis Ich
public int decToBinary(int n) { // 用于存储二进制数的数组 int[] binaryNum = new int[1000]; // 二进制数组的计数器 int i = 0; while (n > 0) { // 将余数存储在二进制数组中 binaryNum[i] = n % 2; n = n / 2; i++; } Collections.reverse(Arrays.asList(binaryNum)); return binaryNum; } ---------------- 会出现错误 --> error: incompatible types: void cannot be converted to int Collections.reverse(Arrays.asList(binaryNum)); - Varun Chandran

33

如果你不想使用Collections,那么你可以这样做:

for (i = 0; i < array.length / 2; i++) {
  int temp = array[i];
  array[i] = array[array.length - 1 - i];
  array[array.length - 1 - i] = temp;
}

2
在for循环之前将array.length / 2部分放到外面不值得吗?我相信它会在每次迭代中重新计算。 - Jin Kwon
@JinKwon 我相信编译器会进行优化,你可以用javap试一下。 - Zarathustra
@JinKwon 为了澄清一下,我不是指javac,我说的是JIT编译器,在运行时发生的优化。 - Zarathustra

12

我喜欢保留原始数组并返回一份副本。这是一个通用版本:

public static <T> T[] reverse(T[] array) {
    T[] copy = array.clone();
    Collections.reverse(Arrays.asList(copy));
    return copy;
}

不保留原始数组:

public static <T> void reverse(T[] array) {
    Collections.reverse(Arrays.asList(array));
}

这真的很有帮助。我喜欢你没有改变原始数组,而是返回了一个新的数组。 - The Room
虽然对于原始类型的数组不起作用。 - sunny_dev

12

试试这个:

public int[] reverse3(int[] nums) {
    int[] reversed = new int[nums.length];
    for (int i=0; i<nums.length; i++) {
        reversed[i] = nums[nums.length - 1 - i];
    }
    return reversed;
}

我的输入是:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12

而我得到的输出是:

12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1


5
您可以使用 org.apache.commons.lang.ArrayUtils: ArrayUtils.reverse(array)

3
或者你可以反向循环它。
int[] firstArray = new int[]{1,2,3,4};
int[] reversedArray = new int[firstArray.length];
int j = 0;
for (int i = firstArray.length -1; i > 0; i--){
    reversedArray[j++] = firstArray[i];
}

(注意:我没有编译这段代码,但希望它是正确的。)

3
使用最少的交换次数进行原地翻转。
for (int i = 0; i < a.length / 2; i++) {
    int tmp = a[i];
    a[i] = a[a.length - 1 - i];
    a[a.length - 1 - i] = tmp;
}

2
以下将原地反转索引ij之间的数组(要反转整个数组,请调用reverse(a, 0, a.length - 1))。
    public void reverse(int[] a, int i , int j) {
        int ii =  i;
        int jj = j;

        while (ii < jj) {
            swap(ii, jj);
            ++ii;
            --jj;
        }
    }

我喜欢这个答案,因为它避免了在循环内调用.length方法,并且不会不断地计算len - 1 - i;它适用于数组的任何范围,并使用swap而不是temp变量。但是没有理由使用重复的变量(ii和jj);你可以直接使用i和j。我会交换(ii ++,jj--)并避免额外的行。 - geowar
请注意,这仅在 i < j 时有效;如果您希望它始终有效,您可以分配 ii = min(i,j) 和 jj = max(i,j)。 - geowar

2
 public void swap(int[] arr,int a,int b)
 {
    int temp=arr[a];
    arr[a]=arr[b];
    arr[b]=temp;        
}
public int[] reverseArray(int[] arr){
    int size=arr.length-1;

    for(int i=0;i<size;i++){

        swap(arr,i,size--); 

    }

    return arr;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接