1. Overview
1.概述
Sometimes, we may want to swap two variables in our code.
有时,我们可能想在代码中交换两个变量。
In this tutorial, we’ll see several ways to do that, depending on the types of variables we want to swap. Then, we will check the performances of each method.
在本教程中,我们将看到几种方法,这取决于我们想要交换的变量的类型。然后,我们将检查每种方法的性能。
2. The Simple Way: Using a Temporary Variable
2.简单的方法 使用一个临时变量
The simplest way to swap two variables is to use a third variable as temporary storage:
交换两个变量的最简单方法是使用第三个变量作为临时存储。
Object a, b;
Object temp;
temp = a;
a = b;
b = temp;
This method is particularly easy to read and understand, even for beginners. Its primary disadvantage is that it requires a temporary variable.
这种方法特别容易阅读和理解,即使对初学者也是如此。它的主要缺点是它需要一个临时变量。
We should keep in mind that this method is the only one that can swap Object variables.
我们应该记住,这个方法是唯一可以交换Object变量的方法。
2.1. Why Not Swap in a Method?
2.1.为什么不在一个方法中进行交换?
If we have to swap variables at several points in our code, it may sound attractive to create a method to swap variables like that:
如果我们必须在代码中的几个点上交换变量,创建一个这样的方法来交换变量,听起来很有吸引力。
public void swap(Object a, Object b)
Unfortunately, this won’t work in Java as references to objects are copied during method invocation.
不幸的是,这在Java中是行不通的,因为对象的引用是在方法调用过程中复制的。
If we really want to have a swap method, we have to use a wrapper class around your object and swap the object contained in the wrapper:
如果我们真的想有一个交换方法,我们必须在你的对象周围使用一个封装类,并交换封装类中包含的对象。
private class Wrapper {
public String string;
}
And the swap method:
还有交换法。
private static void swap(Wrapper a, Wrapper b) {
String temp = b.string;
b.string = a.string;
a.string = temp;
}
With this method, enclosed Strings will remain swapped after the method returns.
使用这个方法,封闭的字符串在方法返回后将保持互换。
3. Without Temporary Variable
3.不含临时变量
If our variables are of primitive types, we can find ways to swap them without temporary variables.
如果我们的变量是原始类型的,我们可以找到方法在没有临时变量的情况下交换它们。
Let’s see several examples.
让我们看看几个例子。
3.1. Using Arithmetic Operations
3.1.使用算术运算
We can use math to swap variables without temporary variables in several ways. For the following examples, let’s assume that we want to swap two integers a=5 and b=10.
我们可以用数学的方式来交换变量,而不需要临时变量。在下面的例子中,让我们假设我们想交换两个整数a=5和b=10。
We can use additions and subtraction for swapping:
我们可以用加法和减法来交换。
a = a + b; // a = 15
b = a - b; // b = 5
a = a - b; // a = 10
Or, we can use multiplications and divisions:
或者,我们可以使用乘法和除法。
a = a * b; // a = 50
b = a / b; // b = 5
a = a / b; // a = 10
We should keep in mind that this method doesn’t work if any of the numbers is 0 as the first operation will lead to storing a zero, making the rest of the algorithm useless. Moreover, if b=0, it will throw an ArithmeticException due to a division by zero.
我们应该记住,如果任何一个数字是0的话,这个方法是不起作用的,因为第一个操作会导致存储一个0,使得算法的其余部分没有用。此外,如果b=0,它将抛出一个ArithmeticException,原因是除以零。
We should also take care of primitives capacity as addition/multiplication can lead to numbers exceeding the maximum value of the primitive type. This may lead to errors after swapping without throwing any exception.
我们还应该注意基元的容量,因为加/乘法可能会导致数字超过基元类型的最大值。这可能会导致交换后出现错误,而不会抛出任何异常。
For example, if a = Integer.MAX_VALUE, then before swapping a=2147483647 and b=10 and after swapping, a=10, b=-1.
例如,如果a=Integer.MAX_VALUE,那么在交换前a=2147483647和b=10,交换后,a=10,b=-1.。
If we’re working with char, byte, or short types of data, an explicit cast is required as arithmetic operators result is a value of type int at least in Java:
如果我们正在处理char、byte或short类型的数据,就需要明确的转换,因为至少在Java中,算术运算的结果是int类型的值。
a = (char)(a + b);
b = (char)(a - b);
a = (char)(a - b);
3.2. Using Logical Operations
3.2.使用逻辑操作
If we’re working with integer data types (i.e., char, short, byte, int, long), we can use the exclusive OR bitwise operator (XOR). The “^” operator will process a bitwise XOR operation on all bits of our variables:
如果我们正在处理整数数据类型(即 char, short, byte, int, long),我们可以使用排他性OR位操作符(XOR)。”^”运算符将对我们的变量的所有位进行位向XOR操作。
a = a ^ b; // a = 1111 (15)
b = a ^ b; // b = 1010 (5)
a = a ^ b; // a = 0101 (10)
We should be aware that, as for the arithmetic operators, the bitwise XOR operator returns at least int data type. So, we have to cast the result of the XOR for each line if we’re working with chars, bytes, or shorts variables.
我们应该注意,和算术运算符一样,位数XOR运算符至少要返回int数据类型。因此,如果我们要处理字符、字节或短线变量,我们必须对每一行的XOR结果进行转换。
3.3. Single-line Variant
3.3.单线变体
We can use a single-line version of the swapping methods to reduce the code size:
我们可以使用单行版本的交换方法来减少代码大小:。
b = (a + b) – (a = b);
a += b – (b = a);
a = a * b / (b = a);
a = a ^ b ^ (b = a);
This works because expressions are evaluated with respect of the precedence of the operators. If a = 5 and b = 10 initially, the last expression is equivalent to a = 5 ^ 10 ^ (b = 5). The first operation (5 ^ 10) is exactly the first line of the multi-line algorithm, then we assign 5 to b (parenthesis have priority), and finally, we calculate 15 ^ 5 which is exactly the third line of the algorithm.
这是因为表达式的评估与运算符的优先级有关。如果a最初=5,b=10,最后一个表达式就相当于a = 5 ^ 10 ^ (b = 5)。第一个运算(5 ^ 10)正好是多行算法的第一行,然后我们把5分配给b(括号有优先权),最后,我们计算15 ^ 5,正好是算法的第三行。
4. Performance Analysis
4.性能分析
We just saw that there are several ways to swap two variables in Java, but which one is the more efficient? To give a tendency on performances of each algorithm, we performed loops of variable swapping methods and measured the time needed to swap two variables 100.000 times. We ran the test 10 times to calculate the average execution time of each algorithm. Here are the results:
我们刚刚看到,在Java中,有几种交换两个变量的方法,但哪种方法更有效?为了给每种算法的性能提供一个趋势,我们对变量交换方法进行了循环,并测量了交换两个变量所需的时间为100.000次。我们进行了10次测试,以计算出每种算法的平均执行时间。以下是结果。
The absolute time is not important here as it depends on the machine which is running the test. We only see that some algorithms are slower than others. It’s especially true for the multiplication/division one, which is significantly slower, either in its single-line version. On the opposite, the XOR algorithm is the most efficient in both multi and single-line versions.
绝对时间在这里并不重要,因为它取决于运行测试的机器。我们只看到一些算法比其他算法慢。尤其是乘/除法算法,无论是单线版还是多线版,都明显慢了很多。相反,XOR算法在多行和单行版本中都是最有效的。
Swapping Objects with a temporary variable is also quite efficient, which is quite understandable as only pointers are manipulated in that case.
用一个临时变量交换Objects也是相当有效的,这很好理解,因为在这种情况下只操作指针。
5. Conclusion
5.总结
In this article, we looked at how to swap two variables in Java, depending on the type of the variables.
在这篇文章中,我们看了如何在Java中交换两个变量,这取决于变量的类型。
We described how to swap Objects, and then we studied several ways to swap primitives types with several algorithms. Finally, we had a look at the performances of each method.
我们描述了如何交换对象,然后我们研究了用几种算法交换基元类型的几种方法。最后,我们看了一下每种方法的性能。
As always, the source code for all examples is available over on GitHub.
一如既往,所有实例的源代码都可以在GitHub上找到。