我想知道有没有比这种方法更有效的交换数组中两个元素的方式:
String temp = arr[1];
arr[1] = arr[2];
arr[2] = temp;
嗯,这显然不是坏事,甚至也不是错的,但我需要经常交换,所以我想知道是否有任何库或其他东西可以提供更高效的方法来做到这一点?
我想知道有没有比这种方法更有效的交换数组中两个元素的方式:
String temp = arr[1];
arr[1] = arr[2];
arr[2] = temp;
嗯,这显然不是坏事,甚至也不是错的,但我需要经常交换,所以我想知道是否有任何库或其他东西可以提供更高效的方法来做到这一点?
不行。您可以在使用它的每个地方都有一个函数使其更简洁,但最终完成的工作将是相同的(加上函数调用的开销,直到/除非HotSpot将其内联 - 为了帮助它,将函数设置为 static final
)。
static final
相比仅使用static
或者不使用的好处是什么? - Robinstatic
告诉编译器和虚拟机(记住,HotSpot 是虚拟机,它可以进行很多运行时优化)不需要担心设置 this
,这使得函数更容易内联。final
表示它不会在子类中被覆盖。我可能对 HotSpot 对它们关注的程度有误解,实际情况可能有所不同,因为我不太了解 HotSpot 的最新技巧。 :-) - T.J. Crowderstatic final
(http://ideone.com/NuMyv4): "error: foo() in Derived cannot override foo() in Base...overridden method is static,final"。如果它不是“final”,则该错误将消失(http://ideone.com/vnuAk6)。只有在通过*实例引用*调用静态方法时才会出现这个错误,这是一件奇怪的事情。调用的方法从引用类型在编译时就已经确定:http://ideone.com/yXDgpa。 - T.J. Crowderpublic 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);
}
Integer[] array
而不是 int[] array
。 - LostNomad311如果你在交换数字并且想以简洁的方式书写代码,而不必创建单独的函数或使用令人困惑的异或运算符技巧,我认为下面这种方法更容易理解,而且只需要一行代码。
public static void swap(int[] arr, int i, int j) {
arr[i] = (arr[i] + arr[j]) - (arr[j] = arr[i]);
}
从一些基本的基准测试结果来看,性能差异基本可以忽略不计。
这是交换数组元素而不使用临时变量的标准方法之一,至少对于整数来说如此。
[i]
将被正确计算。在 IDE 中尝试一下。 - kmecpp如果你想交换字符串,那么现在已经有了高效的方法。
然而,如果你想要交换整数,可以使用异或来更加高效地交换两个整数,像这样:
int a = 1; int b = 2; a ^= b; b ^= a; a ^= b;
Collections.swap
和 Arrays.asList
:Collections.swap(Arrays.asList(arr), i, j);
原地交换(如果您还不知道)可以通过不创建临时变量来节省一些空间。
arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
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);
}
你会失去编译时安全性,但这应该可以解决问题。
注意1:如果给定的数组为 null
,则会出现 NullPointerException
;如果给定的array
不是一个数组,则会出现 IllegalArgumentException
;如果任一索引对于给定的array
无效,则会出现 ArrayIndexOutOfBoundsException
。
注意2:为每种数组类型(Object[]
和所有原始类型)单独设置此方法将更加高效(使用此处提供的其他方法),因为这需要一些装箱/拆箱。但也需要编写/维护大量代码。
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];
}
试试这个:
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;
}
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 x = data[k]
data[k] = data[data.length - 1]
data[data.length - 1] = x;
因为你不想丢失其中一个整数!!