Passing reference to an object [duplicate] - java

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
I am checking whether the specified word can be formed on this boggle board with the canForm method. The board has a graph field which indicates adjacent tiles. I do a DFS and set answer to true if the word can be formed.
I understand why the code as it is below doesn't work: answer is a primitive, its value is copied at every recursion and the initial answer (in the public method) stays false.
If I change boolean answer to Set<String> answer = new HashSet<>() for instance, pass the reference to the set in recursion, eventually add the successfully formed word and test for emptiness in the end, it works.
But why does it not work if I simply declare Boolean answer = new Boolean(false) and pass this container? It passes the reference to the object all right, but it mysteriously changes the reference at assignment answer = true (as seen through the debugger), and the initial answer isn't reset. I don't understand.
public boolean canForm(String word) {
boolean answer = false;
int n = M * N;
char initial = word.charAt(0);
// for each tile that is the first letter of word
for (int u = 0; u < n; u++) {
char c = getLetter(u / N, u % N);
if (c == initial) {
boolean[] marked = new boolean[n];
marked[u] = true;
canForm(u, word, 1, marked, answer);
}
}
return !answer;
}
private void canForm(int u, String word, int d, boolean[] marked, boolean answer) {
if (word.length() == d) {
answer = true;
return;
}
for (int v : graph.adj(u)) {
char c = getLetter(v / N, v % N);
if (c == word.charAt(d) && !marked[v]) {
marked[v] = true;
canForm(v, word, d + 1, marked, answer);
}
}
}

Ah, you're using Java. This matters greatly.
Java is, exclusively, a pass by value language. As such, when you call canForm(int, String, int, boolean[], boolean), you are doing two things:
You are creating 5 new variables in the scope of the canForm method
You are initializing them with values from the call site
Altering the values of of the new variables you created will not have any affect on the values of those variables at the call site. Any re-assignments you make will be lost when the method call ends and will have no impact on the values at the call site.
However, in the case of arrays or objects, the "value" being passed is actually a reference to an object. This can be a bit confusing, but it's like the caller and the method each have their own personal key to a shared mailbox. Either could lose their key or replace it with a key to a different mailbox without affecting the other's ability to access the mailbox.
As such, the method can alter the value of the reference (marked = new boolean[]) without altering the caller's reference. However, if the method changes content WITHIN the referenced structure (marked[0] = false) it will be seen by the caller. It's like the method opened the shared mailbox and changed the mail inside. Regardless of which key you use to open it, you'll see the same changed state.
A great analysis: http://javadude.com/articles/passbyvalue.htm
In general:
If you want to return a value from a method, that should be the return value of the method. This makes the code easier to understand, less likely to have side effects and may make it easier for the compiler to optimize.
If you want to return two values, create an object to hold both of them (A general purpose type safe container called a "Tuple" is available in many languages and frameworks).
If you really need to move state between function calls -- and you usually don't -- wrap it with an object to get the equivalent of pass by reference semantics. That's essentially what you're doing when you add your results to a shared Set. Just be aware: programming with side effects, be they shared objects or global state, is defect prone. As you pass a mutable object around, it becomes hard to keep all the potential mechanisms for change in your head. If you can do a job by exclusively through return values, you should try to do so. Some might calls this a "functional [programming] style."
When you give two methods with different intent the same name, it creates confusion, both for readers and in some cases for the compiler. Be specific. We're in no danger of running out of characters.
Finally, you may want to read up on tail recursion. Due to that loop, I believe this implementation may be a stack overflow waiting to happen -- just give it a string that's longer that your stack is deep.

Related

Is it possible to have methods like this in java? Or is it just some "dummy" method from the book to show example?

What does following Java method - method1 do in general? It doesn't have return parameter (because void). Does it just modify input parameter (int a) to the value stated in body of the method (6)? Or does it just take some int a as input and modify some global parameter a to the input value? What is the point of such methods?
public void method1 (int a){
a = 6;
}
Yes, that code snippet is senseless, when considered out of context. Likely there is a larger lesson being taught in your textbook, but we can only guess as to what that might be since we don’t have your textbook.
The method receives a primitive (not an object) variable holding some number. The only line of that method then discards that passed value, and replaces it with the number 6. This makes no sense for two reasons:
We discarded the value being sent to us by the calling programmer. That calling programmer is trying to message us, but we ignore the content of that message.
We do no further work. After assigning six to the variable, it goes out of scope, to be garbage-collected eventually. No productive work was accomplished.
Be clear that we did not change anything in the calling programmer’s state. When our method completes its execution, our variable a goes out of scope, and our value 6 disappears in a puff of smoke.
By the way, adding final to that argument declaration would tell the compiler to flag the re-assignent of the argument variable to a different value.
public void method1 ( final int a ){ …
The point is probably to talk about call by value, and the subtle differences that come into play when using primitive types, as in your example, or reference types, like here.
int someA[] = ...
foo(someA);
with
void foo(int a[]) { a[0] = 1;
or
List<Whatever> someA = ...
foo(someA)
void foo(List<Whatever> a) { a.clear()
will actually have an effect in the place that foo() is called.
In other words: the method shown in the question is really a no-op, it doesn't do anything that can be observed outside (nicely explained in the other answer).

How to return value from the function without exiting from the function?

I am adding byte arrays from an array list of another array list of bytes. So, basically, I am playing with nested byte arrays. I am able to add the first index of each byte array but I am unable to return it immediately. The function will return the whole byte array when all indexes are added. But, I want to return the sum of each index separately.
public static byte[] final_stream(ArrayList<ArrayList<byte[]>> outerstream) {
ArrayList<byte[]> streams = new ArrayList<byte[]>();
int x = 0;
while (x < outerstream.size()) {
streams = new ArrayList<byte[]>();
for (ArrayList<byte[]> bytes : outerstream) {
streams.add(bytes.remove(0));
}
x++;
return stream_Addr(streams); // Here I want to return the value
}
} // Here it gives error to return byte[]
Your code is wrong on many levels, a quick (probably incomplete) list:
you violate java naming conventions. Method names go camelCase(), and variable names (unless constants), too. And you only use the "_" for SOME_CONSTANT
the term "stream" has a very special meaning in Java. A list is not a stream (but you can create a true java stream from a list by yourList.stream())
and yes, what you intend to do in that while loop is beyond my creativity to interpret. Honestly: throw that away, and start from scratch.
Regarding your real question: every "exit" path of a non-void method needs to either throw an exception or to return something.
Finally: what you intend to do isn't possible like that in Java. A caller calls a method, and that method returns one value and then ends.
What you can do, is something like:
thread A creates someList and passes that to some thread B somehow
thread B manipulates that list object, and by using appropriate synchronization the other thread can access that data (while B continues to make updates)
And the real answer is: you can't learn a new language by assuming that the language supports a concept you know from other languages (like pythons generators) to then invent your own syntax or construct in the new language to then be surprised "gosh, it doesn't work". It goes the other way round: you research if your target language has such a concept, if not, you research what else is offered. Then you read a tutorial about that, and follow that.

Pass-by-value And No Return Type Means Nothing Happens?

THERE ARE ISSUES WTIH AN UNDERSTANDING OF Java IN THIS QUESTION. AS THE AUTHOR, I HAVE KEPT THE ORIGINAL QUESTION INTACT AS THE ANSWERS DO AN EXCELLENT JOB OF CLEARING UP THOSE ISSUES
Please, feel free to make changes to below question in order to improve its quality as a pedagogical tool
I have a JAVA class containing one method, the method receives an array object of integers (as you can see in the code); however, in JAVA, everything is pass[ed]-by-value - a well established fact, i.e. overwriting an object or primitive type passed as an argument cannot happen using a local scope object or p. type.
In other words, in order to change an object (primitive or reference) in Java, one must access the data member (or "attribute") directly or indirectly via a member function (or "method") that has the authority to change the attribute. Simply, the method must have an effect.
The other method for changing the value of an object is to return a value via a function and set the original object to the returned value.
Here is my code (and question to follow):
CODE FRAG. I:
public class BlockSort
{
public static void sort(Block [] blocks)
{
boolean sorted = false;
int length = blocks.length;
while(!sorted)
{
sorted = true;
for (int i = 1; i < length; i++)
{
if (blocks[i - 1].width > array[i].width)
{
Block tempBlock = blocks[i - 1];
blocks[i - 1] = blocks[i];
blocks[i] = tempBlock;
}
else if ((blocks[i - 1].width == array[i].width) && (blocks[i - 1].length > array[i].length))
{
Block tempBlock = blocks[i - 1];
blocks[i - 1] = blocks[i];
blocks[i] = tempBlock;
}
}
length = length - 1;
}
}
Essentially, in a very minimalistic sense, the above code functions the same way as this [NOTE: this statement is not true, see answers):
CODE FRAG. 2:
public myClass
{
public void doesNothing(int someParameter)
{
someParameter = someParameter - 1;
}
}
So, here is my question: without a return type, any value passed to above code will not really do anything, correct? In other words, it has no way of modifying what's passed to it with any real clout (because any modifications are function scope).
I am maintaining that the fragment is not testable
You are absolutely right: changes to parameters of primitive and immutable types cannot be detected from the outside; nor should they be.
[the second code fragment] has no way of modifying what's passed to it
That is also true. Moreover, it may not be possible at all - consider this call:
mc.doesNothing(2*a*a + 3*b + c);
The value passed in to doesNothing is computed from three variables, so there is nothing in the caller that could be modified,
In your original code fragment int someParameter is local to the implementation of doesNothing method - in the same sense that local variables are invisible from outside of the method. Testing it does not make any more sense than "testing" changes to any other local variable of a method.
The other code fragment (CODE FRAG. I), however, is different, because Java arrays are neither primitive nor immutable:
public static void sort(Block [] blocks) {
// Any change to the content of blocks will be visible to the caller
}
Therefore, the changes performed to the blocks array inside the method will be visible to the caller, in the same way that the callers would see changes to any other mutable object.
Java is pass-by-value, but objects and arrays are reference types. The array you pass into sort will be the same array you get out (that is, it'll be in the same place in memory), but the things inside the array may be different.
The BlockSort.sort method does have an effect. It gets passed a reference to a Block [] by value. This does not mean it cannot change the array contents.
If you call it for example with BlockSort.sort(myArray) the variable myArray will on return point to the same array instance. But the content of the array may be changed.
what I am asking ultimately is whether or not the above code is testable
Yes, it is. The code you've posted moves elements around inside the blocks array, and you can certainly test whether the items are sorted once the method returns
Block[] blocks = createBlocks();
BlockSort.sort(blocks);
for(int i = 1; i < blocks.length; i++) {
assert blocks[i].width < blocks[i-1].width;
}
Okay, so, I am going to amalgamate the answers written in response to the original question (because there are a lot of good fragments of information in all of the responses that need to be put together).
THREE ISSUES ARE PRESENT
ISSUE no. 1 Pass-by-value or Pass-by-Reference
Essentially, the above question stems from a - seemingly pervasive - lack of understanding or confusion surrounding how Java's pass-by-value works. Objects in Java are indeed pass[ed]-by-value; however, what is passed by value is the reference to the object, i.e. the value behaves somewhat like a pointer in C++ (that may be untrue, but it seems that way). So, the argument received by the parameter is in fact a value, but the value contains - in thought - a reference to the object:
public static void sort(Block [] blocks)
{
// CODE
}
This is not the case for primitive types. Primitive types pass a copy of their value to the parameter, so they are pass-by-value:
public void doesNothing(int someParameter)
{
// CODE
}
ISSUE no. 2: Arrays Are a Reference Type
An array is a reference type object in Java (as it is in other languages); therefore, when an array is passed, no return statement is need to modify its content. Integers - int are primitive type.
ISSUE no. 3: The Two Code Fragments In the Initial Questions (re-posted)
The two code fragments are indeed behaving differently. The first fragment is passing around values referring to a reference type. The second fragment is passing around values (or copies of values) of primitive type.
Therefore, the first code fragment has an effect, while the second does not

Can anyone explain me what is state and mutable data?

In computer science, functional programming is a programming paradigm
that treats computation as the evaluation of mathematical functions
and avoids state and mutable data.
http://en.wikipedia.org/wiki/Functional_programming
Can anyone explain me what is state and mutable data? Can anyone give me examples in either JAVA or JavaScript.
mutable suggest anything that can change, i.e. an int
int a = 0;
System.out.prtinln(a); //prints 0
a = 2;
System.out.prtinln(a); //now prints 2, so its mutable
In java a string is immutable. you cannot change the string value only its reference.
String s1 = "Hello";
System.out.println(s1); //prints Hello
String s2 = s1;
s1 = "Hi";
System.out.println(s2); //prints "Hello" and not "Hi"
State is something which an instance of a class will have (an Object).
If an Object has certain values for its attributes its in a diffrent state then another Object of the same class with diffrent attribute values
State refers collectively to the data stored in the object that determines the current properties of the object. For example, if you have a BankAccount object, the owner of the account and the amount of money in it represent the state of the account.
However, not all state is bad for functional programming, only the mutable+ one is not acceptable. For example, the characters of which a string is composed is that string's state. If you cannot change the content of the string, it is said to have an immutable state. This fits well with functional programming paradigm.
+ mutable is a fancy word for "changeable".
Mutable state is everything that can make a function return a different value, despite it being called with the same arguments.
Simple example in Java:
public static double badSqrt(double x) {
double r = Math.sqrt(x);
if (System.currentTimeMillis() % 42L == 0L) return r;
return r + 0.000000001;
}
This function computes a slightly incorrect result sometimes. We say that badSqrt is impure, because its result does not solely depend on its argument (and constants).
For the person debugging a program that contains calls to badSqrt() or impure functions in general this is a nightmare. Often, the program seems to work, but once in a while, wrong results are delivered. Unless the function is clearly documented or the source code is available, it'll be hard to track the bug.
In such cases, it is said that the behaviour of the functions depends on mutable state. This is state that could be changed (mutated) by completely unrelated parts of the program, or, like in the example, by another program (the operating system).
A classic example of an immutable object is an instance of the Java String class.
String s = “ABC”;
s.toLowerCase();
System.out.println(s);
Output = ABC
This is because s continues referencing its immutable String. If you want to mutate s, a different approach is needed:
s = s.toLowerCase();
This will create a new reference. Now the String s references a new String object that contains "abc".
suppose
int i=5;
now the state of variable i is that , now it has contained value 5.
suppose now i have set i=7;
now the state of variable i is that , now it has contained value 7, it has replaces 5.
if change in value is possible then it is called as-mutable that means
we can change state here.
if change in value is not possible then it is called as-immutable.
Here's the simplest explanation of the difference between state and mutable state. Almost every language has built in methods and functions that we can call to do different things. These methods and functions maintain its own state and we can manipulate it depending on the parameter(s) we use. Different parameters gives different parameters(arguments) can return different values. Now, lets say we make a constructor(JavaScript) to store our own state. We then write a function to manipulate state based on user input, and after we write it we don't change the parameter(s), even when it's called. BUT the content inside state can be changed using setState, resulting in endless changes from the same function without changing the parameter(s).
State data is static. I.e. hypercard. Mutable data resembles more of a binary assembled artificial movement paradigm. QED -Bryan Meluch Purdue 1997 [verb.atim] Web

Is it possible to swap two variables in Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to write swap method in Java?
Given two values x and y, I want to pass them into another function, swap their value and view the result. Is this possible in Java?
Not with primitive types (int, long, char, etc). Java passes stuff by value, which means the variable your function gets passed is a copy of the original, and any changes you make to the copy won't affect the original.
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
// a and b are copies of the original values.
// The changes we made here won't be visible to the caller.
}
Now, objects are a bit different, in that the "value" of an object variable is actually a reference to an object -- and copying the reference makes it point at the exact same object.
class IntHolder { public int value = 0; }
void swap(IntHolder a, IntHolder b)
{
// Although a and b are copies, they are copies *of a reference*.
// That means they point at the same object as in the caller,
// and changes made to the object will be visible in both places.
int temp = a.value;
a.value = b.value;
b.value = temp;
}
Limitation being, you still can't modify the values of a or b themselves (that is, you can't point them at different objects) in any way that the caller can see. But you can swap the contents of the objects they refer to.
BTW, the above is rather hideous from an OOP perspective. It's just an example. Don't do it.
I'm going to be reallllyyyy annoying and pedantic here because the word "value" has a very specific meaning in Java, which people often don't often understand, especially when the variables hold references to objects.
I am going to assume the question asks for this behavior:
x = initialValueForX;
y = initialValueForY;
swap(x, y);
// x now holds initialValueForY;
// y now holds initialValueForX;
This is not possible because Java passes all arguments to methods by value. You can never change the actual value stored inside of x and y this way.
You can, however, if x and y hold references to objects, change the properties of the two objects in such a way as to make the printed values look like each other's initial values:
x = initialValueForX;
y = initialValueForY;
swap(x, y);
System.out.println(x); prints what looks like initialValueForY
System.out.println(y); prints what looks like initialValueForX
This works if your understanding of value is what the object looks like, rather than what the identity of an object is. Usually, that is acceptable.
(Was going to give a good example here, but cHao already did. Plus others pointed out that this was a duplicate question anyway.)

Categories

Resources