How to write a basic swap function in Java [duplicate] - java

This question already has answers here:
Java method to swap primitives
(8 answers)
Closed 6 years ago.
I am new to java. How to write the java equivalent of the following C code.
void Swap(int *p, int *q)
{
int temp;
temp = *p;
*p = *q;
*q = temp;
}

Here is one trick:
public static int getItself(int itself, int dummy)
{
return itself;
}
public static void main(String[] args)
{
int a = 10;
int b = 20;
a = getItself(b, b = a);
}

Sorting two ints
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){
// look mom, no tmp variables needed
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.
Sorting an int[] array
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;
}

Here's a method to swap two variables in java in just one line using bitwise XOR(^) operator.
class Swap
{
public static void main (String[] args)
{
int x = 5, y = 10;
x = x ^ y ^ (y = x);
System.out.println("New values of x and y are "+ x + ", " + y);
}
}
Output:
New values of x and y are 10, 5

Use this one-liner for any primitive number class including double and float:
a += (b - (b = a));
For example:
double a = 1.41;
double b = 0;
a += (b - (b = a));
System.out.println("a = " + a + ", b = " + b);
Output is a = 0.0, b = 1.41

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.

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

What about the mighty IntHolder? I just love any package with omg in the name!
import org.omg.CORBA.IntHolder;
IntHolder a = new IntHolder(p);
IntHolder b = new IntHolder(q);
swap(a, b);
p = a.value;
q = b.value;
void swap(IntHolder a, IntHolder b) {
int temp = a.value;
a.value = b.value;
b.value = temp;
}

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;

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.

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

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

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.

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.

You can swap variables with or without using a temporary variable.
Here is an article that provides multiple methods to swap numbers without temp variable :
http://topjavatutorial.com/java/java-programs/swap-two-numbers-without-a-temporary-variable-in-java/

You can easily write one yourself.
given:
int array[]={1,2};
you do:
int temp=array[0];
array[0]=array[1];
array[1]=temp;
And you're done. 3 lines of code.

Swapping by using pointer is not possible in java. However, you can implement swapping by passing array containing two objects.
Code goes like this:
public class Swap {
public static void swap(String [] a){
String temp;
temp = a[0];
a[0] = a[1];
a[1] = temp;
}
public static void main(String [] args){
String [] foo = new String[2];
foo[0] = "str1";
foo[1] = "str2";
swap(foo);
System.out.println("First value: "+ foo[0]);
System.out.println("Second value: "+ foo[1]);
}
}
Output:
First value: str2
Second value: str1

public class swaptemp {
public static void main(String[] args) {
String s1="10";
String s2="20";
String temp;
System.out.println(s1);
System.out.println(s2);
temp=Integer.toString(Integer.parseInt(s1));
s1=Integer.toString(Integer.parseInt(s2));
s2=Integer.toString(Integer.parseInt(temp));
System.out.println(s1);
System.out.println(s2);
}
}

//here is also another answer:
class SwapDemo{
static int a=1, b=2 ;
public static void main(String [] args){
Swap swp = new Swap();
swp.swaps(x,y);
System.out.println( " a (was 1)now is " + a + " b (was 2) now is " + b);
}
}
class Swap{
void swaps(int c, int d){
SwapDemo f = new SwapDemo();
f.a = c;
f.a = d;
}
}

class Swap2Values{
public static void main(String[] args){
int a = 20, b = 10;
//before swaping
System.out.print("Before Swapping the values of a and b are: a = "+a+", b = "+b);
//swapping
a = a + b;
b = a - b;
a = a - b;
//after swapping
System.out.print("After Swapping the values of a and b are: a = "+a+", b = "+b);
}
}

Related

Java is giving me different results for the same process

what i mainly want to know is :
in the line public static void val(int[] x) what does the (int[] x) do?
Also: why am i getting the final added up values when i ask
for(int y:i){
System.out.println(y);
}
but not for:
int y=2+i2;
System.out.println(y);
why isnt the vale() method not converting the "i2" value to "x" immediately and then continuing the compilation by using the "x" value for subsequent 'i2" calculations....sorry if my question is vague....i just dont know how else to put it....thanks
complete code:
public static void main(String[] args) {
int[] i = { 25, 22 };
int i2 = 41;
val(i);
for (int y : i) {
System.out.println(y);
}
vale(i2);
int y = 2 + i2;
System.out.println(y);
}
public static void val(int[] x) {
for (int c = 0; c < x.length; c++) {
x[c] *= 2;
}
}
public static void vale(int x) {
x += 23;
}
Java always passes arguments by value, never by reference (not only primitive types, reference types as well). This is why your vale(int x) method doesn't work.
Have a look at this article, it explains everything: http://www.javaworld.com/article/2077424/learn-java/does-java-pass-by-reference-or-pass-by-value.html
I think you need to read about pass by value and reference in Java. Regarding your questions, both val(i) & vale(i2) are technically pass by value. Since array is an object type, its reference is passed to the method in case of val(i) and hence you could see the modifications when you print the reference. However, vale(i2) takes a primitive integer type as parameter and thus the modifications within the method doesn't affect the original value. To understand this better you can modify your val(int[] x) method as follows:
public static void val(int[] x) {
x = new int[] {35, 57};
for (int c = 0; c < x.length; c++) {
x[c] *= 2;
}
}
I just added x = new int[] {35, 57}; which would make the value of x point to a different reference and not affect the original value. Hope this clarifies!
Your method val(int[] x) accomplishes absolutely nothing in this code. It returns void(nothing) to the main() function and the operations you preform inside val() with your array x are done on a copy of x...
possible fix:
public static int[] val(int[] x){
int[] newarr = new int[x.length];
for (int c=0; c<x.length;c++){
newarr[c] = x[c]*2;
}
return newarr;
}
in main:
int[] i={25,22};
i = val(i); // creates an array with every element doubled and assigns it to i
same story with vale() !

The value of an array changes without any command affecting it

I am facing a weird problem in the following piece of code:
public class Main {
public static void main(String args[]){
int[] c = {0};
int[] a = c;
int[] b = c;
a[0] = 1;
b[0] = 2*a[0];
System.out.println(" a " + a[0]);
}
}
This returns "a 2", and not "a 1", which means that the value of the array a changed, even though the operation is only supposed to affect the array b!
Does anyone know where this might come from, and how to solve it please?
The culprit is here:
int[] c = {0};
int[] a = c;
int[] b = c;
You think you're creating three different arrays but really they're all pointing to the same array c.
System.out.println(a + "-" + b + "-" + c); //[I#1b6d3586-[I#1b6d3586-[I#1b6d3586
All variables are actually pointing at the same array in memory.
What you have done is effectively create 2 copies of the same array as when you declare an array:
int[] a = c;
This is the same as writing:
int* a = c;
Writing, c is the same as &c[0], its the base address of the array.
So:
int[] c = {0};
int[] a = c;
int[] b = c;
a[0] = 1; // This also sets the value of c[0] and b[0] to 1
b[0] = 2*a[0]; // This is 2 * 1 = 2

How to call method in lambda expression

I have 3 ways to swap 2 variables (basically 3 different algorithms). Since you can't pass a method as a parameter in Java, I thought this would be a good time to use lambda expressions.
chooseSwapMethod(int selection) {
if(selection == 1) {
functionThatUsesSwap(
(int[] arr, int x, int y) -> {
int holder = arr[x];
arr[x] = arr[y];
arr[y] = holder;
});
}
else if(selection == 2)
{
functionThatUsesSwap(
(int[] arr, int x, int y) -> {
arr[x] -= arr[y];
arr[y] = arr[x]-arr[y];
arr[x] -= arr[y];
});
}
else if(selection == 3) {
functionThatUsesSwap(
(int[] arr, int x, int y) -> {
arr[x] = arr[x]^arr[y];
arr[y] = arr[y]^arr[x];
arr[x] = arr[x]^arr[y];
});
}
else {
throw new IllegalArgumentEarr[x]ception();
}
}
but in the method functionThatUsesSwap how do you actually use the swap? Am I not understanding lambda expressions clearly? For example
public void functionThatUsesSwap(Swaper s)
{
int[] someArr = {1, 2};
s.doSwap(someArr, 0, 1);//this is where I’m stuck
System.out.println(“a: “+someArr[0]+” b: “+someArr[1]);//this should print out a: 2 b: 1
}
Java is pass by value, that means that in the following:
int a = 5;
int b = 6;
swap(a,b);
System.out.println(a+" "+b);
There is no way for the function swap to change value of a or b and the result will always be 5 6.
What you can do is:
pass and arrays of 2 numbers into the swap method, and swap numbers inside that array.
make a class to hold 2 numbers and pass that.
Going with possibility 2:
class Pair {
int a, b;
}
#FunctionalInterface
interface Swapper {
void swap(Pair p);
}
void main() {
Pair p = new Pair();
p.a = 5;
p.b = 6;
Swapper swapper = (v -> {
v.a ^= v.b;
v.b ^= v.a;
v.a ^= v.b;
});
swapper.swap(p);
System.out.println(p.a + " " + p.b);
}
Result: 6 5. Note that your claim that you can't pass a method as a parameter in Java isn't entirely true, since you can pass interfaces instead.
EDIT:
There is yet another approach (I haven't thought of this earlier because Interger class is immutable). You can create a mutable (= changable) object vrapper for integer value, something like:
class IntVrapper {
public int value;
}
Then your swap method could swap data between those two objects.

Java - continues adding value on integer

im having a little problem about my codes
public class ex{
public static void main(String[] args) {
int sum,int a = 1,int b = 2;
int c = 1,int d = 2;
if (a<b) {
sum = sum+1;
}
if (c<b) {
sum = sum+1;
}
System.out.println("output :"+sum);
}
}
I wanted to add a value of 1 in the int sum if the conditions are met. but its not compiling
the output should be like this:
output: 2
First things first.. If you are a beginner to Java, this is an advise for you to learn well about the syntax of Java declaration, initialization and usage.
Declaration:
If you want to declare variables separately, you have to do it as below:
int a;
int b;
int c;
If you want to declare multiple variables in a single line, you have to do it as below:
int a,b,c;
Initialization:
If you want to initialize multiple variables in a single line, do it as below:
int a=0, b=4, c=3;
Usage:
Important thing you would like to learn here is - you can always declare 'n' number of variables without initialization.. but if you want to use any of them, they must be initialized at least once before you use them. Using them also includes even to print them.
If you won't follow any of the above mentioned points, you must get a compilation error.
Here is the code you must follow:
public class ex{
public static void main(String[] args) {
int sum = 0 , a = 1, b = 2;
int c = 1, d = 2;
if (a < b) {
sum = sum + 1;
}
if (c < b) {
sum = sum + 1;
}
System.out.println("output :"+sum);
}
}
public class TestExample {
public static void main(String args[]){
int sum = 0 ;
int a = 1;
int b = 2;
int c = 1;
int d = 2;
if (a<b) {
sum = sum+1;
}
if (c<b) {
sum = sum+1;
}
System.out.println("output :"+sum);
}
}
declaration of variable is wrong you should not declare your variable like int a,int b= 10
avoid declaration of variable on same line.
your code gives compilation error try this one it will give output as your expectation
Don't declare variables on the same line like this, even when it's compilable. It compacts your code in a way that makes it difficult to understand, especially when you name them a,b,c and d.
int sum = 0;
int a = 1;
int b = 2;
int c = 1;
int d = 2;
Change your declaration of variables to that and the rest of the code will run fine. But I would recommend reading some basic Java tutorials so you understand how to write code that compiles. I would also suggest using an IDE so these kinds of errors are flagged while you write your code.
IDEOne (with compilation errors): http://ideone.com/rYzIf5
IDEOne (without compilation errors): http://ideone.com/rYzIf5
Try this:
int sum = 0,a = 1,b = 2;
int c = 1, d = 2;
if (a<b) {
sum++;
}
if (c<b) {
sum++;
}
System.out.println("output :"+sum);

Returning an Array

I am new to programming and Java and trying to write a program which takes two arrays as input and reports back their sum. I want to do this by creating a class which takes two arrays as constructor inputs and then creating a method that adds them together and a method which prints out this new sum array.
Here is my class:
public class test1 {
int [] a;
int [] b;
int [] final23;
public test1 (int x [], int y [])
{
int [] a = x;
int [] b = y;
}
public int [] sum(int [] x, int[] y)
{
int [] a = x;
int [] b = y;
for (int i = 0; i < Math.min(x.length, y.length); i++)
{
final23 [0]=x[0] + y[0] ;
}
return final23;
}
public void print()
{
for (int i = 0; i < final23.length; i++)
{
System.out.println(final23[0]);
}
}
}
Here is my main class:
public class main1 {
public static void main(String[] args)
{
int l[] = {4,7,2};
int k[] = {4,6,2};
test1 X = new test1(k,l);
X.sum(k,l);
X.print();
}
}
I keep getting an error when I run this through:
Exception in thread "main" java.lang.NullPointerException
at test2.sum(test2.java:17)
at main1.main(main1.java:8)
I guess what I really want is for my sum method to take a test1 object as input. However, I don't know how to do this.
Your variable final23 is never initialized.
In java you have to initialize an array before using it. Either you do it during the declaration (like you did with k and l) or you have to do it later with a new arrayType[arraySize];
Here are the way an array can be declared/initialized.
int[] iArray = {1, 2, 3}; //Declaration, Initialization, set values
int[] iArray; //Declaration
iArray = new int[3]; //Initialization
iArray[0] = 1; //Set value
int[] iArray; //Declaration
iArray = new Array[3]{1, 2, 3}; // Initialization and set values
You can of course for the two last sample put the initialization on the same line that the declaration.
Try this (cleaned) code :
public class test1 {
int[] final23;
public int[] sum(int[] x, int[] y) {
final23 = new int[Math.min(x.length, y.length)];
for (int i = 0; i < final23.length; i++) {
final23[i] = x[i] + y[i];
}
return final23;
}
public void print() {
for (int aFinal23 : final23) {
System.out.println(aFinal23);
}
}
public static void main(String[] args) {
int l[] = {4, 7, 2};
int k[] = {4, 6, 2};
test1 x = new test1();
x.sum(k, l);
x.print();
}
}
Resources :
Oracle.com - Arrays
JLS - Array Initializers
JLS - Array Creation Expressions
I'm going to take a long shot here
public int [] sum(int [] x, int[] y)
{
int [] a = x;
int [] b = y;
for (int i = 0; i < Math.min(x.length, y.length); i++)
{
final23 [0]=x[0] + y[0] ;
}
return final23;
}
As a side comment, I'm guessing that you want to add all of the elements of the vector, not just the first. Change your for-loop body to:
final23 [i]=x[i] + y[i] ;
What's final23? Where is it created?
Try adding this to your constructor
public test1 (int x [], int y [])
{
int [] a = x;
int [] b = y;
this.final23 = new int[Math.min(a.length, b.length)];
}
Now final23 is defined and created, and you can use it in your class.
If you supply test1 with arrays in the ctor, you don't need them in the sum method, just use the ones you have in the class already:
public int [] sum()
{
for (int i = 0; i < Math.min(x.length, y.length); i++)
{
final23 [i]=a[i] + b[i] ;
}
return final23;
}
You also had an error in the sumation, you didn't use the iteration variable, you also need to initialize final23 in the ctor.
You have to initialize final23 array before putting elements in it (on line 17).
**final23 = new int[Math.min(x.length, y.length)];**
for (int i = 0; i < Math.min(x.length, y.length); i++)
{
final23 [0]=x[0] + y[0] ;
}
I see a couple of things to point out here.
public test1 (int x [], int y [])
{
int [] a = x;
int [] b = y;
}
First of all, remember that each test1 object - that is, each instance of your test1 class - has variables named a and b. I'm guessing that in the constructor, you want to take the arrays x and y which were passed as parameters and store them into a and b of the object. To do that, all you have to do is write
a = x;
b = y;
You don't have to write int[] again, not when you just want to access an existing array-type variable. You only write that when you're creating a new array-type variable. In this case, when Java sees that you've written int[] a in the constructor, it thinks you want to create yet another array-type variable named a, separate from the one in the test instance, and that's the one that gets set equal to x. The thing is, that local variable gets lost at the end of the constructor. So you're left with a test1 instance that has variables a and b that still refer to nothing, i.e. they're null.
By the way, since you're going to be using the array final23 later on, you should initialize it. Right now, it refers to null because you never set it to equal anything else. You'll need to create a new array and store it in that variable in order to be able to use it later on. So put this line in your constructor:
final23 = new int[Math.min(a.length, b.length)];
That creates the new array with a length equal to the shorter of the two arrays passed in.
Moving on:
public int [] sum(int [] x, int[] y)
{
int [] a = x;
int [] b = y;
In this bit of code, you have the same issue as in the constructor: you create two new array-type variables a and b that get used instead of the ones in the test1 object. I don't think that's what you meant to do. So I'd say get rid of those last two lines entirely.
There's another problem, though: if you think about it, you still have two arrays stored in the test1 object. Assuming you've fixed your constructor, those are the same two arrays that were passed to the constructor. And now you're getting two new arrays under the names x and y. So you have four arrays total. Which ones did you want to sum up? I'm guessing that you meant to sum the two arrays that were passed to the constructor. In that case, your sum method doesn't need to - and shouldn't - accept more arrays as parameters. Get rid of the parameters x and y, so your sum method just looks like
public int [] sum()
{
Now you have to change the rest of that method to use a and b, starting with the for loop. Change its opening line to this:
for (int i = 0; i < Math.min(a.length, b.length); i++)
{
I notice you were wondering how to get your sum method to take an instance of test1. Well, in a way it actually does. There's a special hidden parameter passed to all methods (except static ones) that contains the object the method was called on - in fact, using your main program as an example you could kind of think of X.sum(k,l); as actually calling test1.sum(X,k,l);, where X is the special hidden parameter. You can access it inside the method using the name this (so you could write this.a instead of just a), but Java is generally smart enough to do that for you.
In the body of the for loop, you have another problem. What you want to do is add up corresponding elements of the arrays, i.e. a[0] + b[0] goes into final23[0], a[1] + b[1] goes into final23[1], and so on. But inside the for loop, you only ever add up element 0 of each array. You need to use the loop index variable i, because that runs through all the values from 0 to the length of the shorter array minus 1.
final23 [i] = a[i] + b[i];
}
return final23;
}
So the first time the loop runs, i will be 0, and you'll set final23[0] = a[0] + b[0]. The next time it runs, i will be 1, and you'll set final23[1] = a[1] + b[1]. And so on.
The same problem occurs in your print method. Each time through the loop, you always print out final23[0], when you really should be printing out final23[i] because i changes each time you go through the loop. Change it to
public void print()
{
for (int i = 0; i < final23.length; i++)
{
System.out.println(final23[i]);
}
}
At this point your program should be working, I think, but there are still some improvements you could make to its design. For one thing, every time you create an object of test1, you know you're immediately going to call sum on it. So why not just put the summing-up code right into the constructor? That way you know that the sum will be computed right when you create the object, and you don't have to call sum explicitly.
Of course, once you do that, you'll have no way to access the array final23 from your main class - except that if you want to print it, you can call the print method. But what if you want to write a main class that, say, adds up two arrays, and then adds the result to a third array? It'd be nice to have a way to get the result from the test1 instance. So you can add an accessor method, possibly named getFinal23, that just returns the sum array final23.
In practice, this operation of adding two arrays would probably be implemented as a static method. So if you want, you could try starting over, and writing it as a static method. (Remember that a static method is one which doesn't receive a special hidden parameter) Inside the static method, you'd have to create the final23 array, go through the loop to compute the sums, and then return the array you created. You'll need to enclose the static method in a class, of course, but that class doesn't have to have a constructor since you never really use it for anything. It'd look something like this:
public class SumClass { // pun intended ;-)
public static int[] sum(int[] x, int[] y) {
// you fill in this part
}
}

Categories