Java中交换两个变量的方法 | Baeldung
Java中交换两个变量的方法 | Baeldung
1. 概述
有时,我们可能希望在代码中交换两个变量。
在本教程中,我们将看到几种交换变量的方法,这取决于我们想要交换的变量类型。然后,我们将检查每种方法的性能。
2. 简单方法:使用临时变量
交换两个变量的最简单方法是使用第三个变量作为临时存储:
Object a, b;
Object temp;
temp = a;
a = b;
b = temp;
这种方法特别易于阅读和理解,即使是初学者也容易理解。它的主要缺点是需要一个临时变量。
我们应该记住,这种方法是唯一可以交换_Object_变量的方法。
2.1. 为什么不在方法中交换?
如果我们要在代码的多个地方交换变量,创建一个像下面这样的交换变量的方法可能听起来很有吸引力:
public void swap(Object a, Object b)
不幸的是,这在Java中是行不通的,因为在方法调用期间对象的引用会被复制。
如果我们真的想要有一个交换方法,我们必须使用一个包装类来包装你的对象,并交换包装类中包含的对象:
private class Wrapper {
public String string;
}
private static void swap(Wrapper a, Wrapper b) {
String temp = b.string;
b.string = a.string;
a.string = temp;
}
通过这种方法,封装的_Strings_将在方法返回后仍然被交换。
3. 不使用临时变量
如果我们的变量是原始类型,我们可以找到不使用临时变量交换它们的方法。
让我们看几个例子。
3.1. 使用算术运算
我们可以使用数学来在不使用临时变量的情况下交换变量。对于以下示例,让我们假设我们想要交换两个整数_a=5_和_b=10_。
我们可以使用加法和减法来交换:
a = a + b; // a = 15
b = a - b; // b = 5
a = a - b; // a = 10
或者,我们可以使用乘法和除法:
a = a * b; // a = 50
b = a / b; // b = 5
a = a / b; // a = 10
我们应该记住,如果任何数字是0,这种方法就不起作用,因为第一个操作将导致存储一个零,使得算法的其余部分变得无用。此外,如果_b_=0,由于除以零,它将抛出一个_ArithmeticException_。
**我们还应该注意原始类型的容量,因为加法/乘法可能导致数字超过原始类型的最大值。**这可能导致在交换后出现错误,而不会抛出任何异常。
例如,如果_a_ = Integer.MAX_VALUE,那么在交换之前_a=2147483647_和_b=10_,交换后,a=10,b=-1。
如果我们使用_char_、_byte_或_short_类型的数据,我们需要进行显式转换,因为算术运算符的结果至少是_int_类型的值在Java中:
a = (char)(a + b);
b = (char)(a - b);
a = (char)(a - b);
3.2. 使用逻辑运算
如果我们使用整数数据类型(即_char, short, byte, int, long_),我们可以使用异或位运算符(XOR)。“^”运算符将在我们变量的所有位上执行位异或操作:
a = a ^ b; // a = 1111 (15)
b = a ^ b; // b = 1010 (5)
a = a ^ b; // a = 0101 (10)
我们应该意识到,与算术运算符一样,位异或运算符返回的至少是_int_数据类型。因此,如果我们使用chars、bytes或shorts变量,我们必须对每行XOR的结果进行强制转换。
3.3. 单行变体
我们可以使用交换方法的单行版本来减小代码大小:
b = (a + b) - (a = b);
a += b - (b = a);
a = a * b / (b = a);
a = a ^ b ^ (b = a);
这是因为表达式是根据运算符的优先级进行计算的。如果最初_a_ = 5和_b_ = 10,最后一个表达式等同于_a = 5 ^ 10 ^ (b = 5)_。第一个操作(5 ^ 10)正是多行算法的第一行,然后我们给_b_赋值为5(括号优先),最后,我们计算15 ^ 5,这正是算法的第三行。
4. 性能分析
我们刚刚看到Java中有几种交换两个变量的方法,但哪一种更有效?为了给出每种算法性能的趋势,我们执行了变量交换方法的循环,并测量了交换两个变量100,000次所需的时间。我们运行了10次测试来计算每种算法的平均执行时间。这是结果:

这里的绝对时间并不重要,因为它取决于运行测试的机器。我们只看到一些算法比其他的慢。特别是乘法/除法,无论是单行还是多行版本,都明显更慢。相反,XOR算法在多行和单行版本中都是最有效的。
使用临时变量交换对象也非常高效,这是可以理解的,因为在那情况下只操作了指针。
5. 结论
在本文中,我们探讨了如何在Java中根据变量的类型交换两个变量。
我们描述了如何交换对象,然后我们研究了几种交换原始类型的方法和几种算法。最后,我们查看了每种方法的性能。
和往常一样,所有示例的源代码都可以在GitHub上找到。