This question already has answers here:
Why does Java's concat() method not do anything?
(6 answers)
Closed 5 years ago.
i would like to know why the output of this code is "roar roar!!!" not "roar!!! roar!!!"?
the code is:
public class Lion
{
public void roar(String roar1, StringBuilder roar2) {
roar1.concat("!!!");
roar2.append("!!!");
}
public static void main(String[] args)
{
String roar1 = "roar";
StringBuilder roar2 = new StringBuilder("roar");
new Lion().roar(roar1, roar2);
System.out.println(roar1 + " " + roar2);
} }
i try to find the reason of method concat() dont appends one String to the end of another. please with explain.
Here roar1 is you string variable and roar2 is your object of class string builder, and only string builder is mutable, string can not be mutated.... Because of which only inbuilt function in class string builder concate will work on its object roar2.
Roar1 is not object of string builder thus concate function will not work on it.
As said before, Objects of the class String are always immutable.
Additionally you have to remember how variables in JAVA are passed to some Methods.
In your case you build a String and a StringBuilder an pass them to your roar() method. The JVM will create two new Variables which are referencing the two orignal Objects. Due to the immutablity of your local String Variable, a new Object will be created, if you want to change this Object. The append() method of an String Object, normally creates and returns a new Instance of a String, with the changes you've made. You doesn't have a reference on this Object. Even if your local String references this object, the String Variable outside of the roar() method still references the old String ("roar").
That's the reason why your System.out.println, doesn't show the changes you made.
Related
When creating a String like this:
String s1 = “ABC”
the JVM will look in the String pool if "ABC" exists there and create a new object only if "ABC" doesn't exist yet.
So the usage of
String s1 = new String("ABC")
halts this behavior and will create an object every time.
Now I have a problem when converting a char array to String:
private char[] names;
...
#Override
public String toString() {
return new String(this.names);
}
This will always create a new object. Can I convert from char array to String without creating a new object each time?
I know of no way to avoid creating a String object in your toString(), but you can avoid retaining these new strings (all but the first one become eligible for GC after the method execution) by explicitly calling String.intern():
#Override
public String toString() {
return new String(this.names).intern();
}
And you can test it by repeatedly checking myObject.toString() == myObject.toString().
But before doing this, do yourself a favor and be aware of what you're doing. It's possible that generating a string object is the better choice, depending on your main reason for doing this.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 6 years ago.
Since java is pass by value.In below code we are passing a value to appendStringMethod not a reference, then why in main method we get HelloWorld not just Hello after calling appendStringMethod() in main.
public class test {
public static void main(String args[]) {
StringBuilder str = new StringBuilder("Hello");
appendStringMethod(str);
System.out.println(str);
}
static void appendStringMethod(StringBuilder s) {
s.append("World");
}
}
However in below code, values are not swapped.
public class Mock {
public static void main(String args[]) {
StringBuilder str1 = new StringBuilder("Hello");
StringBuilder str2 = new StringBuilder("World");
swap(str1, str2);
System.out.println(str1);
System.out.println(str2);
}
static void swap(StringBuilder s1, StringBuilder s2) {
StringBuilder s= s1;
s1=s2;
s2=s1;
}
}
It's because the reference to the StringBuilder is passed by value. You can add characters and they will be in the instance after the method returns. This in the end acts like a pass by reference. It works similarly with the Collection classes (List, Map,...), as well as your own classes.
In the case of primitive types (int,...), Java behaviour is simple: The value is copied in another instance of the primitive type.
In case of Objects, this is the same: Object variables are pointers that holds the Object’s address so the references are copied. The only exception I can think of are String Objects as the characters are stored in an array declared final so that it cannot be modified.
While Java is technically pass by value for everything, as spoken about here, It's best not to think of it like that.
When passing an instance of a class into a method, you're really passing the reference of the object by value.
StringBuilder str = new StringBuilder("Hello");
appendStringMethod(str);
In this code, you are passing a reference to the StringBuilder instance into the appendStringMethod by value.
As a result, str will become "HelloWorld" once the method has been called.
Note: This doesn't apply to primitives such as int and char. Since they are not actual objects, they won't have a reference. This means they will be passed by value in the "expected" way.
In java we pass by value of reference. Have a look at a following example:
public void foo(Integer i) {
i = new Integer(1000);
}
public void bar(Integer i) {
i++;
}
Integer n = new Integer(2000);
foo(n);
bar(n);
System.out.println(n.toString());
I believe that much of the confusion on this issue has to do with the
fact that different people have different definitions of the term
"reference". People coming from a C++ background assume that
"reference" must mean what it meant in C++, people from a C background
assume "reference" must be the same as "pointer" in their language,
and so on. Whether it's correct to say that Java passes by reference
really depends on what's meant by "reference".
--first comment
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
I do not understand why System.out.println(name) outputs Sam without being affected by the method's concat function, while System.out.println(names) outputs Sam4 as a result of the method's append method. Why is StringBuilder affected and not String? Normally, calling methods on a reference to an object affects the caller, so I do not understand why the String result remains unchanged. Thanks in advance
public static String speak(String name) {
name = name.concat("4");
return name;
}
public static StringBuilder test(StringBuilder names) {
names = names.append("4");
return names;
}
public static void main(String[] args) {
String name = "Sam";
speak(name);
System.out.println(name); //Sam
StringBuilder names = new StringBuilder("Sam");
test(names);
System.out.println(names); //Sam4
}
Because when you call speak(name);, inside speak when you do
name = name.concat("4");
it creates a new object because Strings are immutable. When you change the original string it creates a new object,I agree that you are returning it but you are not catching it.
So essentially what you are doing is :
name(new) = name(original) + '4'; // but you should notice that both the names are different objects.
try
String name = "Sam";
name = speak(name);
Of course now I think there is no need to explain why it's working with StringBuilder unless if you don't know that StringBuilder is mutable.
Looking at the Javadoc for String, one will read that
[...] String objects are immutable [...].
This means concat(String) does not change the String itself, but constructs a new String.
StringBuilders, on the other hand, are mutable. By calling append(CharSequence), the object itself is mutated.
Because String is immutable and hence String#concat does not modify the original String instance, it only returns a new String while the original is left unmodified, while StringBuilder is mutable and the change is reflected in the StringBuilder instance passed as parameter.
Okay, what is speak method doing?
First of all,
name.concat("4");
creates new object, which is equal to name, concatenated with "4".
So, the line
name = name.concat(4);
redefines local (for speak method) variable name.
Then you return the reference to this new value with
return name;
So, the original variable, passed within method is not modified, but the method returns modified value.
In the test method you actually modify variable without modifying the reference (the StringBuilder class is mutable, so variable if this type can be modified).
Then we can see another question arising: why StringBuilder.append returns value, where it can seem redundant. The answer to this question lies in the description of "builder" pattern, for which it is the usual way of implementing modification methods. See wikipedia on Builder pattern.
String is immutable in java. As soon as you invoke concat method on name. A new string is created and while you are playing with the old reference in System.out.println(name).If you want to use the modified string you should explicitly return the reference.
While StringBuilder is mutable and it returns the same reference always.
When you invoke speak(name) it computes the new value, but discards it.
If you replace it with
name = speak(name);
the result will be the one you expect.
With the StringBuilder, the object you pass is mutable: so
names.append(names);
changes the state of the current object (it also returns a reference to the same object, which is just a convenience to allow you to write code like names.append(...).append(...) etc.). So in the case of the StringBuilder, the object you are referencing when you call the method has actually changed, hence you see the changes.
In your method speak, the concat method returns a new String, the original object it was called on is unchanged (strings are immutable). As documented:
If the length of the argument string is 0, then this String object is returned. Otherwise, a String object is returned that represents a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.
Calling name.concat("4") is the equivalent of name + "4".
In your test method the append method modifies the content of the StringBuilder. As documented:
The principal operations on a StringBuilder are the append and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string builder. The append method always adds these characters at the end of the builder; the insert method adds the characters at a specified point.
In your main method both name and names are still the same object as before the method call, but the content of name is unchanged as strings are immutable, while the content of names has been changed.
If instead you had used the return values of both methods, then you would have the result you were expecting.
First of all, String is an immutable class in Java. An immutable class is simply a class whose instances cannot be modified. All information in an instance is initialized when the instance is created and the information can not be modified.
Second, in java parameters are sent by values and not by reference.
In your method 'test' you don't need names = names.append("4"), instead names.append("4") will be enough .
If you check java docs for String object, you will see that most of the methods there, including concat, will generate a new String.
So to have on output Sam4 also for the String, you will need in main method to have this name = speak(name).
String
String is immutable ( once created can not be changed )object . The
object created as a String is stored in the Constant String Pool .
Every immutable object in Java is thread safe ,that implies String is
also thread safe . String can not be used by two threads
simultaneously. String once assigned can not be changed.
String demo = " hello " ; // The above object is stored in constant
string pool and its value can not be modified.
demo="Bye" ; //new "Bye" string is created in constant pool and
referenced by the demo variable // "hello" string still
exists in string constant pool and its value is not overrided but we
lost reference to the "hello"string
StringBuilder
StringBuilder is same as the StringBuffer , that is it stores the
object in heap and it can also be modified . The main difference
between the StringBuffer and StringBuilder is that StringBuilder is
also not thread safe. StringBuilder is fast as it is not thread safe
.
For more details check this
Conclusion:
You don't need to re-assign the value again to StringBuilder as it is already a reference
test method should be
public static void test(StringBuilder names) {
names.append("4");
}
but speak should be
String name = "Sam";
name = speak(name);
This question already has answers here:
String, StringBuffer, and StringBuilder
(12 answers)
Closed 7 years ago.
Yes i have read all material on internet regarding their difference.and that difference is totally based on concatenation performance of both.My question is that in the below code which technique is better.
public class StringBuilderDemo {
public static void main(String[] args) {
StringBuilder str = new StringBuilder("test");
System.out.println(str.toString());
str = new StringBuilder("Hi ");
System.out.println(str.toString());
}
}
here is string demo
public class StringDemo {
static String str="";
public static void main(String[] args) {
str = "test";
System.out.println(str);
str ="Hi";
System.out.println(str);
}
}
My assumptions are since strings are immutable so when we assign "Hi" to str "test " also remain in memory(two objects of string created "Hi" and "test" ).where as in case of string builder when we give value "Hi" "test" is removed.so we have one object in case of string builder. So i concluded that we should use string builder in these cases. Correct me if i am being childish here .
You are right, String is immutable. Means you cannot add things to its memory content directly, meaning you'll need additional memory to access it. However, your application here doesn't seems to be memory intensive, hence you can just use String directly.
In your case an ordinary String is better. You should use StringBuilder in large for loops where you are adding a lot of stuff to a string.
The thing is that a String is imutable and when you assign a variable to a string, java looks in what you can imagine a table of already created ones. If there is one with the same content, you get a reference to that String. However, whenever you are chaining the content of the String, a new object is created and hence a slower performance in large loops.
With the StringBuilder that is not the case, it is mutable, which means that you can modify it's objects and there will be no new objects created, instead it will just resize itself when it needs to.
Yep, when you join more string or you create a string there is a String Builder hided behind it.
For simple string there is no difference in performance but you should use the String Builder if u need join (or add) more strings togheter.
This is very basic thing. you should use 'String' not 'StringBuilder' in your case.
This question already has answers here:
Immutability of Strings in Java
(26 answers)
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
In java String is a class and it is imutable so we can not change its value.In following code it will concate other string without any error.So I want to ask that if it is immutable then why in this following code value of String is changed??
import java.util.*;
public class conc
{
public static void main(String args[])
{
String a="Sheetal";
a=a+"Ga";
System.out.println("Result:"+a);
}
}
In the code that you have shown, you have not changed the original String object.
Instead, you have created a new String object, which represents a + "Ga", and then re-assigned it to the reference variable a.
Note that all variables in Java other than primitive types are references.
You are creating a new object by concatenating two strings, that is: You are not changing the object referenced by a but assigning to that reference the value referencing to a new String object.
String a="Sheetal";
a=a+"Ga"; // now this is not the same object you are referring early
When you alter your a will create a new String.
Your original String is not change that's why we call String are immutable and new String will create in the heap.
In this moment there are 2 object in your heap. now a is referring new Object.