68

我想知道是否有比这样做更有效的方法来交换数组中的两个元素:

String temp = arr[1];
arr[1] = arr[2];
arr[2] = temp;

好吧,这显然还不错,甚至是错误的,但是我需要经常交换,所以我很感兴趣是否有任何库或提供更有效方法的东西?

4

13 回答 13

36

没有。你可以有一个函数来使它在你使用它的每个地方都更简洁,但最终,所做的工作将是相同的(加上函数调用的开销,直到/除非 HotSpot 将其移入内联 - 以帮助它,制作函数static final)。

于 2012-12-07T15:40:30.117 回答
34

这应该使它无缝:

public static final <T> void swap (T[] a, int i, int j) {
  T t = a[i];
  a[i] = a[j];
  a[j] = t;
}

public static final <T> void swap (List<T> l, int i, int j) {
  Collections.<T>swap(l, i, j);
}

private void test() {
  String [] a = {"Hello", "Goodbye"};
  swap(a, 0, 1);
  System.out.println("a:"+Arrays.toString(a));
  List<String> l = new ArrayList<String>(Arrays.asList(a));
  swap(l, 0, 1);
  System.out.println("l:"+l);
}
于 2012-12-07T15:59:26.913 回答
18

如果您正在交换数字并且想要一种简洁的方式来编写代码,而无需创建单独的函数或使用令人困惑的 XOR hack,我发现这更容易理解,而且它也是一个单行。

public static void swap(int[] arr, int i, int j) {
    arr[i] = (arr[i] + arr[j]) - (arr[j] = arr[i]);
}

我从一些原始基准中看到的是,性能差异也基本上可以忽略不计。

这是在不使用临时变量的情况下交换数组元素的标准方法之一,至少对于整数来说是这样。

于 2017-01-28T15:13:46.867 回答
11

如果你想交换字符串。这已经是做到这一点的有效方法。

但是,如果要交换整数,可以使用 XOR 更有效地交换两个整数,如下所示:

int a = 1; int b = 2; a ^= b; b ^= a; a ^= b;
于 2012-12-07T15:41:46.790 回答
5

使用Collections.swapArrays.asList

Collections.swap(Arrays.asList(arr), i, j);
于 2017-09-20T05:40:18.820 回答
2

就地交换(以防您已经不知道)可以通过不创建临时变量来节省一些空间。

arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
于 2021-01-21T00:44:14.580 回答
1

尝试这个:

    int lowIndex = 0;
    int highIndex = elements.length-1;

    while(lowIndex < highIndex) {
        T lowVal = elements[lowIndex];
        T highVal = elements[highIndex];
        elements[lowIndex] = highVal;
        elements[highIndex] = lowVal;

        lowIndex += 1;
        highIndex -=1;
    }
于 2017-08-11T15:29:34.640 回答
1

派对迟到了(我很抱歉),但可以实现比此处提供的更通用的解决方案(将适用于原语和非原语):

public static void swap(final Object array, final int i, final int j) {
    final Object atI = Array.get(array, i);
    Array.set(array, i, Array.get(array, j));
    Array.set(array, j, atI);
}

你失去了编译时的安全性,但它应该可以解决问题。

注意 I:如果给定是,你会得到一个NullPointerException如果给定不是数组,如果任一索引对给定无效,会得到一个。arraynullIllegalArgumentExceptionarrayArrayIndexOutOfBoundsExceptionarray

注意二:为每个数组类型(Object[]和所有原始类型)设置单独的方法会更好(使用这里给出的其他方法),因为这需要一些装箱/拆箱。但它也需要更多的代码来编写/维护。

于 2017-08-02T01:09:54.243 回答
0

对象和原始类型的解决方案:

public static final <T> void swap(final T[] arr, final int i, final int j) {
    T tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final boolean[] arr, final int i, final int j) {
    boolean tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final byte[] arr, final int i, final int j) {
    byte tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final short[] arr, final int i, final int j) {
    short tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final int[] arr, final int i, final int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final long[] arr, final int i, final int j) {
    long tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final char[] arr, final int i, final int j) {
    char tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final float[] arr, final int i, final int j) {
    float tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final double[] arr, final int i, final int j) {
    double tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
于 2019-06-15T21:49:39.277 回答
0
public static final void swap (int[] a, int i, int j) {
    a[i] = a[i] + a[j];
    a[j] = a[i] - a[j];
    a[i] = a[i] - a[j];
}
于 2021-09-22T10:03:47.460 回答
0

这只是“hack”风格的方法:

int d[][] = new int[n][n];

static int swap(int a, int b) {
  return a;
}
...

in main class --> 

d[i][j + 1] = swap(d[i][j], d[i][j] = d[i][j + 1])
于 2020-08-11T01:34:28.000 回答
0

首先你不应该写for (int k = 0; k **<** data.length **- 1**; k++),因为 < 是直到 k 小于长度 -1 然后循环将运行到数组中的最后一个位置并且不会得到数组中的最后一个位置;所以你可以通过两种方式修复它:1:for (int k = 0; k <= data.length - 1; k++) 2:for (int k = 0; k < data.length; k++)然后它会正常工作!并交换您可以使用:将其中一个 int 保留在另一个地方,然后替换

int x = data[k]
data[k] = data[data.length - 1]
data[data.length - 1] = x;

因为你不想失去一个 int 的!!

于 2019-04-24T19:14:22.057 回答
-3
public class SwapElements {

public static void main(String[] args) {

    int[] arr1 = new int[5];
    int[] arr2 = {10,20,30,40};

    System.out.println("arr1 Before Swapping " + Arrays.toString(arr1));
    System.out.println("arr2 Before Swapping " + Arrays.toString(arr2));

    int temp[];
    arr1[3] = 5;
    arr1[0] = 2;
    arr1[1] = 3;
    arr1[2] = 6;
    arr1[4] = 10;

    temp = arr1;
    arr1 = arr2;
    arr2 = temp;
    System.out.println("arr1 after Swapping " + Arrays.toString(arr1));
    System.out.println("arr2 after Swapping " + Arrays.toString(arr2));
}

}

于 2020-02-12T03:00:42.250 回答