This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 4 years ago.
I have the following code:
public class Main {
static void swap (Integer x, Integer y) {
Integer t = x;
x = y;
y = t;
}
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
swap(a, b);
System.out.println("a=" + a + " b=" + b);
}
}
I expect it to print a=2 b=1, but it prints the opposite. So obviously the swap method doesn't swap a and b values. Why?
This doesn't have anything to do with immutability of integers; it has to do with the fact that Java is Pass-by-Value, Dammit! (Not annoyed, just the title of the article :p )
To sum up: You can't really make a swap method in Java. You just have to do the swap yourself, wherever you need it; which is just three lines of code anyways, so shouldn't be that much of a problem :)
Thing tmp = a;
a = b;
b = tmp;
Everything in Java is passed by value and the values of variables are always primitives or references to object.
If you want to implement a swap method for Integer objects, you have to wrap the values into an array (or ArrayList) and swap inside the array. Here's an adaptation of your code:
public class Main {
static void swap (Integer[] values) {
if ((values == null) || (values.length != 2)) {
throw new IllegalArgumentException("Requires an array with exact two values");
}
Integer t = values[0];
values[0] = values[1];
values[1] = t;
}
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer[] integers= new Integer[]{a,b};
swap(integers);
System.out.println("a=" + integers[0] + " b=" + integers[1]);
}
}
(Just added this answer because Svish mentioned, that "You can't really make a swap method in Java" fg)
As Svish and others pointed out it it's call by value, not by reference in Java. Since you have no pointers in Java you need some kind of holder object to really swap values this way. For example:
static void swap(AtomicReference<Integer> a, AtomicReference<Integer> b) {
Integer c = a.get();
a.set(b.get());
b.set(c);
}
public static void main(String[] args) {
AtomicReference<Integer> a = new AtomicReference<Integer>(1);
AtomicReference<Integer> b = new AtomicReference<Integer>(2);
System.out.println("a = " + a);
System.out.println("b = " + b);
swap(a, b);
System.out.println("a = " + a);
System.out.println("b = " + b);
}
You would need to pass the parameters by reference, which it's not possible in java. Also Integers are inmutables, so you cannot exchange the values as you don't have a setValue method.
Integer are immutable - you can't change their values. The swapping that occurs inside the swap function is to the references, not the values.
You would need to return both references in an array to achieve what you want
static Integer[] swap(Integer a, Integer b) {
return new Integer[]{b, a};
}
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer[] intArray = swap(a, b);
a = intArray[0];
b = intArray[1];
System.out.println("a=" + a + " b=" + b);
}
If Integer had a setValue method, you could do something like this.
static void swap(Integer a, Integer b) {
int temp = a.intValue();
a.setValue(b.intValue());
b.setValue(temp);
}
But it doesn't - so to achieve what you want, return an array.
Using the XOR operator is a very bad idea:
First, it is far less readable. Second, there were times when this was faster but nowadays the opposite is the case. See
Wikipedia
for reference.
As all the guys mentioned its a Pass-By-Value thing.
Just liked to add: you can use this method of swapping GLOBAL integers.
private void swap (){
a ^= b;
b ^= a;
a ^= b;
}
It eliminates the use of another variable, and its just cooler :)
Java code:
class swap {
int n1;
int n2;
int n3;
void valueSwap() {
n3 = n1;
n1 = n2;
n2 = n3;
}
public static void main(String[] arguments) {
Swap trial = new Swap();
trial.n1 = 2;
trial.n2 = 3;
System.out.println("trial.n1 = " + trial.n1);
System.out.println("trial.n2 = " + trial.n2);
trial.valueSwap();
System.out.println("trial.n1 = " + trial.n1);
System.out.println("trial.n2 = " + trial.n2);
}
}
Output:
trial.n1 = 2
trial.n2 = 3
trial.n1 = 3
trial.n2 = 2
Using Scanner:
import java.util.*;
public class Swap {
public static void main(String[] args){
int i,temp,Num1,Num2;
Scanner sc=new Scanner(System.in);
System.out.println("Enter Number1 and Number2");
Num1=sc.nextInt();
Num2=sc.nextInt();
System.out.println("Before Swapping Num1="+Num1+" Num2="+Num2);
temp=Num1;
Num1=Num2;
Num2=temp;
System.out.println("After Swapping Num1="+Num1+" Num2="+Num2);
}
}
Related
I have to make a program which works like this. first it gets a number from input and then it gets (number) * strings.
for example:
2
a b
or
3
x1 x2 x3
then in the output it prints something like this:
Math.max(a, b)
or
Math.max(x1, Math.max(x2, x3))
I want to make Math.max method syntax with this code. I hope you understood!
Another Sample Input & output:
Input =
4
a b c d
Output =
Math.max(a, Math.max(b, Math.max(c, d)))
can someone help me?
The code I've wrote for it, can you suggest me some changes to make it better?
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
String[] r = new String[n];
for (int i = 0; i < n; i++) {
r[i] = input.next();
}
printmax(r);
}
public static int i = 0 , j = 0;
public static boolean last = false;
public static void printmax(String [] r){
if (last == true) {
System.out.print(r[r.length - 1]);
while (j < r.length - 1){ System.out.print(")");
j++;
}
}
if (r.length == 2) System.out.print("Math.max(" +r[0] + ", " + r[1] + ")");
if (r.length > 2) {
while (i < r.length -1) {
if (i == r.length -2) last = true;
System.out.print("Math.max(" + r[i] + ", ");
i++;
printmax(r);
}
}
}
}
You can use the following code to achieve the above, here m calling maxElement() function recursively to achieve somthing like this Math.max(a, Math.max(b, Math.max(c, d)))
public static void main(String args[]){
int length = 2; //here read the input from scanner
String[] array = {"a", "b"}; //here read this input from scanner
String max = maxElement(array,0,length);
System.out.println(max);
}
public static String maxElement(String[] start, int index, int length) {
if (index<length-1) {
return "Math.max(" + start[index] + ", " + maxElement(start, index+1, length)+ ")";
} else {
return start[length-1];
}
}
Output:
Math.max(a, b)
You need to do something like this.
First you define a function maxElement which takes your variable array as a parameter.
public static maxElement(String[] variables) {
return maxElementBis(variables,0);
}
Then you call a second function : maxElementBis which takes an additional argument which represents the index of the variable we are processing.
public static String maxElementBis(String[] variables, int index) {
if (variables.length < 2)
return "not enought variables";
if (variables.length - index == 2)
return "Math.max("+ variables[index]+","+variables[index + 1]+")";
return "Math.max("+ variables[index]+","+maxElementBis(variables,index + 1)+")";
}
If the array contains less than two variables you cannot do what you want.
If you only have two variables left, this is your stop condition and you can directly return Math.max(v1,v2).
Otherwise you recursively call your function maxElementBis.
I am new to Java so I need help.
How can I access the variables of the method method1 and compare them with the variable int c? What should I return?
public static void main (String [] args){
int c = 30;
// I want to compare c with a, for example:
if (c > a)
{
System.out.println(c + " is greater than " + a);
}
}
I want to do the above comparison without touching method1()
public double method1(){
int a = 10; int b = 20;
if (a > b)
{
System.out.println(a + " is greater than " + b);
}
else if (a < b)
{
System.out.println(b + " is greater than " + a);
}
//What should I return?
return ????;
}
if you are writing "int c = 30;" directly below main then it becomes global variable.
Global Variable means: "c" can be accessed inside methods(anywhere in same class).
if you are writing "int c = 30;" inside particular method than you cannot access outside that particular method.
Following is example of global variable.
public static void main (String [] args){
int c = 30;
public double method1(){
int a = 10;
if (a > c)
{
System.out.println(a + " is greater than " + c);
return a;
}
else if (a < c)
{
System.out.println(c + " is greater than " + a);
return b;
}
}
I hope it works for you.
How can I access the variables of the method "method1" [...] without touching the method1()?
You can't.
Local variables in a method are only accessible inside that method. And if that method doesn't give you a way to see them, then without modifying the method, you can't see them.
Since a is always 10, you could do if (c > 10) instead.
import java.util.*;
public class something {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int kvadratek, a, b;
a = sc.nextInt();
b = sc.nextInt();
--a;
--b;
if(a>b) {
kvadratek=b;
b=a;
a=kvadratek;
System.out.println((a*(a+1)*(2*a+1)/6-((a+1)*a/2)*(a+b)+(a+1)*a*b));
}
else {
System.out.println(a*(a+1)*(2*a+1)/6-((a+1)*a/2)*(a+b)+(a+1)*a*b);
}
}
}
i am new to java coding and i have a question if i can write this part
kvadratek=b;
b=a;
a=kvadratek;
differently so that it will give me the same result as the else part. Is it possible to do it with if, while sentences? I actually don't need the else part of the code if I insert
kvadratek=b;
b=a;
a=kvadratek;
but is there a way to change that part?
First thing, to avoid repeating code, is to extract it to a method:
private static int compute(int a, int b) {
return (a*(a+1)*(2*a+1)/6-((a+1)*a/2)*(a+b)+(a+1)*a*b);
}
Now you want b to be the biggest of the two numbers, and a to be the other one. Instead of swapping them, you could use Math.max and Math.min:
a = sc.nextInt() - 1;
b = sc.nextInt() - 1;
System.out.println(compute(Math.min(a, b), Math.max(a, b));
You can use this:
int k = Math.max(a, b)
a = Math.min(a, b);
b = k
After this piece of code, b will be the greater between the original a and b, while a will be the smaller, thus removing the need for the if/else.
I was doing some RnD I came across this this difference
my java code is as below
public class Main {
public static void main(String[] args) {
Integer x = 10;
increment(x);
System.out.println("print x" + x);
List<String> strList = new ArrayList<String>();
strList.add("one");
strList.add("two");
strList.add("three");
strList.add("four");
strList.add("five");
strList.add("six");
System.out.println("Before removing");
for (String string : strList) {
System.out.println("item " + string);
}
removeSomeItem(strList);
System.out.println("After removing");
for (String string : strList) {
System.out.println("item " + string);
}
}
private static void removeSomeItem(List<String> strList) {
strList.remove(0);
strList.remove(4);
}
private static void increment(Integer x) {
x++;
}
}
I got out for the above code as below
print x10
Before removing
item one
item two
item three
item four
item five
item six
After removing
item two
item three
item four
item five
my question is when I had sent Integer to function it behaved like value same way when I had sent List<String> its behaving like reference why is this difference ?
can any one explain
The main difference is that the Integer class is immutable, hence why you do not see the change in your main method.
x++; // this will simply return a new Integer
To see the difference, try this from your main method:
x = increment(x);
and in the increment method, change it to this:
return x++;
However, with your list example, you are simply passing a copy of the reference to the list. As long as that reference is not set to a new object (which it isn't), it is able to update the original list you passed.
This is exactly what happened
private static Integer b;
public static void main(String[] args) {
Integer x0 = 10;
b = x0;
increment(x0);
}
private static void increment(Integer x1) {
//x1 == b is true
x1++; //implies x1 = x1 + 1;
//x1 == b is now false
//at the end of the day, you've done nothing to x0 or b
}
EDIT: This code will fail because apparently, the JVM is caching Integer values between -128 and 127, see here, set x0 = 150 and test.
public class Main {
static Integer b;
public static void main(String[] args) {
Integer x = 150;
b = x;
increment(x);
}
private static void increment(Integer x) {
System.out.println(x == b); //true
x++;
System.out.println(x == b); //false
b++;
System.out.println(x == b); //false
}
}
Well in case of,
removeSomeItem(strList);
you are passing the address of original ArrayList to the method so when it remove some value using that reference the original ArrayList change too (actually they are single object with two access point , I mean the reference ).
But in case of Integer you also pass the reference and the increment(Integer x) method receive the original reference. But as Integer immutable when I do something like,
x++;
In the background its work like
x=new Integer(x+1);
That’s why the original Integer remain unchanged when the ArrayList change.
I am trying to make an algorithm for the following task:
I have two integers a ≤ b
The algorithm has to transform a into b by adding 1 and multiply by 2 operations. For example, if a = 5 and b = 23 the program should output something like 23 = ((5 * 2 + 1) * 2 + 1)
I have to use recursion
I've already Googled many times but all I could find is ideas on how to transform a matrix, how to do geometric transformations, how to transform string into another string and similar stuff.
Does anybody have any ideas?
This is the way to find the transformation with the minimum number of operations:
(EDIT: Added parenthesis)
public static void main (String [] args)
{
int a = 5, b = 23;
System.out.println (transform (a, b) + " = " + b);
}
public static String transform (int a, int b)
{
if (a == b) return "" + a;
if (b % 2 == 0 && 2 * a <= b)
{
b = b / 2;
return transform (a, b) + " * 2";
}
else
{
b = b - 1;
return "(" + transform (a, b) + " + 1)";
}
}
This actually prints it, but it may not be exactly what you are looking for I'm not sure.
private static String doDo(int a, int b, StringBuilder sb) {
if (a == b) {
String ret = sb.toString();
int charCount = ret.replaceAll("[^)]", "").length();
for (int i = 0; i < charCount; i++)
ret = "(" + ret;
return ret;
}
if (a < (b/2f)) {
sb.append(")*2+1");
return doDo(a*2 + 1, b, sb);
} else {
sb.append("+1");
return doDo(a+1, b, sb);
}
}
System.out.println(doDo(5, 23, new StringBuilder().append("5")));
This is printed -> ((5)*2+1)*2+1
Following method should work for you I think:
int transform(int a, int b) {
if (a>= b)
return a;
else if (a*2 <= b)
return transform(2*a, b);
else
return transform(a + 1, b);
}
here's some pseudo code that you can use
transform(a, b)
start
if a >= b
return
else
print formatted progress
transform(a * 2 + 1, b)
end
If you don't want to over shoot then use this (modified version of #anubhava's solution).
int transform(int a, int b) {
if (a >= b){
return a;
} else {
int c = a*2 + 1;
if (c>b){
return a;
} else {
return transform(c, b);
}
}
}
Here's a version that uses recursion to determine the optimal strategy for doing the transform in the minimal number of operations. I assume that each time you double, that counts as one operation; each time you add 1, that counts as one operation, and the goal is to minimise the total number of operations.
And testing it on the 5->23 example yields:
((((5)*2)+1)*2)+1=23
You could be terser with the syntax, but hopefully a little verbosity helps to show the intent of the code.
Hat tip to josh.trow as I used his idea on how to do the string formatting.
import java.util.ArrayList;
import java.util.List;
public class DoubleAndAddAlgorithm {
public enum Op {
DOUBLE, ADD_ONE
}
private static List<Op> getOptimalTransform(int a, int b) throws IllegalArgumentException {
// Returns the list of operations that comprises the optimal way to get from a to b
// If a is already bigger than b, we have a problem
if (a > b) {
throw new IllegalArgumentException("a cannot be greater than b");
}
List<Op> result = new ArrayList<Op>();
// If we can get there in one operation, do so
if (2*a == b) {
result.add(Op.DOUBLE);
} else if (a+1 == b) {
result.add(Op.ADD_ONE);
}
// If doubling would cause us to overshoot, all we can do is add 1
// and take it from there...
else if (2*a > b) {
result.add(Op.ADD_ONE);
result.addAll(getOptimalTransform(a+1, b));
}
// Otherwise, let's try doubling, and let's try adding one, and use
// recursion to see which gets us to the target quicker
else {
List<Op> trialResultDouble = getOptimalTransform(2*a, b);
List<Op> trialResultAddOne = getOptimalTransform(a+1, b);
// Let's say (arbitrarily), that if neither operation results in us
// getting to the target any quicker than the other, we choose to add 1
if (trialResultDouble.size() < trialResultAddOne.size()) {
result.add(Op.DOUBLE);
result.addAll(trialResultDouble);
} else {
result.add(Op.ADD_ONE);
result.addAll(trialResultAddOne);
}
}
return result;
}
public static String getFormattedResult(int a, int b) {
try {
List<Op> ops = getOptimalTransform(a, b);
StringBuilder sb = new StringBuilder();
sb.append(Integer.toString(a));
for (Op op: ops) {
if (op == Op.DOUBLE) {
sb.insert(0, "(");
sb.append(")*2");
} else if (op == Op.ADD_ONE) {
sb.insert(0, "(");
sb.append(")+1");
}
}
sb.append("=");
sb.append(Integer.toString(b));
return sb.toString();
} catch (IllegalArgumentException e) {
return "Illegal arguments supplied";
}
}
public static void main(String[] args) {
System.out.println( getFormattedResult(5, 23) );
}
}
Search for an algorithm called double&add, it's the dual of the square&multiply one...i'm sorry but i don't know the details.