swap method in Java

B

Bill Reyn

I know we have been over this before, but I still don't get it./*
How can you swap two integers in Java? - in C++ I can swap references
with 3 lines of code - but how on earth am I supposed to do it in
Java, the code below works, but cannot be the right way of doing it.
Why not?
--------------------------------------------------------------------
/* this swaps 2 integers correctly, BUT its seems non-OO */
class Swap4
{
static int x=5, y=7 ; // this looks horrid!
public static void main(String [] args){
WorkItOut w = new WorkItOut();
w.swaps(x,y);
System.out.println( " x (was 5)now is " + x + " y (was 7) now is " +
y);
}
}
class WorkItOut
{
void swaps(int p, int q){
Swap4 s = new Swap4();
s.x = q;
s.y = p; }
}

---------------------------------------------------------------
If your interested in Cplusplus its simply:
void SwapInt( int &nA, int &nB)
{

int nC;
nC = nA;
nA = nB;
nB = nC;

}
 
M

Michael Borgwardt

Bill said:
I know we have been over this before, but I still don't get it./*
How can you swap two integers in Java? - in C++ I can swap references
with 3 lines of code - but how on earth am I supposed to do it in
Java, the code below works, but cannot be the right way of doing it.
Why not?

Because you're *not supposed* to do it in Java at all, not the way
you want it to. If you want C, you know where to find it, but if
you want to use Java, don't expect to do things the same way as in C.
(what you want to do would be bad style in C++ as well).

Java does not have C-style pointers, and it's object-oriented.
You don't work with arbitrary variables via pointers. Local
variables are *local*. To make them accessibale in another
method, they have to be parts of an object, i.e. fields or
array elements.
 
B

Bryce

I know we have been over this before, but I still don't get it./*
How can you swap two integers in Java? - in C++ I can swap references
with 3 lines of code - but how on earth am I supposed to do it in
Java, the code below works, but cannot be the right way of doing it.
Why not?

Why on earth would you do it that way...
--------------------------------------------------------------------
/* this swaps 2 integers correctly, BUT its seems non-OO */
class Swap4
{
static int x=5, y=7 ; // this looks horrid!

Well, you declared them static. I see no reason why.

In Java, you don't have pointers. You have references.

So in short, you cannot swap variables in a method. You would need to
do it inline like this:

public class SwapTest {
public static void main (String[] args) {
Integer x = new Integer(5);
Integer y = new Integer(7);

System.out.println("Before Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");

Integer tmp = x;
x = y;
y = tmp;

System.out.println("After Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");
}
}

More information on the differences between C++ and Java and how Java
passes values to functions:
http://www-106.ibm.com/developerworks/java/library/j-passbyval/
 
J

Joona I Palaste

Bryce said:
On 22 Jun 2004 04:55:44 -0700, (e-mail address removed) (Bill Reyn)
wrote:
Why on earth would you do it that way...
Well, you declared them static. I see no reason why.
In Java, you don't have pointers. You have references.
So in short, you cannot swap variables in a method. You would need to
do it inline like this:
public class SwapTest {
public static void main (String[] args) {
Integer x = new Integer(5);
Integer y = new Integer(7);
System.out.println("Before Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");

Integer tmp = x;
x = y;
y = tmp;

System.out.println("After Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");
}
}

Your example above would work just as well if you used:

int x = 5;
int y = 7;

int tmp = x;
x = y;
y = tmp,

If all your variables are local to one method, it doesn't matter whether
they are primitives or references, you can use their values any way you
like.
The problem, which you don't seem to have grasped, comes when these
variables are passed onto other methods.

In C you can do this:

void swap(int *x, int *y) {
int tmp = *x;
*x = *y;
*y = tmp;
}

In Java, you can't. Not with primitive types, anyway. But if you have
some sort of wrapper object, you can do this:

void swap(IntWrapper x, IntWrapper y) {
int tmp = x.getValue();
x.setValue(y.getValue());
y.setValue(tmp);
}

You can't do this with java.lang.Integer as it doesn't have methods to
change its value, but you can write your own wrapper class.
More information on the differences between C++ and Java and how Java
passes values to functions:
http://www-106.ibm.com/developerworks/java/library/j-passbyval/

I suggest you read that yourself...
 
A

Andy Fish

In C you can do this:

void swap(int *x, int *y) {
int tmp = *x;
*x = *y;
*y = tmp;
}

In Java, you can't. Not with primitive types, anyway. But if you have
some sort of wrapper object, you can do this:

in java, all parameters are passed by value. that's a decision the language
designers took and I for one am 100% behind them. when you pass a parameter
into a procedure you don't expect that your own variable to be updated by
the procedure.

sometimes it would have been nice to be able to return 2 values from a
function like you can in perl. then you could have a function like

(int, int) swap (int a, int b) {
return (b, a);
}
and call it like this:
(a, b) = swap (a, b);

but the whole idea of passing by reference is something I don't think
accords well with good programming practice.
 
J

Joona I Palaste

in java, all parameters are passed by value. that's a decision the language
designers took and I for one am 100% behind them. when you pass a parameter
into a procedure you don't expect that your own variable to be updated by
the procedure.

The example I gave, but which you snipped away, was not trying to
disprove that all parameters are passed by value. It was trying to show
that when you pass a reference to an object from one method to another,
the references in both methods refer to the same object.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"When a man talks dirty to a woman, that's sexual harassment. When a woman talks
dirty to a man, that's 14.99 per minute + local telephone charges!"
- Ruben Stiller
 
T

Tim Ward

Andy Fish said:
in java, all parameters are passed by value. that's a decision the language
designers took and I for one am 100% behind them. when you pass a parameter
into a procedure you don't expect that your own variable to be updated by
the procedure.

Or even a constant. Here's a good one from the days of FORTRAN (I've
probably got the syntax wrong, it's a while since I've done any):

SUBROUTINE NASTY( I )
I = 10
RETURN

CALL NASTY( 6 )
WRITE( 6, 99 )
99 FORMAT( ..... )
END

What happens? NASTY changes the value of its parameter, which is a constant
passed by reference, so every later reference to the constant 6 actually
finds the value 10. So, the debug print line doesn't work, because it tries
to write to unit 10, which probably doesn't exist, instead of unit 6, the
line printer.

(Yes, I discovered this by debugging real code, *not* by trying to construct
a theoretical pathelogical case.)
 
T

Thomas Weidenfeller

Joona said:
int x = 5;
int y = 7;

int tmp = x;
x = y;
y = tmp,

From the old days, when memory was scare, and one couldn't afford a
temporary variable or register but could waste some 1MHz CPU cycles :)

x ^= y;
y ^= x;
x ^= y;

/Thomas
 
J

Joona I Palaste

From the old days, when memory was scare, and one couldn't afford a
temporary variable or register but could waste some 1MHz CPU cycles :)
x ^= y;
y ^= x;
x ^= y;

Which will only work for unsigned integer values and will still fail
miserably if x and y should ever be the same variable... (as it can
be in Java if they're elements of the same array, and the indices
happen to match).
 
B

Bryce

Bryce said:
public class SwapTest {
public static void main (String[] args) {
Integer x = new Integer(5);
Integer y = new Integer(7);
System.out.println("Before Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");

Integer tmp = x;
x = y;
y = tmp;

System.out.println("After Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");
}
}

Your example above would work just as well if you used:

int x = 5;
int y = 7;

int tmp = x;
x = y;
y = tmp,

Yea, and it works just as well the other way.. What's your point?
If all your variables are local to one method, it doesn't matter whether
they are primitives or references, you can use their values any way you
like.

I think that's the point I was trying to make!
The problem, which you don't seem to have grasped, comes when these
variables are passed onto other methods.

I grasped it just fine. What makes you think otherwise?
In C you can do this:

void swap(int *x, int *y) {
int tmp = *x;
*x = *y;
*y = tmp;
}

In Java, you can't. Not with primitive types, anyway.

And not with the primitive wrappers either... Of course you can write
your own wrapper object, but that wasn't the point of the OP's post.
 
A

Andy Fish

The example I gave, but which you snipped away, was not trying to
disprove that all parameters are passed by value. It was trying to show
that when you pass a reference to an object from one method to another,
the references in both methods refer to the same object.

sorry, I wasn't in any way trying to infer that your example was wrong. I
was just saying that I happen to believe java's lack of pass-by-reference is
a positive aspect of the language rather than a drawback
 
J

Joona I Palaste

Bryce said:
Bryce said:
public class SwapTest {
public static void main (String[] args) {
Integer x = new Integer(5);
Integer y = new Integer(7);
System.out.println("Before Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");

Integer tmp = x;
x = y;
y = tmp;

System.out.println("After Swap");
System.out.println(" x=[" + x + "]");
System.out.println(" y=[" + y + "]");
}
}

Your example above would work just as well if you used:

int x = 5;
int y = 7;

int tmp = x;
x = y;
y = tmp,
Yea, and it works just as well the other way.. What's your point?

Why use Integers when ints work just as well? Your use of Integers led
me to believe you thought only references can be swapped, not
primitives.
I think that's the point I was trying to make!

So it appears to be. I read your code but not your text. Had you used
primitives, I would not even have written my reply...
I grasped it just fine. What makes you think otherwise?

Reading your code too fast. As I said, because you used Integers instead
of ints, I thought you thought reference types were *needed* to swap
values at all. This is consistent with your correct statement that a C-
style int swap method won't work in Java unless you use objects to wrap
the ints in. However, as we both know, that doesn't mean it's impossible
to swap ints without using objects, only impossible to do that in
another method.
 
R

Roedy Green

in java, all parameters are passed by value. that's a decision the language
designers took and I for one am 100% behind them.

Me too. Keeping track of just how many levels of indirection, and the
multiple ways to generate the same assembler code wasted so much time
in writing C++. In Java you just have . and it always works without
fuss. The increased maintainability and legibility was easily worth
the loss of flexibility.
 
R

Roedy Green

Which will only work for unsigned integer values and will still fail
miserably if x and y should ever be the same variable... (as it can
be in Java if they're elements of the same array, and the indices
happen to match).

See sample code at http://mindprod.com/jgloss/swap.html

It works fine for int, which is signed, and it works fine for both
positive and negative values. ^ treats the sign bit like any other.
For all practical purposes ^ sees in as unsigned, just like >>> does.

// XOR swap fail for swapping array elements if two indexes refer to
the same element.
{
int[] x = { 100, 200 };
int i = 0, j = 1;
x ^= x[j];
x[j] ^= x;
x ^= x[j];
// prints 200 100
System.out.println( x[0] + " " + x[1] );
}
{
int[] x = { 100, 200 };
int i = 0, j = 0;
x ^= x[j];
x[j] ^= x;
x ^= x[j];
// prints 0 200
System.out.println( x[0] + " " + x[1] );
}
 
S

Stefan Ram

/* this swaps 2 integers correctly, BUT its seems non-OO */
class Swap4
{
static int x=5, y=7 ; // this looks horrid!
public static void main(String [] args){
WorkItOut w = new WorkItOut();
w.swaps(x,y);
System.out.println( " x (was 5)now is " + x + " y (was 7) now is " + y);
}

When is it not applicable to swap the variable names in
the rest of the block? I.e.,

class Swap4a
{ final static int x=5, y=7 ;
public static void main( final String[] args )
{ System.out.println( "x now is " + y + " y now is " + x ); }}
 
C

Chris Smith

Stefan said:
When is it not applicable to swap the variable names in
the rest of the block? I.e.,

class Swap4a
{ final static int x=5, y=7 ;
public static void main( final String[] args )
{ System.out.println( "x now is " + y + " y now is " + x ); }}

Generally speaking, when:

a) the swaps occur in a loop or conditional, or

b) the variables being swapped are not local (for example, they are
fields of an object or elements of an array), unless you can prove that
the data will only be accessed in controlled in a local environment.

c) the variables are fields of an array (even under the local exception
above), and you plan to access them in a loop. Or, on a related but
less common note, the variables are fields and you plan to access them
using reflection.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jezuch

U¿ytkownik Roedy Green napisa³:
Me too. Keeping track of just how many levels of indirection, and the
multiple ways to generate the same assembler code wasted so much time
in writing C++. In Java you just have . and it always works without
fuss. The increased maintainability and legibility was easily worth
the loss of flexibility.

Yeah, I got burned by the "one level of indirection too far" effect recently
while coding a C++ program for my university class... I thought it was a bug
somewhere in STL but my colleague, a C++ fanatic, showed me my mistake.
Ohhhhhhhh, baaaaad Java habits! ;)
 
S

Steven J Sobol

Roedy Green said:
Me too. Keeping track of just how many levels of indirection, and the
multiple ways to generate the same assembler code wasted so much time
in writing C++. In Java you just have . and it always works without
fuss. The increased maintainability and legibility was easily worth
the loss of flexibility.

I don't mind using C/C++ at all, but C/C++ pointers tend to really piss me
off. I am extremely glad Java does NOT have them.
 
T

Thomas Weidenfeller

Joona said:
Which will only work for unsigned integer values
No.

and will still fail
miserably if x and y should ever be the same variable...

Since both were of type int, this is not possible in Java. You can not
construct Java code were two separate int variables point to the same
memory location. ints are not objects, so you can't mess up something
with references pointing to the same object.
(as it can
be in Java if they're elements of the same array, and the indices
happen to match).

Now you are redefining the problem by changing the type from int to
int[]. And yes, one sure can mess up things now.

/Thomas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top