[java] Java method to swap primitives

how do I make my swap function in java if there is no method by which we can pass by reference? Could somebody give me a code?

swap(int a, int b)
{
     int temp = a;
     a = b;
     b = temp;
}

But the changes wont be reflected back since java passes parameters by value.

This question is related to java swap

The answer is


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