I think this is the closest you can get to a simple swap, but it does not have a straightforward usage pattern:
int swap(int a, int b) { // usage: y = swap(x, x=y);
return a;
}
y = swap(x, x=y);
It relies on the fact that x
will pass into swap
before y
is assigned to x
, then x
is returned and assigned to y
.
You can make it generic and swap any number of objects of the same type:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
c = swap(a, a=b, b=c)
Apparently I don't have enough reputation points to comment on Dansalmo's answer, but it is a good one, though mis-named. His answer is actually a K-combinator.
int K( int a, int b ) {
return a;
}
The JLS is specific about argument evaluation when passing to methods/ctors/etc. (Was this not so in older specs?)
Granted, this is a functional idiom, but it is clear enough to those who recognize it. (If you don't understand code you find, don't mess with it!)
y = K(x, x=y); // swap x and y
The K-combinator is specifically designed for this kind of thing. AFAIK there's no reason it shouldn't pass a code review.
My $0.02.
AFAIS, no one mentions of atomic reference.
Integer
public void swap(AtomicInteger a, AtomicInteger b){
a.set(b.getAndSet(a.get()));
}
String
public void swap(AtomicReference<String> a, AtomicReference<String> b){
a.set(b.getAndSet(a.get()));
}
I might do something like the following. Of course, with the wealth of Collection classes, i can't imagine ever needing to use this in any practical code.
public class Shift {
public static <T> T[] left (final T... i) {
if (1 >= i.length) {
return i;
}
final T t = i[0];
int x = 0;
for (; x < i.length - 1; x++) {
i[x] = i[x + 1];
}
i[x] = t;
return i;
}
}
Called with two arguments, it's a swap.
It can be used as follows:
int x = 1;
int y = 2;
Integer[] yx = Shift.left(x,y);
Alternatively:
Integer[] yx = {x,y};
Shift.left(yx);
Then
x = yx[0];
y = yx[1];
Note: it auto-boxes primitives.
It depends on what you want to do. This code swaps two elements of an array.
void swap(int i, int j, int[] arr) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Something like this swaps the content of two int[]
of equal length.
void swap(int[] arr1, int[] arr2) {
int[] t = arr1.clone();
System.arraycopy(arr2, 0, arr1, 0, t.length);
System.arraycopy(t, 0, arr2, 0, t.length);
}
Something like this swaps the content of two BitSet
(using the XOR swap algorithm):
void swap(BitSet s1, BitSet s2) {
s1.xor(s2);
s2.xor(s1);
s1.xor(s2);
}
Something like this swaps the x
and y
fields of some Point
class:
void swapXY(Point p) {
int t = p.x;
p.x = p.y;
p.y = t;
}
For integer types, you can do
a ^= b;
b ^= a;
a ^= b;
using the bit-wise xor operator ^
. As all the other suggestions, you probably shouldn't use it in production code.
For a reason I don't know, the single line version a ^= b ^= a ^= b
doesn't work (maybe my Java compiler has a bug). The single line worked in C with all compilers I tried. However, two-line versions work:
a ^= b ^= a;
b ^= a;
as well as
b ^= a;
a ^= b ^= a;
A proof that it works: Let a0 and b0 be the initial values for a
and b
. After the first line, a
is a1 = a0 xor b0; after the second line, b
is b1 = b0 xor a1 = b0 xor (a0 xor b0) = a0. After the third line, a
is a2 = a1 xor b1 = a1 xor (b0 xor a1) = b0.
Try this magic
public static <T> void swap(T a, T b) {
try {
Field[] fields = a.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object temp = field.get(a);
field.set(a, field.get(b));
field.set(b, temp);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
And test it!
System.out.println("a:" + a);
System.out.println("b:" + b);
swap(a,b);
System.out.println("a:" + a);
System.out.println("b:" + b);
Source: Stackoverflow.com