Java 中数组元素的高效交换

我想知道是否有一种更有效的方式来交换一个 Array 中的两个元素,而不是像下面这样:

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

这显然不是坏事,甚至是错事,但我需要经常交换,所以我很感兴趣,是否有任何 Libs 或其他东西,提供一个更有效的方法来做到这一点?

280444 次浏览

没有。你可以设置一个函数,让你使用它的每个地方都更加简洁,但是最终,所做的工作是一样的(加上函数调用的开销,直到/除非 HotSpot 把它内联起来ーー为了达到这个目的,设置函数 static final)。

如果你想交换字符串,这已经是最有效的方法了。

然而,如果你想交换整数,你可以使用 XOR 来更有效地交换两个整数,如下所示:

int a = 1; int b = 2; a ^= b; b ^= a; a ^= b;

这应该会让它变得天衣无缝:

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);
}

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

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

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

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

虽然来得太晚了(抱歉) ,但是可以实现一个比这里提供的更通用的解决方案(可以同时使用原语和非原语) :

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);
}

您会失去编译时的安全性,但它应该可以解决这个问题。

注意: 如果给定的 arraynull,那么您将得到一个 NullPointerException; 如果给定的 array没有,那么您将得到一个 IllegalArgumentException; 如果任何一个索引对给定的 array无效,那么您将得到一个 ArrayIndexOutOfBoundsException

注意 II: 对于 每个数组类型(Object[]和所有基元类型)使用单独的方法可能性能更好(使用这里给出的其他方法) ,因为这需要一些装箱/取消装箱。但是编写/维护的代码也要多得多。

试试这个:

    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;
}

使用 Collections.swapArrays.asList:

Collections.swap(Arrays.asList(arr), i, j);

首先,你不应该写 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;

因为你不想失去一个整型数! !

对象和基元类型的解决方案:

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;
}
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));
}

}

这只是“黑客”式的方法:

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])

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

arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
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];
}