Pass by Reference and recursion - java

I have the following recursive function prototype:
public void calcSim(Type<String> fort, Integer metric)
Integer metric = 0;
calcSim(fort, metric);
System.out.println("metric: " + metric);
}
I want to print the value of metric as shown above. However it is always zero. Now, when I print at the end of the function, I do get a valid number.
How do I pass by reference or get the equivalent functionality like in C++
What all can I do with regards to my parameter passing? (by value, by reference, etc...)

There is no such thing as pass by reference in Java, sorry :(
Your options are either to give the method a return value, or use a mutable wrapper and set the value as you go. Using AtmoicInteger cause it is in JDK, making your own that doesn't worry about threadsafety would of course be mildly faster.
AtomicInteger metric = new AtomicInteger(0);
calcSim(fort, metric);
System.out.println("metric: " + metric.get());
Then inside the calcSim set it with metric.set(int i);

To get the behavior of pass by reference, you can create a wrapper class, and set the value in that class, eg:
class MyWrapper {
int value;
}
Then you can pass a MyWrapper to your method and change the value, for example like this:
public void calcSim(Type<String> fort, MyWrapper metric)
metric.value++;
System.out.println("metric: " + metric.value);
calcSim(fort, metric);
}

Integer is wrapper class. Wrapper classes are immutable. So, what you are expecting can't be achieved with Integer type.
You may create mutable wrapper class around primitive and update the object to achieve what you want.

Two big issues:
You are redefining metric with the same name in your method as well. How is program printing anything. It should complain at compilation time.
No defined exit criteria. Does you program(method) stops?
I think you wanted something as (pseudo code as I don't know what are you doing):
public void calcSim(Type<String> fort, Integer metric)
if(condtion){
//print or return
}else{
//modify fort or metric so that it exits
calcSim(fort, metric); //call this with modified value
System.out.println("metric: " + metric.value);
}
}

Related

Is there a way to create an anonymous Object array with data and an overridden toString method?

Object[] x = new Object[] {"Skye", "Eyks", 123}
{
#Override
public String toString()
{
return this[0] + " " + this[1] + " (" + this[3] + ")";
}
};
So that x.toString() would return "Skye Eyks (123)".
NetBeans says it expects a semi-colon and that it's an Illegal start of expression.
Why I want to use an anonymous array class is to display the data in a combo-box and get all the other data in my array once the user submits the form.
No, this is impossible.
Your code paste strongly suggests an alternate solution:
Java is a statically and nominally typed object oriented language. Java is very very bad at dealing with data stored in a heterogenerous, untyped, and unnamed 'grabbag of unknown mystery' - which is what Object[] is.
This is presumably what you're looking for:
public class Word {
final String word;
final int score;
public String getWord() {
return word;
}
public String getReverse() {
// ...
}
public int getScore() {
return score;
}
#Override public String toString() {
return word + " " + getReverse() + " (" + score + ")";
}
}
Now, it's got structure (the compiler now knows, and your editor can now help you out): a Word has properties like getWord() and getReverse(); getReverse() is far more informative than [1]. You now have a place to add documentation if you want (how do you intend to 'document' new Object[]?), and you have room for flexibility (for example, getReverse() could be calculated on the fly instead of passed in at construction).
You can now write methods that take a Word. This:
public void printWord(Word word) {}
is almost self evident. Compare to this:
/**
* This function requires that you pass a 3-sized object array, with:
* The first argument must be a string - this is the word to print.
* The second argument must be that string, reversed. It will be printed in light grey for a mirror effect.
* The third argument must be a boxed integer, this will be printed in the lower right corner as page number
*/
public void printWord(Object[] o) {}
That's a ton of documentation, and this is considerably worse: This documentation is unstructured - whereas with an actual class, the names of methods can carry most of this meaning and lets you document each fragment independently. You can also farm out any checks and other code to the right place, instead of ending up in a scenario where the code to check if the input array is proper needs to be called in many places, and you need to go out of your way to document, for everything, what happens if you pass invalid input (vs. having to do that only once, in Word's constructors).
If you end up with an Object[] due to external forces, such as, say, the arguments passed along to your main function, then the general aim is to convert that to a proper object once, and as soon as possible, so that your java code remains as uninfected by this heterogenous, untyped and unnamed mysterymeat as possible.
NB: Yes, that means you need to make a ton of classes, for everything you can think of, so you end up with clean code. Lombok's #Value can help with this, as can java15's records.

Java: calling an object using a generated string

I would like to call an object through the use of a generated string.
As you can see, name is being generated correctly.
Also, the method for getting the object works fine.
However I can not use name to reference the object even though that is the name of the object.
Why is that? How can I solve this?
public class FrameTest{
public static void main(String[] args) {
ObjectMethod first_object = new ObjectMethod(); //instanciate object
first_object.setCost(2.5);
String object = "first";
String one = "object";
String name = object + "_" + one;
System.out.println(name);
System.out.println(first_object.getCost());
System.out.println(name.getCost()); //this line does not work
}
}
public class ObjectMethod{
public double value;
public void setCost(double cost) {
value = cost;
}
public double getCost() {
return value;
}
}
The closest I can think of to what you're describing, short of using Reflection (if you're asking this question, you're not ready for Reflection) is to have a map of strings to objects.
Map<String,Runnable> options = new HashMap<>();
options.add("getCost", new CostGetter(...));
options.add("getDescription", new DescriptionGetter(...));
String command = getCommandFromUi();
options.get(command).run();
It could be Callable rather than Runnable. It could be an interface of your own. In Java 8 it could be Supplier and you could pass lambdas:
options.add("getCost", () -> currentUser.price());
Have a look at the Command and Strategy patterns in any book about design patterns.
You have to understand: Java isn't ruby or python or some other dynamic language.
There is no magic connection that allows you to turn a reference to a String into something else.
In other words: the fact that you put "object_one" into a string object doesn't allow you to treat that String like some actual variable object_one.
The one feature of Java that goes into that direction is reflection. But that is really an advanced topic; and before you look into that, you should understand the real basics of Java. So, better start here.
What I mean is: as the answer by "slim" points out: you could use a Map in order to implement some sort of "call by name" functionality. But the point is: that is "not how you do things in Java". Java is a statically compiled language; and there is no sense in using Java when one then tries to break out of that system and do things that rely on flat string parsing at runtime.
This will not work as you wish, because you are trying to call getCost() on String name object.
name - is just a string, but not the object of ObjectMethod class.
You cannot invoke name.getCost() and type of name is String, and string donot have getCost() method. Hence, your code fails here.
String name = object + "_" + one;
In above code, you are assigning name field with value "object_first". That means, field name is type of String with value "object_first". So, name is in no way related to ObjectMethod class, and hence name.getCost() make no sense.
Basically, what you are trying to accomplish
"I would like to call an object through the use of a generated string"
is not possible unless you use reflection.
java is a Strong typed language
that means you have to define a variable and also specify the variable type before you use it and (emphasis mine)
Certain operations may be allowable only to that type*
just because you do:
String objectName;
Object comboValue = departingStop.getSelectedItem();
Object combo2Value = finalStop.getSelectedItem();
objectName = comboValue + "_" + combo2Value;
dosn't mean that now objectName mutated from string into a ComboBox...
imagine how terrible this could be:
Car tata = new Car();
Robot kuka = new Robot();
String foo = tata.getName() + kuka.getName();
now what is foo? a transformer?? NO,
is still a String...
since that is a string you just can not do
foo.drive(), because is not a car, neither foo.weld(); because is not a robot

How to use method result properly in Java

I will use result of a method call in some calculation. I have two ways:
Invoke method once and store the return into a local value, then use the local value in some calculation.
Use call method many times.
Please see my sample code:
public class TestMethod {
public void doSomething_way1() {
String prop1 = this.getProp1();
if (prop1 != null) {
String value = prop1 + " - another value";
System.out.println(value);
}
}
public void doSomething_way2() {
if (this.getProp1() != null) {
String value = this.getProp1() + " - another value";
System.out.println(value);
}
}
public String getProp1() {
return "return the same value";
}
}
NOTE that, the method doSomething will be invoked a lots at a time ( In web environment )
Can someone show me which way I should use in the case the result of method will be used at least 3 times?
I believe using the method call many times is more intuitive and makes the code more readable.
In your case it wont matter even if you give call to the getProp1() method multiple times. Because it does not perform any computation, object creation or I/O operation which may cause performance issues.
You could go a step further:
public void doSomething_way2() {
if (this.getProp1() != null) {
System.out.println(this.getProp1() + " - another value");
}
}
If the method is getting called a lot (I mean many, many times a second), creating the extra variable could change performance a tiny bit with respect to garbage collection and what not... I think its trivial.
In some cases, getting the value more than once could raise thread-safety issues, if the value weren't final, whereas if you fetch the value once, at least the entire operation of way1 will be consistent with a single value for prop1.
But even if threading weren't an issue, I still think it's better, stylistically, to 'cache' the value in a local variable which is well named.
(I'm assuming that your real code does something more significant than return the fixed String "something") - the getProp1 method as written is pretty thread-safe. :)
From a performance standpoint, at least from the examples given, it does not appear to be any fundamental difference doing it one way or another. Object allocations for small numbers of iterations (unless they are heavyweight objects) should be minimal.
However, from a programming design and implementation standpoint, it may be helpful to keep the program 'cohesive', i.e. have classes more closely represent things.
In which case the local variable from the return of the method (as it is a different 'thing') and subsequent calculation.
e.g.:
interface Dog{
void wagTail();
Dung eat(DogFood f);
}
interface Human{
void pickUpDung(Dung d);
}
codeLoop(Human m, Dog d, DogFood f){
d.wagTail();
Dung poo = d.eat(f);
m.pickUpDung(poo);
}
whereas a less cohesive example would be
interface Dog{
void wagTail();
void eatAndHaveHumanPickUp(DogFood f);
}
// you can fill in the rest...
it wouldn't follow the principle of cohesion, because you wouldn't normally expect a dog call to have this kind of method...

Output Parameters in Java

With a third party API I observed the following.
Instead of using,
public static string getString(){
return "Hello World";
}
it uses something like
public static void getString(String output){
}
and I am getting the "output" string assigned.
I am curious about the reason of implementing such functionality. What are the advantages of using such output parameters?
Something isn't right in your example.
class Foo {
public static void main(String[] args) {
String x = "foo";
getString(x);
System.out.println(x);
}
public static void getString(String output){
output = "Hello World"
}
}
In the above program, the string "foo" will be output, not "Hello World".
Some types are mutable, in which case you can modify an object passed into a function. For immutable types (such as String), you would have to build some sort of wrapper class that you can pass around instead:
class Holder<T> {
public Holder(T value) {
this.value = value;
}
public T value;
}
Then you can instead pass around the holder:
public static void main(String[] args) {
String x = "foo";
Holder<String> h = new Holder(x);
getString(h);
System.out.println(h.value);
}
public static void getString(Holder<String> output){
output.value = "Hello World"
}
That example is wrong, Java does not have output parameters.
One thing you could do to emulate this behaviour is:
public void doSomething(String[] output) {
output[0] = "Hello World!";
}
But IMHO this sucks on multiple levels. :)
If you want a method to return something, make it return it. If you need to return multiple objects, create a container class to put these objects into and return that.
I disagree with Jasper: "In my opinion, this is a really ugly and bad way to return more than one result".
In .NET there is a interesting construct that utilize the output parameters:
bool IDictionary.TryGet(key, out value);
I find it very usefull and elegant. And it is the most convenient way to aks if an item is in collection and return it at the same time. With it you may write:
object obj;
if (myList.TryGet(theKey, out obj))
{
... work with the obj;
}
I constantly scold my developers if I see old-style code like:
if (myList.Contains(theKey))
{
obj = myList.Get(theKey);
}
You see, it cuts the performance in half. In Java there is no way to differentiate null value of an existing item from non-existance of an item in a Map in one call. Sometimes this is necessary.
This functionality has one big disadvantage - it doesn't work. Function parameters are local to function and assigning to them doesn't have any impact outside the function.
On the other hand
void getString(StringBuilder builder) {
builder.delete(0, builder.length());
builder.append("hello world");
}
will work, but I see no advantages of doing this (except when you need to return more than one value).
Sometimes this mechanism can avoid creation of a new object.
Example:
If an appropriate object exists anyhow, it is faster to pass it to the method and get some field changed.
This is more efficient than creating a new object inside the called method, and returning and assigning its reference (producing garbage that needs to be collected sometime).
String are immutable, you cannot use Java's pseudo output parameters with immutable objects.
Also, the scope of output is limited to the getString method. If you change the output variable, the caller won't see a thing.
What you can do, however, is change the state of the parameter. Consider the following example:
void handle(Request r) {
doStuff(r.getContent());
r.changeState("foobar");
r.setHandled();
}
If you have a manager calling multiple handles with a single Request, you can change the state of the Request to allow further processing (by other handlers) on a modified content. The manager could also decide to stop processing.
Advantages:
You don't need to return a special object containing the new content and whether the processing should stop. That object would only be used once and creating the object waste memory and processing power.
You don't have to create another Request object and let the garbage collector get rid of the now obsolete old reference.
In some cases, you can't create a new object. For example, because that object was created using a factory, and you don't have access to it, or because the object had listeners and you don't know how to tell the objects that were listening to the old Request that they should instead listen to the new Request.
Actually, it is impossible to have out parameters in java but you can make a work around making the method take on a de-reference for the immutable String and primitives by either writing a generic class where the immutable is the generic with the value and setter and getter or by using an array where element 0 (1 in length) is the value provided it is instantiate first because there are situations where you need to return more than one value where having to write a class just to return them where the class is only used there is just a waste of text and not really re-usable.
Now being a C/C++ and also .Net (mono or MS), it urges me that java does not support at least a de-reference for primitives; so, I resort to the array instead.
Here is an example. Let's say you need to create a function (method) to check whether the index is valid in the array but you also want to return the remainding length after the index is validated. Let's call it in c as 'bool validate_index(int index, int arr_len, int&rem)'. A way to do this in java would be 'Boolean validate_index(int index, int arr_len, int[] rem1)'. rem1 just means the array hold 1 element.
public static Boolean validate_index(int index, int arr_len, int[] rem1)
{
if (index < 0 || arr_len <= 0) return false;
Boolean retVal = (index >= 0 && index < arr_len);
if (retVal && rem1 != null) rem1[0] = (arr_len - (index + 1));
return retVal;
}
Now if we use this we can get both the Boolean return and the remainder.
public static void main(String[] args)
{
int[] ints = int[]{1, 2, 3, 4, 5, 6};
int[] aRem = int[]{-1};
//because we can only scapegoat the de-ref we need to instantiate it first.
Boolean result = validate_index(3, ints.length, aRem);
System.out.println("Validation = " + result.toString());
System.out.println("Remainding elements equals " + aRem[0].toString());
}
puts: Validation = True
puts: Remainding elements equals 2
Array elements always either point to the object on the stack or the address of the object on the heap. So using it as a de-references is absolutely possible even for arrays by making it a double array instantiating it as myArrayPointer = new Class[1][] then passing it in because sometimes you don't know what the length of the array will until the call going through an algorithm like 'Boolean tryToGetArray(SomeObject o, T[][] ppArray)' which would be the same as in c/c++ as 'template bool tryToGetArray (SomeObject* p, T** ppArray)' or C# 'bool tryToGetArray(SomeObject o, ref T[] array)'.
It works and it works well as long as the [][] or [] is instantiate in memory first with at least one element.
in my opinion, this is useful when you have more than one result in a function.

How to keep a "things done" count in a recursive algorithm in Java?

I have a recursive algorithm which steps through a string, character by character, and parses it to create a tree-like structure. I want to be able to keep track of the character index the parser is currently at (for error messages as much as anything else) but am not keen on implementing something like a tuple to handle multiple returned types.
I tried using an Integer type, declared outside the method and passed into the recursive method, but because it's final, recursive call increments are "forgotten" when I return. (Because the increment of the Integer value makes the passed-by-value object reference point at a new object)
Is there a way to get something similar to work which won't pollute my code?
Since you've already discovered the pseudo-mutable integer "hack," how about this option:
Does it make sense for you to make a separate Parser class? If you do this, you can store the current state in a member variable. You probably need to think about how you're going to handle any thread safety issues, and it might be overkill for this particular application, but it might work for you.
It's kind of a hack, but sometimes I use an AtomicInteger, which is mutable, to do things like this. I've also seen cases where an int[] of size 1 is passed in.
The current solution I am using is:
int[] counter = {0};
and then pass it to the recursive algorithm:
public List<Thing> doIt (String aString, int[] counter) { ... }
and when I want to increment it:
counter[0]++;
Not super elegant, but it works...
Integers are immutable, which means that when you pass it as an argument it creates a copy rather than a reference to the same item. (explanation).
To get the behavior you're looking for, you can write your own class which is like Integer only mutable. Then, just pass it to the recursive function, it is incremented within the recursion, and when you access it again after the recursion is over it will still maintain its new values.
Edit: Note that using an int[] array is a variation on this method... In Java, arrays are also passed by reference rather than copied like primitives or immutable classes.
You could just use a static int class variable that gets incremented each time your doIt method is called.
You could also do:
private int recurse (int i) {
if (someConditionkeepOnGoing) {
i = recurse(i+1);
}
return i;
}
To be honest I would recode the function to make it a linear algorithm that uses a loop. This way you have no chance of running out of heap space if you are stepping through an extremely large string. Also, you would not need to have a the extra parameter just to keep track of the count.
This also would probably have the result of making the algorithm faster because it does not need to make a function call for every character.
Unless of course there is a specific reason it needs to be recursive.
One possibility I can think of is to store the count in a member variable of the class. This of course assumes that the public doIt method is only called by a single thread.
Another option is to refactor the public method to call a private helper method. The private method takes the list as a parameter and returns the count. For example:
public List<Thing> doIt(String aString) {
List<Thing> list = new ArrayList<Thing>();
int count = doItHelper(aString, list, 0);
// ...
return list;
}
private int doItHelper(String aString, List<Thing> list, int count) {
// ...
// do something that updates count
count = doItHelper(aString, list, count);
// ...
return count;
}
This assumes that you can do the error handling in the public doIt method, since the count variable isn't actually passed back to the caller. If you need to do that, you could of course throw an exception:
public List<Thing> doIt(String aString) throws SomeCustomException {
List<Thing> list = new ArrayList<Thing>();
int count = doItHelper(aString, list, 0);
// ...
if (someErrorOccurred) {
throw new SomeCustomException("Error occurred at chracter index " + count, count);
}
return list;
}
It's difficult to know whether that will help without knowing more about how your algorithm actually works.

Categories

Resources