Java array method(Confusion) [duplicate] - java

This question already has answers here:
Why do arrays change in method calls? [duplicate]
(6 answers)
Closed 7 years ago.
I'm confused about the method. I thought typically you need to return something. Or in my mind I would have thought the need for a for loop that passes the elements back from the method that adds 5 to each element.
However When the array is passed to the method, the array itself changes, but why?
public static void main(String[] args) {
int ray[]={3,4,5,6,7};
change(ray);
for(int y: ray){
System.out.println(y);
}
}
public static void change(int x[]){
for(int counter = 0; counter < x.length;counter++){
x[counter]+=5;
}
}

In Java, all objects are passed by reference, and arrays are objects. That means that your change method receives the same array that was created in main--not a copy of it, the same object. So when you modify it, the main method sees that change too.

Java is pass-by-value for primitives, and pass-by-reference(value) for everything else (including arrays).
http://javadude.com/articles/passbyvalue.htm
What that basically means is that your function does not get a copy of the array, it gets the array itself.
Try it with an int (the original value will not change, because it's a primitive).
public static void main(String[] args) {
int ray[]={3,4,5,6,7};
change(ray);
for(int y: ray){
System.out.println(y);
}
}
public static void change(int i){
i = i + 10;
}
public static void change(int x[]){
for(int counter = 0; counter < x.length;counter++){
x[counter]+=5;
}
}
Some will say that Java always passes by value, but that's because of a poor choice of definitions when it comes to references.
Objects are conceptually passed by reference, and primitives by value. You can call it what you like but it looks like a duck, walks like a duck and quacks like a duck.
Try this, you'll get a better idea:
/**
* Main
*
*/
public class Main {
static class IntegerClass {
int internal;
public IntegerClass(int i) {
internal = i;
}
public void setInternal(int i) {
internal = i;
}
public int getInternal() {
return internal;
}
}
public static void main(String[] a) {
int x = 10;
changeInteger(x);
System.err.println(x);
IntegerClass ic = new IntegerClass(10);
changeIntegerClass(ic);
System.err.println(ic.getInternal());
}
public static void changeIntegerClass(IntegerClass ic) {
ic.setInternal(500);
}
public static void changeInteger(Integer i) {
i = 500;
}
}

Related

How can I use varible from another function?

For printing the value of factorial, I want to use the value of fact in the facto() function. How can I achieve this?
I have tried declaring variables i and fact in the facto() function.
public class Factorial {
int fact=1;
int n=5,i=1;
void facto()
{
for(i=n;i>=1;i--)
{
fact=fact*i;
}
}
public static void main(String args[])
{
Factorial obj1= new Factorial();
System.out.println(obj1.fact);
}
}
The answer I'm getting is what it gets the value from the class and is initialized with 1. I want to get 120 as the solution.
Void function means the function that does not return any value, so it is wrong to use void function.
If you want to get a value from the method. You should use a method that can return a value as following :
public class Factorial {
public int facto()
{
int fact=1;
int n=5,i=1;
for(i=n;i>=1;i--)
{
fact=fact*i;
}
return fact;
}
public static void main(String args[])
{
Factorial obj1= new Factorial();
System.out.println(obj1.facto());
}
}
ps : I have changed the place of variables to scope of facto() method with warning of #Idle_Mind.
Because this has a slight side effect in that if you call facto() more than once you'll get different results. To "fix" this you could re-initialize "fact" to 1 inside facto()
Don't use fields. Use a parameter and a return value.
public class Factorial {
private int facto(int n) {
int fact = 1;
for (int i = n; i >= 1; i--) {
fact = fact * i;
}
return fact;
}
public static void main(String args[]) {
Factorial obj1 = new Factorial();
System.out.println(obj1.facto(5));
}
}

shared variable for java thread

My program is not returning the expected output, I tried very hard but I don't know how to do for this code. What can I do ?
Expected output
1 2 3 4 5 6 7 8 ......2000
Actual output
1 2 3 4 5 6 1 2 3 4 5 6 ..1000
Main
public class Race_ConditonTest {
public static void main(String[] args) {
Race_Condition2 R1 = new Race_Condition2();
Race_Condition2 R2 = new Race_Condition2();
R1.start();
R2.start();
}
}
RaceCondition2 (sub class)
public class Race_Condition2 extends Thread{
Race_Condition R= new Race_Condition();
public void run() {
R.sum();
}
}
RaceCondition class (super class)
public class Race_Condition {
int x=0;
public int Load(int x){
return x;
}
public void Store(int data) {
int x= data;
System.out.println(x);
}
public int Add(int i,int j) {
return i+j ;
}
public void sum() {
for (int i=0 ; i<1000 ; i++) {
this.x=Load(x);
this.x=Add(x,1);
Store(x);
}
}
}
how can i share x ?
simple way> make x static.
...
static int x=0;
...
Edit
After some tests, if you find something weird happening then make the Store function synchronized.
public synchronized void Store(int data) {
int x= data;
System.out.println(x);
}
check out how synchronized work synchronized
If your goal is to make the attribute x shared between R1 and R2 you could make it static in the RaceCondition class.
static int x=0;
Take care that if x is shared, they will be concurrent access to it, so some weird output could produce. Make the function that access x synchronized (as described here) :
// static cause it only access a static field
// synchronized so the access the the shared resource is managed
public static synchronized void sum() {
for (int i=0 ; i<1000 ; i++) {
this.x=Load(x);
this.x=Add(x,1);
Store(x);
}
}
You should probably make the same changes on the other functions.

Method cannot modify input int parameter

Not to sure why the integers lowRange and highRange are not going between these classes.
package guessnumber;
public class GuessNumber
{
static public int computerGenedNumber;
static public int lowRange;
static public int highRange;
static public int playerGuess;
public static void main(String[] args)
{
Input.range(lowRange, highRange);
Rand.number(lowRange, highRange, computerGenedNumber);
Input.guess();
Give.result();
}
}
Next Class:
package guessnumber;
import javax.swing.JOptionPane;
class Input
{
public static void range(int lowRange, int highRange)
{
String rawUserInput;
rawUserInput = JOptionPane.showInputDialog("Please enter the range you wish to guess. (EX: 1-10)", "1-10");
for(int i = 0; i < rawUserInput.length(); i++)
{
if(rawUserInput.charAt(i) == '-')
{
lowRange = Integer.parseInt(rawUserInput.substring(0, i));
highRange = Integer.parseInt(rawUserInput.substring(i + 1, rawUserInput.length()));
}
}
}
static void guess()
{
}
}
And the last relevant one:
package guessnumber;
class Rand
{
static public void number(int lowRange, int highRange, int computerGenedNumber)
{
computerGenedNumber = (int)(Math.random() * (highRange - lowRange) + lowRange);
}
}
The rest of the classes are currently blank so I don't think I need to put them here too.
Here is a simplified piece of code which reproduce your problem, and make sure you understand why it is causing problem and the solution:
class Foo {
public static void square(int a, int result) {
result = a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
Foo.square(a, result);
System.out.println("result " + result);
}
}
This should be fundamental understanding of Java. Checkout what is the meaning of "pass-by-value"
In brief, the parameter passed in the method is a copy of the argument. Therefore when you are changing the parameter in your method, you are just changing another piece of data, and your change is not reflected to caller.
One way to fix is to change the method and return your result, which looks like:
class Foo {
public static int square(int a) {
return a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
result = Foo.square(a);
System.out.println("result " + result);
}
}
Another common solution is to pass in a "holder object" as the result. Although the object reference is passed by value, that copy of object reference is still pointing to the same object as caller. I won't go too deep into this as it is less common and you should be able to get the proper way doing so once you have better understanding on how value (including object reference) is passed around.
Parameters are passed "by value" in Java. What that means is that when you call
input.range(lowRange, highRange);
it gives the current values of those variables to input.range, but it doesn't give input.range a way to modify them. In the range method:
public static void range(int lowRange, int highRange)
the parameters lowRange and highRange (which have no connection with the variables in GuessNumber, even though the names are the same) are copies of what you pass in. When you assign lowRange = ... in the method, it changes the copy but has no effect at all on the lowRange and highRange in GuessNumber.
You need to write a range method that returns two values. This needs a little bit of work, but I'd write a Range class that has low and high members, and then change your method to
public static Range range()
That method would have to create a new Range object. I think it's OK for low and high to be public members of Range:
class Range {
public int low;
public int high;
public Range(int low, int high) {
this.low = low;
this.high = high;
}
}
Normally, public data in a class is a bad thing, but for a class whose only purpose is to let a method return multiple values, it's OK in my opinion.

Is it possible to link integers from a method to a class?

I have a quick question out of curiosity...if I declare an integer in one method, for example: i = 1, is it possible for me to take that i and use its value in my main class (or another method)? The following code may be helpful in understanding what I'm asking...of course, the code might not be correct depending on what the answer is.
public class main {
public main() {
int n = 1;
System.out.print(n + i);
}
public number(){
i = 1;
}
}
No you cannot! Not unless you make it an instance variable!
Or actually send it to the function as an argument!
First, let's start simple. All methods that are not constructors require a return type. In other words,
public void number(){
i = 1;
}
would be more proper.
Second: the main method traditionally has a signature of public static void main(String[] args).
Now, on to your question at hand. Let's consider a few cases. I will be breaking a few common coding conventions to get my point across.
Case 1
public void number(){
i = 1;
}
As your code stands now, you will have a compile-time error because i is not ever declared. You could solve this by declaring this somewhere in the class. To access this variable, you will need an object of type Main, which would make your class look like this:
public class Main {
int i;
public static void main(String[] args) {
Main myMain = new Main();
myMain.number();
System.out.print(myMain.i);
}
public void number(){
i = 1;
}
}
Case 2
Let's say you don't want to make i a class variable. You just want it to be a value returned by the function. Your code would then look like this:
public class Main {
public static void main(String[] args) {
Main myMain = new Main();
System.out.print(myMain.number());
}
public int number(){ //the int here means we are returning an int
i = 1;
return i;
}
}
Case 3
Both of the previous cases will print out 1 as their output. But let's try something different.
public class Main {
int i = 0;
public static void main(String[] args) {
Main myMain = new Main();
myMain.number();
System.out.print(myMain.i);
}
public void number(){
int i = 1;
}
}
What do you think the output would be in this case? It's not 1! In this case, our output is 0. Why?
The statement int i = 1; in number(), it creates a new variable, also referred to as i, in the scope of number(). As soon as number() finishes, that variable is wiped out. The original i, declared right under public class Main has not changed. Thus, when we print out myMain.i, its value is 0.
Case 4
One more case, just for fun:
public class Main {
int i = 0;
public static void main(String[] args) {
Main myMain = new Main();
System.out.print(myMain.number());
System.out.print(myMain.i);
}
public int number(){
int i = 1;
return i;
}
}
What will the output of this be? It's 10. Why you ask? Because the i returned by number() is the i in the scope of number() and has a value of 1. myMain's i, however, remains unchanged as in Case 3.
You may use a class-scope field to store you variable in a class object or you can return it from one method or pass it as a parameter to the other. Mind that you will need to call your methods in the right order, which is not the best design possible.
public class main {
int n;
int i;
public main() {
n = 1;
System.out.print(n + i);
}
public number(){
i = 1;
}
}
Yes, create a classmember:
public class Main
{
private int i;
public main() {
int n = 1;
System.out.print(n + i);
number();
System.out.print(n + i);
}
public number(){
i = 1;
}
}
void method(){
int i = 0; //has only method scope and cannot be used outside it
}
void method1(){
i = 1; //cannot do this
}
This is because the scope of i is limited to the method it is declared in.

Question about Static methods

The question asks for the user to enter. lets forget about that and make it already initialized with some values so I can understand the first part.
Write a static method
public static int findMax(int[] r)
which receives as a parameter an array of numbers of type int and returns the maximum value.
Write a main method to test your program with array size 10 and elements entered by user.
Can't get what you exactly want to do? But if want that one class has static method and other class in main access that then you can try like this..
public class Demo {
public static void main(String[] args) {
int i = FindMaxClass.findMax(new int[10]); // pass int array
System.out.print(i);
}
}
class FindMaxClass{
public static int findMax(int[] r){
//logic to find max.
return 0; // return the max value found.
}
}
If static method should be in same class then others answers are good/correct.
public static int findMax(int[] values) {
int max = Integer.MIN_VALUE;
for (int val : values) {
if (val > max) {
max = val;
}
}
return max;
}
public static void main(String[] args) {
System.out.println("Max value: " + findMax(new int[]{1,2,3,1,2,3}));
}
I'm not going to write the code to solve your exact problem, but I'll tell you how to create and call a static method. See the example below:
public class Test {
// This is a static method
static void myMethod(int myArg) {
System.out.println("Inside Test.myMethod " + myArg);
}
// This is how to call it from main()
public static void main(String[] args) {
myMethod(3);
}
}
If you need more information to static methods take a look at:
http://openbook.galileocomputing.de/javainsel/javainsel_05_003.htm#mjd51d5220468ee4a1f2a07b6796bb393b
But you already know how to iterate over arrays?
Or maybe you are able to be more specific what you do not understand and what you have tried yet?

Categories

Resources