tags:

views:

443

answers:

11

I am new to java. How to write the java equivalent of the following C code.

public void Swap(int &p, int &q)
{
   int temp;
   temp = *p;
   *p = *q;
   *q = temp;
} 
+1  A: 

There are no pointers in Java. However, every variable that "contains" an object is a reference to that object. To have output parameters, you would have to use objects. In your case, Integer objects.

So you would have to make an object which contains an integer, and change that integer. You can not use the Integer class, since it is immutable (i.e. its value cannot be changed).

An alternative is to let the method return an array or pair of ints.

Sjoerd
Integer objects are immutable, so that won't work either.
Michael Borgwardt
Integers won't help, they are immutable. You need a container, either AtomicInteger (see my answer) or a 1-element List or array or any such thing
seanizer
Again, Integer objects will be passed by value. This won't work either. http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
Lunivore
@Lunivore: no, `Integer` objects are not passed by value. They are not passed at all. A **reference** *to an `Integer` object* will be passed by value. You can only pass references and primitive values in Java, never objects!
Joachim Sauer
Sorry. I was being lazy, and your description is far more accurate. In my defence, the URL explains it very well, even for objects which aren't immutable.
Lunivore
+3  A: 

Java uses pass-by-value. It is not possible to swap two primitives or objects using a method.

Although it is possible to swap two elements in an integer array.

codaddict
It's not possible to swap two anythings by passing them into a method as parameters - not just primitives.
Lunivore
@Lunivore I thought that objects where passed by reference. So, in that case, why couldn't you swap their references?
Cristian
@Cristian: not correct: java objects are references that are passed by value. That's a difference
seanizer
@seanizer thanks for the clarification!
Cristian
+15  A: 

Instead of simply giving a swap method, I'd give you this article. It explains how to make a swap-method, but also explains how not to make it, and why it is not possible in the form you expect it, due to the fact Java is only pass-by-value (unlike C/C++)

Bozho
Good answer, giving the link!
javaguy
A: 

You cannot use references in Java, so a swap function is impossible, but you can use the following code snippet per each use of swap operations:

T t = p
p = q
q = t

where T is the type of p and q

However, swapping mutable objects may be possible by rewriting properties:

void swap(Point a, Point b) {
  int tx = a.x, ty = a.y;
  a.x = b.x; a.y = b.y;
  b.x = t.x; b.y = t.y;
}
SHiNKiROU
+9  A: 

The short answer is: you can't do that, java has no pointers.

But here's something similar that you can do:

public void swap(AtomicInteger a, AtomicInteger b){
    // update: look mom, no variables
    a.set(b.getAndSet(a.get()));
}

You can do this with all kinds of container objects (like collections and arrays or custom objects with an int property), but just not with primitives and their wrappers (because they are all immutable). But the only way to make it a one-liner is with AtomicInteger, I guess.

BTW: if your data happens to be a List, a better way to swap is to use Collections.swap(List, int, int):

Swaps the elements at the specified positions in the specified list.
(If the specified positions are equal, invoking this method leaves
the list unchanged.)

Parameters:
    list - The list in which to swap elements.
    i - the index of one element to be swapped.
    j - the index of the other element to be swapped. 

UPDATE:

apparently the real objective is to sort an array of ints. That's a one-liner with Arrays.sort(int[]):

int[] arr = {2,3,1,378,19,25};
Arrays.sort(arr);

To check the output:

System.out.println(Arrays.toString(arr));
// [1, 2, 3, 19, 25, 378]

And here is a simple helper function to swap two positions in an array of ints:

public static void swap(final int[] arr, final int pos1, final int pos2){
    final int temp = arr[pos1];
    arr[pos1] = arr[pos2];
    arr[pos2] = temp;
}
seanizer
Since I am doing some sorting algorithms, I have array of ints. Do I need to typecast normal ints to AtomicInteger before calling swap?
Melinda
if you want to sort an array of ints, use Arrays.sort() http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#sort%28int%5b%5d%29
seanizer
see my updated answer
seanizer
btw there's no way to typecast a primitive type to an object, but AtomicInteger has a constructor with an int
seanizer
@Melinda: Arrays.sort is the answer, but if you want to swap two simple values follow the ol'good method: `int aux = b; b = a; a = aux;`
helios
+1  A: 

You have to do it inline. But you really don't need that swap in Java.

Bart
Not sure why this got downvoted as it's actually accurate. If you have those two values and you want to swap them, you can inline the method and it works just fine - but I agree, I can't really see why you'd need it in Java either.
Lunivore
Thanks. I was also suprised. It may be too laconic, but the code indicates C-like coding style which totally isn't the way to do things in Java.
Bart
+1  A: 

try this to simulate pass arguments by reference.

public void Swap(RefObject<Integer> p, RefObject<Integer> q)
{
   int temp;
   temp = p.argvalue;
   p.argvalue = q.argvalue;
   q.argvalue = temp;
}

public final class RefObject<T>
{
    public T argvalue;
    public RefObject(T refarg)
    {
        argvalue = refarg;
    }
}
RRUZ
And if you use AtomicReference you can do it in one step: `p.set(q.getAndSet(p.get()));` (see my answer).
seanizer
A: 

In cases like that there is a quick and dirty solution using arrays with one element:

public void swap(int[] a, int[] b) {
  int temp = a[0];
  a[0] = b[0];
  b[0] = temp;
}

Of course your code has to work with these arrays too, which is inconvenient. The array trick is more useful if you want to modify a local final variable from an inner class:

public void test() {
  final int[] a = int[]{ 42 };  
  new Thread(new Runnable(){ public void run(){ a[0] += 10; }}).start();
  while(a[0] == 42) {
    System.out.println("waiting...");   
  }
  System.out.println(a[0]);   
} 
Landei
A: 

Your swap function is essentially changing the values in two pieces of memory. Anything referencing those bits of memory will now get different values.

In Java there aren't really pointers, so this won't work. Instead, references are held on objects, and you can only change stuff inside the objects. If you need to reference one object in two places, so that you can pass the same values around the system and have things react to them changing, try something like the repository pattern or dependency injection.

We can only guess at why you needed this code in C. The only advice I can give is to think about the changes to the objects which you want to achieve, preferably add a method on the actual objects rather than pulling their internals out, and call that method instead. If this doesn't help you, try posting the calling code as we'll probably have a good idea of how to solve the real problem Java-style.

Lunivore
+1  A: 

Snippet-1

public int[] swap1(int[] values) {
  if (values == null || values.length != 2)
    throw new IllegalArgumentException("parameter must be an array of size 2");
  int temp = values[0];
  values[0]=values[1];
  values[1]=temp;
  return values;
}

Snippet-2

public Point swap2(java.awt.Point p) {
  if (p == null)
    throw new NullPointerException();
  int temp = p.x;
  p.x = p.y;
  p.y = temp;
  return p;
}

Usage:

int[] values = swap1(new int[]{x,y});
x = values[0];
y = values[1];

Point p = swap2(new Point(x,y));
x = p.x;
y = p.y;
Andreas_D
+1  A: 

Java is pass by value. So the swap in the sense you mean is not possible. But you can swap contents of two objects or you do it inline.

fastcodejava