How does this recursion work [duplicate] - java

This question already has answers here:
Reversing a String with Recursion in Java
(17 answers)
Closed 8 years ago.
This piece of code reverses string parameter passed to it. I know that string is immutable. I seem not to understand what is going on. Where does it store the reversed string that it returns.
public static String reverseRecursively(String str) {
//base case to handle one char string and empty string
if (str.length() < 2) {
return str;
}
return reverseRecursively(str.substring(1)) + str.charAt(0);
}

Your reverseRecursively(str.substring(1)) + str.charAt(0) creates a new String object every time it is called.

Where does it store the reversed string that it returns.
As the method shows, it calls itself recursively. Each time it is called it would add entries to the call stack. So, read about how the call stack works if you are concerned with the magic about where these "intermediate" results are stored.

Here is a call diagram that illustrates data flow:
Vector source of the image
Each call returns a copy of string with first character placed last and rest being processed by further calls. References to these strings are stored on stack which grows with each call (more stack space is required to handle longer strings).

Related

Error at using Assignment operator in java [duplicate]

This question already has answers here:
Replace a character at a specific index in a string?
(9 answers)
Closed 2 years ago.
I also the error "Left Hand Side of an Assignment must be a Variable" for following line
outPutArray.charAt(i)=inputArray[i]
how to resolve this? I have tried putting braces like but of no use
(outPutArray.charAt(i))=inputArray[i]
You are trying to mutate a String object. This is not possible, String is supposed to be immutable. You have to create a new String with the changed content, use a char array instead, or something else that allows you to actually achieve what you are trying to do in the end (which is: given an input String, return an output String where one character is changed).
With that out of the way, you can't do an assignment on the return value of a function. You don't get a reference back that you can change and then some variable gets changed. You get a value back. The great Is Java "pass-by-reference" or "pass-by-value"? question is maybe a good read.
Very silly, but the format should be:
inputArray[i] = outPutArray.charAt(i);
not
outPutArray.charAt(i) = inputArray[i]
putting the function on the left hand side means you are assigning a constant integer to a integer array element. As the integer is constant, it will fail. This is why we put our variables(inputArray[i] in your case) on the left hand side and our functions on the right hand(outPutArray.charAt(i)). Hope you understand!
.charAt(i) function returns the character at position i. It does not return the reference to the character at that index.
Look at this for more details

Is there a more performant way to prepend a string before another string?

Using the StringBuilder.insert method like:
builder.insert(0, str)
seems a reasonable way to prepend a String instance before another string, but after having a look a the source code of the insert method I am not sure if its an efficient way of doing so, because the insert method has to assert sufficient capacity and perform some shifting:
public AbstractStringBuilder insert(int offset, String str) {
...
ensureCapacityInternal(count + len);
shift(offset, len);
...
}
and both relies on using System.arraycopy.
I wrote a StringCombiner class which just adds two strings:
public StringCombiner prepend(String pre){
this.string = pre + this.string;
return this;
}
After running some performance tests the insert method still seems to be much faster as the creation of the new string seems to be a much bigger performance penalty.
So I wanted to know if there is another more performant way to prepend a string before another.
Thx.
Your prepend() method uses the + string operator, which internally creates a StringBuilder, appends both strings, and converts the result to a String. So, the + operator can't help you.
If it's just adding two strings, there's no way to improve that.
If it's inside a loop, you might get some improvement by reversing the loop, so you start from the part of the result string that gets placed at the very beginning of the result, and instead of continuously prepending (and thus repeatedly moving ever-growing accumulated character sequences), you'll end up appending strings and keep the majority of characters in place.
So, improvements are possible only considering the bigger context of this string operation.

How to get the string from its String.hashCode() value? [duplicate]

This question already has answers here:
how can I get the String from hashCode
(4 answers)
Closed 3 years ago.
I need to somehow get the text from its hash in java.
I have this code:
String myString = new String("creashaks organzine");
int hashCode = myString.hashCode();
System.out.println("Hash:" + hashCode);
The result of this code will be 0.
But the hash of "pollinating sandboxes" string will also be 0.
There might be collisions, for example with "creashaks organzine" and "pollinating sandboxes" and I want to find collisions like in this case.
Since i don't have enough reputation to add comment, i will quote solution from another question
You know that several objects can have same hash(), as it mentioned in java doc for Object.hashCode()
It is not required that if two objects are unequal
* according to the {#link java.lang.Object#equals(java.lang.Object)}
* method, then calling the {#code hashCode} method on each of the
* two objects must produce distinct integer results.
It's obvious you can't restore different objects from same hash code, so it's impossible at all, simple logic.
how can I get the String from hashCode
This is a very interesting thing. Regarding the specification in https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#hashCode() says that the hashCode is calculated from the string content but the example seems to shows that is not true for the first string:
class Main
{
public static void main(String[] args)
{
String myString1 = "creashaks organzine";
String myString2 = "crsomething else";
String myString3 = "crsomething else";
System.out.println("Hash1:" + myString1.hashCode());
System.out.println("Hash2:" + myString2.hashCode());
System.out.println("Hash3:" + myString3.hashCode());
}
}
Outputs:
Hash1:0
Hash2:444616526
Hash3:444616526
But when I modify the string, then I get a different output:
String myString1 = "creashaks organzine...";
System.out.println("Hash1:" + myString1.hashCode());
Outputs:
Hash1:45678
So it seems that somebody tricked us by giving a very rare example string that produced exactly the "0" as output. Here you see that the hashCode is not very unique, so you cannot use is safely to compare strings.
Coming back to your initial question: The hashCode is a number with reduced details, so you cannot calculate it back to the original string. This applies to all hash codes.
Hash codes are so often used in server side databases instead of real password strings. They can be compared but not reconstructed.

String.valueOf(someVar) vs ("" + someVar) [duplicate]

This question already has answers here:
String valueOf vs concatenation with empty string
(10 answers)
Closed 5 years ago.
I want to know the difference in two approaches. There are some old codes on which I'm working now, where they are setting primitive values to a String value by concatenating with an empty String "".
obj.setSomeString("" + primitiveVariable);
But in this link Size of empty Java String it says that If you're creating a separate empty string for each instance, then obviously that will take more memory.
So I thought of using valueOf method in String class. I checked the documentation String.valueOf() it says If the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.
So which one is the better way
obj.setSomeString("" + primitiveVariable);
obj.setSomeString(String.valueOf(primitiveVariable));
The above described process of is done within a List iteration which is having a size of more than 600, and is expected to increase in future.
When you do "" that is not going to create an Object. It is going to create a String literal. There is a differenc(How can a string be initialized using " "?) actually.
Coming to your actual question,
From String concatenation docs
The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method.
So unnecissarly you are creating StringBuilder object and then that is giving another String object.
However valueOf directly give you a String object. Just go for it.
Besides the performance, just think generally. Why you concatenating with empty string, when actually you want to convert the int to String :)
Q. So which one is the better way
A. obj.setSomeString(String.valueOf(primitiveVariable)) is usually the better way. It's neater and more domestic. This prints the value of primitiveVariable as a String, whereas the other prints it as an int value. The second way is more of a "hack," and less organized.
The other way to do it is to use Integer.toString(primitiveVariable), which is basically the same as String.valueOf.
Also look at this post and this one too

Difference between printing char and int arrays in Java [duplicate]

This question already has answers here:
If a char array is an Object in Java, why does printing it not display its hash code?
(6 answers)
Closed 5 years ago.
When I run the following code I get the address of the array:
int arr[] = {2,5,3};
System.out.println(arr); // [I#3fe993
But when I declare a character array and print it the same way it gives me the actual content of the array. Why?
char ch[] = {'a','b','c'};
System.out.println(ch); // abc
Class PrintStream (which is what System.out is) has a dedicated method overload println(char[]) which prints the characters of a char array.
It has no special overloads for other arrays, so when you pass an int[] the called method is println(Object). That method converts the passed object to a string by calling its toString() method.
The toString() method for all arrays is simply the default one inherited from class Object, which displays their class name and default hashcode, which is why it's not so informative. You can use Arrays.toString(int[]) to get a string representation of your int array's contents.
P.S. Contrary to what the doc says, the default hashcode of an object is not typically the object's address, but a randomly generated number.
When you say
System.out.println(ch);
It results in a call to print(char[] s) then println()
The JavaDoc for println says:
Prints a character and then terminate the line. This method behaves as though it invokes print(char) and then println().
A integer variable is not char, so the print(int[] s) get the address of array.

Categories

Resources