Related
I there any utils method in Java that would enable me to surround a string with another string? Something like:
surround("hello","%");
which would return "%hello%"
I need just one method so the code would be nicer then adding prefix and suffix. Also I don't want to have a custom utils class if it's not necessary.
String.format can be used for this purpose:
String s = String.format("%%%s%%", "hello");
No but you can always create a method to do this:
public String surround(String str, String surroundingStr) {
StringBuffer buffer = new StringBuffer();
buffer.append(surroundingStr).append(str).append(surroundingStr);
return buffer.toString();
}
You have another method of doing it but Do not do this if you want better performance:-
public String surround(String str, String surroundingStr){
return surroundingStr + str + surroundingStr;
}
Why not use the second method?
As we all know, Strings in Java are immutable. When you concatinate strings thrice, it creates two new string objects apart from your original strings str and surroundingStr. And so a total of 4 string objects are created:
1. str
2. surroundingStr
3. surroundingStr + str
4. (surroundingStr + str) + surroundingStr
And creating of objects do take time. So for long run, the second method will downgrade your performance in terms of space and time. So it's your choice what method is to be used.
Though this is not the case after java 1.4
as concatinating strings with + operator uses StringBuffer in the background. So using the second method is not a problem if your Java version is 1.4 or above. But still, if you wanna concatinate strings is a loop, be careful.
My suggestion:
Either use StringBuffer of StringBuilder.
Not that i know of, but as already commented, its a single line piece of code that you could write yourself.
private String SurroundWord(String word, String surround){
return surround + word + surround;
}
Do note that this will return a New String object and not edit the original string.
Create a new method:
public String surround(String s, String surr){
return surr+s+surr;
}
Tested the following and returns %hello%
public static void main (String[] args) throws java.lang.Exception
{
System.out.println(surround("hello", "%"));
}
public static String surround(String s, String sign) {
return sign + s + sign;
}
StringUtils.wrap(str,wrapWith) is what you are looking for.
If apache common utils is already a part of dependency, then you can use it. Otherwise as others already mentioned. It's better to add to your base. Not a big deal
https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/StringUtils.java
As per my knowledge,
a mutable string can be changed, and
an immutable string cannot be changed.
Here I want to change the value of String like this,
String str="Good";
str=str+" Morning";
and other way is,
StringBuffer str= new StringBuffer("Good");
str.append(" Morning");
In both the cases I am trying to alter the value of str. Can anyone tell me, what is difference in both case and give me clear picture of mutable and immutable objects.
Case 1:
String str = "Good";
str = str + " Morning";
In the above code you create 3 String Objects.
"Good" it goes into the String Pool.
" Morning" it goes into the String Pool as well.
"Good Morning" created by concatenating "Good" and " Morning". This guy goes on the Heap.
Note: Strings are always immutable. There is no, such thing as a mutable String. str is just a reference which eventually points to "Good Morning". You are actually, not working on 1 object. you have 3 distinct String Objects.
Case 2:
StringBuffer str = new StringBuffer("Good");
str.append(" Morning");
StringBuffer contains an array of characters. It is not same as a String.
The above code adds characters to the existing array. Effectively, StringBuffer is mutable, its String representation isn't.
What is difference between mutable and immutable String in java
immutable exist, mutable don't.
In Java, all strings are immutable. When you are trying to modify a String, what you are really doing is creating a new one. However, when you use a StringBuilder, you are actually modifying the contents, instead of creating a new one.
Java Strings are immutable.
In your first example, you are changing the reference to the String, thus assigning it the value of two other Strings combined: str + " Morning".
On the contrary, a StringBuilder or StringBuffer can be modified through its methods.
Mutable :- Changeable
Immutable :- Unchangeable
String in Java is immutable. However what does it mean to be mutable in programming context is the first question. Consider following class,
public class Dimension {
private int height;
private int width;
public Dimenstion() {
}
public void setSize(int height, int width) {
this.height = height;
this.width = width;
}
public getHeight() {
return height;
}
public getWidth() {
return width;
}
}
Now after creating the instance of Dimension we can always update it's attributes. Note that if any of the attribute, in other sense state, can be updated for instance of the class then it is said to be mutable. We can always do following,
Dimension d = new Dimension();
d.setSize(10, 20);// Dimension changed
d.setSize(10, 200);// Dimension changed
d.setSize(100, 200);// Dimension changed
Let's see in different ways we can create a String in Java.
String str1 = "Hey!";
String str2 = "Jack";
String str3 = new String("Hey Jack!");
String str4 = new String(new char[] {'H', 'e', 'y', '!'});
String str5 = str1 + str2;
str1 = "Hi !";
// ...
So,
str1 and str2 are String literals which gets created in String constant pool
str3, str4 and str5 are String Objects which are placed in Heap memory
str1 = "Hi!"; creates "Hi!" in String constant pool and it's totally different reference than "Hey!" which str1 referencing earlier.
Here we are creating the String literal or String Object. Both are different, I would suggest you to read following post to understand more about it.
Difference between string object and string literal
In any String declaration, one thing is common, that it does not modify but it gets created or shifted to other.
String str = "Good"; // Create the String literal in String pool
str = str + " Morning"; // Create String with concatenation of str + "Morning"
|_____________________|
|- Step 1 : Concatenate "Good" and " Morning" with StringBuilder
|- Step 2 : assign reference of created "Good Morning" String Object to str
How String became immutable ?
It's non changing behaviour, means, the value once assigned can not be updated in any other way. String class internally holds data in character array. Moreover, class is created to be immutable. Take a look at this strategy for defining immutable class.
Shifting the reference does not mean you changed it's value. It would be mutable if you can update the character array which is behind the scene in String class. But in reality that array will be initialized once and throughout the program it remains the same.
Why StringBuffer is mutable ?
As you already guessed, StringBuffer class is mutable itself as you can update it's state directly. Similar to String it also holds value in character array and you can manipulate that array by different methods i.e. append, delete, insert etc. which directly changes the character value array.
When you say str, you should be careful what you mean:
do you mean the variable str?
or do you mean the object referenced by str?
In your StringBuffer example you are not altering the value of str, and in your String example you are not altering the state of the String object.
The most poignant way to experience the difference would be something like this:
static void change(String in) {
in = in + " changed";
}
static void change(StringBuffer in) {
in.append(" changed");
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("value");
String str = "value";
change(sb);
change(str);
System.out.println("StringBuffer: "+sb);
System.out.println("String: "+str);
}
In Java, all strings are immutable(Can't change). When you are trying to modify a String, what you are really doing is creating a new one.
Following ways we can create the string object
Using String literal
String str="java";
Using new keyword
String str = new String("java");
Using character array
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
String helloString = new String(helloArray);
coming to String immutability, simply means unmodifiable or unchangeable
Let's take one example
I'm initializing the value to the String literal s
String s="kumar";
Below I'm going to display the decimal representation of the location address using hashcode()
System.out.println(s.hashCode());
Simply printing the value of a String s
System.out.println("value "+s);
Okay, this time I'm inittializing value "kumar" to s1
String s1="kumar"; // what you think is this line, takes new location in the memory ???
Okay let's check by displaying hashcode of the s1 object which we created
System.out.println(s1.hashCode());
okay, let's check below code
String s2=new String("Kumar");
System.out.println(s2.hashCode()); // why this gives the different address ??
Okay, check this below code at last
String s3=new String("KUMAR");
System.out.println(s3.hashCode()); // again different address ???
YES, if you see Strings 's' and 's1' having the same hashcode because the value hold by 's' & 's1' are same that is 'kumar'
Let's consider String 's2' and 's3' these two Strings hashcode appears to be different in the sense, they both stored in a different location because you see their values are different.
since s and s1 hashcode is same because those values are same and storing in the same location.
Example 1:
Try below code and analyze line by line
public class StringImmutable {
public static void main(String[] args) {
String s="java";
System.out.println(s.hashCode());
String s1="javA";
System.out.println(s1.hashCode());
String s2=new String("Java");
System.out.println(s2.hashCode());
String s3=new String("JAVA");
System.out.println(s3.hashCode());
}
}
Example 2: Try below code and analyze line by line
public class StringImmutable {
public static void main(String[] args) {
String s="java";
s.concat(" programming"); // s can not be changed "immutablity"
System.out.println("value of s "+s);
System.out.println(" hashcode of s "+s.hashCode());
String s1="java";
String s2=s.concat(" programming"); // s1 can not be changed "immutablity" rather creates object s2
System.out.println("value of s1 "+s1);
System.out.println(" hashcode of s1 "+s1.hashCode());
System.out.println("value of s2 "+s2);
System.out.println(" hashcode of s2 "+s2.hashCode());
}
}
Okay, Let's look what is the difference between mutable and immutable.
mutable(it change) vs. immutable (it can't change)
public class StringMutableANDimmutable {
public static void main(String[] args) {
// it demonstrates immutable concept
String s="java";
s.concat(" programming"); // s can not be changed (immutablity)
System.out.println("value of s == "+s);
System.out.println(" hashcode of s == "+s.hashCode()+"\n\n");
// it demonstrates mutable concept
StringBuffer s1= new StringBuffer("java");
s1.append(" programming"); // s can be changed (mutablity)
System.out.println("value of s1 == "+s1);
System.out.println(" hashcode of s1 == "+s1.hashCode());
}
}
Any further questions?? please write on...
I modified the code of william with a output comments for better understandable
static void changeStr(String in) {
in = in+" changed";
System.out.println("fun:"+in); //value changed
}
static void changeStrBuf(StringBuffer in) {
in.append(" changed"); //value changed
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("value");
String str = "value";
changeStrBuf(sb);
changeStr(str);
System.out.println("StringBuffer: "+sb); //value changed
System.out.println("String: "+str); // value
}
In above code , look at the value of str in both main() and changeStr() , even though u r changing the value of str in changeStr() it is affecting only to that function but in the main function the value is not changed , but it not in the case of StringBuffer..
In StringBuffer changed value is affected as a global..
hence String is immutable and StringBuffer is mutable...
In Simple , whatever u changed to String Object will affecting only to that function By going to String Pool. but not Changed...
A mutable variable is one whose value may change in place, whereas in an immutable variable change of value will not happen in place. Modifying an immutable variable will rebuild the same variable.
Mutable means you will save the same reference to variable and change its contents but immutable you can not change contents but you will declare new reference contains the new and the old value of the variable
Ex
Immutable -> String
String x = "value0ne";// adresse one
x += "valueTwo"; //an other adresse {adresse two}
adresse on the heap memory change.
Mutable -> StringBuffer - StringBuilder
StringBuilder sb = new StringBuilder();
sb.append("valueOne"); // adresse One
sb.append("valueTwo"); // adresse One
sb still in the same adresse i hope this comment helps
How do String objects work in Java? How does term "immutable" exactly apply to string objects? Why don't we see modified string after passing through some method, though we operate on original string object value?
a String has a private final char[] . when a new String object is created, the array is also created and filled. it cannot be later accessed [from outside] or modified [actually it can be done with reflection, but we'll leave this aside].
it is "immutable" because once a string is created, its value cannot be changed, a "cow" string will always have the value "cow".
We don't see modified string because it is immutable, the same object will never be changed, no matter what you do with it [besides modifying it with reflection]. so "cow" + " horse" will create a new String object, and NOT modify the last object.
if you define:
void foo(String arg) {
arg= arg + " horse";
}
and you call:
String str = "cow";
foo(str);
the str where the call is is not modified [since it is the original reference to the same object!] when you changed arg, you simply changed it to reference another String object, and did NOT change the actual original object. so str, will be the same object, which was not changed, still containing "cow"
if you still want to change a String object, you can do it with reflection. However, it is unadvised and can have some serious side-affects:
String str = "cow";
try {
Field value = str.getClass().getDeclaredField("value");
Field count = str.getClass().getDeclaredField("count");
Field hash = str.getClass().getDeclaredField("hash");
Field offset = str.getClass().getDeclaredField("offset");
value.setAccessible(true);
count.setAccessible(true);
hash.setAccessible(true);
offset.setAccessible(true);
char[] newVal = { 'c','o','w',' ','h','o','r','s','e' };
value.set(str,newVal);
count.set(str,newVal.length);
hash.set(str,0);
offset.set(str,0);
} catch (NoSuchFieldException e) {
} catch (IllegalAccessException e) {}
System.out.println(str);
}
From the tutorial:
The String class is immutable, so that once it is created a String object cannot be changed. The String class has a number of methods, some of which will be discussed below, that appear to modify strings. Since strings are immutable, what these methods really do is create and return a new string that contains the result of the operation.
Strings in Java are immutable (state cannot be modified once created). This offers opportunities for optimization. One example is string interning, where string literals are maintained in a string pool and new String objects are only created if the particular string literal doesn't already exist in the pool. If the string literal already exists, a reference is returned. This can only be accomplished because strings are immutable, so you don't have to worry that some object holding a reference will change it.
Methods that appear to modify a string actually return a new instance. One example is string concatenation:
String s = "";
for( int i = 0; i < 5; i++ ){
s = s + "hi";
}
What actually happens internally (the compiler changes it):
String s = "";
for( int i = 0; i < 5; i++ ){
StringBuffer sb = new StringBuffer();
sb.append(s);
sb.append("hi");
s = sb.toString();
}
You can clearly see that new instances are created by the toString method (note that this can be made more efficient by directly using StringBuffers). StringBuffers are mutable, unlike Strings.
Every object has state. The state of a String object is the array of characters that make up the String, for example, the String "foo" contains the array ['f', 'o', 'o']. Because a String is immutable, this array can never be changed in any way, shape, or form.
Every method in every class that wants to change a String must instead return a new String that represents the altered state of the old String. That is, if you try to reverse "foo" you will get a new String object with internal state ['o', 'o', 'f'].
I think this link will help you to understand how Java String really works
Now consider the following code -
String s = "ABC";
s.toLowerCase();
The method toLowerCase() will not change the data "ABC" that s contains. Instead, a new String object is instantiated and given the data "abc" during its construction. A reference to this String object is returned by the toLowerCase() method. To make the String s contain the data "abc", a different approach is needed.
Again consider the following - s = s.toLowerCase();
Now the String s references a new String object that contains "abc". There is nothing in the syntax of the declaration of the class String that enforces it as immutable; rather, none of the String class's methods ever affect the data that a String object contains, thus making it immutable.
I don't really understood your third question. May be providing a chunk of code and telling your problem is a better option. Hope this helps.
You can also look into this blogpost for more understanding
[code samples are taken from the wiki. you can also look in there for more information]
I am using the OpenJDK Java compiler under Ubuntu. I wanted to convert a character array to a string and when that seemed to have ended up giving ambiguous results, I tried to write a toString method of my own. In the process, I wrote a test program wherein (out of the fun of it) I tried to compile the following code.
class toString{
public static void main(String[] args){
string = "abc";
string = string + "bcd";
System.out.println(string);
}
}
Now, I know that String objects in Java are immutable and the code should have in fact generated an error but to my surprise, it printed abcbcd to the console. Does this mean that String objects in Java are mutable or is there something wrong with the implementation of OpenJDK compiler in this case?
The code that you've posted above does not actually mutate any strings, though it looks like it does. The reason is that this line doesn't mutate the string:
string = string + "bcd";
Instead, what this does is:
Construct a new string whose value is string + "bcd".
Change what string is referenced by string to refer to this new string.
In other words, the actual concrete string objects themselves weren't changed, but the references to those strings were indeed modified. Immutability in Java usually means that objects cannot be modified, not the references to those objects.
An important detail that confuses a lot of new Java programmers is that the above line is often written as
string += "bcd";
which looks even more strongly as though it's concatenating bcd onto the end of the string and thereby mutating it, even though it's equivalent to the above code and therefore doesn't cause any changes to the actual String object (again, it works by creating a new String object and changing what object the reference refers to.)
To see that what's going on here is that you're actually changing the reference and not the string it refers to, you can try rewriting the code to make string final, which prevents you from changing what object is referenced. If you do so, you'll find that the code no longer compiles. For example:
class toString{
public static void main(String[] args){
final String string = "abc";
string = string + "bcd"; // Error: can't change string!
System.out.println(string);
}
}
One final note - another common cause of grief for new Java programmers when using Strings is that String has methods that appear to mutate the string but in actuality do not. For example, this code does not work correctly:
String s = "HELLO, WORLD!";
s.toLowerCase(); // Legal but incorrect
System.out.println(s); // Prints HELLO, WORLD!
Here, the call to s.toLowerCase() does not actually convert the characters of the string to lower case, but instead produces a new string with the characters set to lower case. If you then rewrite the code as
String s = "HELLO, WORLD!";
s = s.toLowerCase(); // Legal and correct
System.out.println(s); // Prints hello, world!
Then the code will behave properly. Again, the key detail here is that the assignment to s does not change any concrete String object, but just adjusts what object s refers to.
Hope this helps!
Nope, no error - you're not changing the contents of any string object.
You're changing the value of a string variable which is entirely different. Look at this as two operations:
Creating a new string, the result of the expression string + "bcd"
Assigning the reference to the new string back to the string variable
Let's separate them out explicitly:
String string = "abc";
String other = string + "bcd";
// abc - neither the value of string nor the object's contents have changed
System.out.println(string);
// This is *just* changing the value of the string variable. It's not making
// any changes to the data within any objects.
string = other;
It's very important to distinguish between variables and objects. The value of a variable is only ever a reference or a primitive type value. Changing the value of a variable does not change the contents of the object to which it previously referred.
The difference is between References to an object and the object itself.
String XXX = "xxx";
Means:
Make a new variable and assign the reference to an instance of object String that contains the literal string "xxx".
XXX = XXX + "yyy";
Means:
Get the reference to the object we have in variable named XXX.
Make a new object of type String that contains the string literal "yyy".
Add them together executing the string + operator.
This operation will create a new String object that contains the literal string "xxxyyy".
After all this, we put the reference to the new object again in the variable XXX.
The old referenced object containing "xxx" is not used anymore but the content of it was never modified.
As a counter proof, there is an example:
String a = "abc";
String b = "def";
String c = a;
a = a + b;
System.out.println(a); // will print "abcdef".
System.out.println(b); // will print "def".
System.out.println(c); // will print "abc".
// Now we compare references, in java == operator compare references, not the content of objects.
System.out.println(a == a); // Will print true
System.out.println(a == c); // Will print false, objects are not the same!
a = c;
System.out.println(a == c); // Will print true, now a and b points on the same instance.
Object instance are something "abstract" that live in a portion of memory of your program. A reference variable is a reference to that portion of memory.
You can access objects only through variables (or return values).
A single object can have more than one variable pointing at it.
String is immutable means that you cannot modify the content of that area of memory used by the String object, but of course, you are free to change and exchange references to it as you prefer.
It doesn't refute it. It actually won't compile since string isn't declared as a String object. But, let's say you meant:
class toString{
public static void main(String[] args){
String string = "abc";
string = string + "bcd";
System.out.println(string);
}
}
See the + operator creates a new String leaving "abc" in tact. The original "abc" still exists, but all you've actually done is create a new string "abcbcd" and overwrite the original reference to "abc" when doing: string = string + "bcd". If you changed that code to this you'll see what I mean:
class toString {
public static void main(String[] args ) {
String originalString = "abc";
String newString = originalString + "bcd";
System.out.println( originalString ); // prints the original "abc";
System.out.println( newString ); // prints the new string "abcbcd";
}
}
String objects are immutable, you are simply re-assigning the value of string to string + "bcd" in your code example. You are not modifying the existing String object, you are creating a new one and assigning it to the old name.
string = string + "bcd" sets a new instance of String to the variable string, rather than modify that object
what this will do is that it will make a new object, and replace the old one.
if you want mutable string look at string builder.
The String variable string itself is mutable.
The String object "abc" is immutable, as is the String object "bcd", and the result of the concatenation, "abcbcd". That last result is assigned to the variable.
No String was mutated in the execution of that code snipped.
The string is immutable... all your example does is show that you can assign a new string reference to a variable.
If we make the code compile, and change it slightly:
class toString{
public static void main(String[] args){
String string = "abc";
System.out.println(string);
string = string + "bcd";
System.out.println(string);
}
}
You will see "abc" and then "abcbcd" which, could lead you to think that the string has changed, but it has not.
When you do the string = /* whatever */ you are overwriting what used to be in the variable called string with a new value.
If String had a method, such as setCharAt(int index, char value) then it would be mutable.
I'm trying to replace a character at a specific index in a string.
What I'm doing is:
String myName = "domanokz";
myName.charAt(4) = 'x';
This gives an error. Is there any method to do this?
String are immutable in Java. You can't change them.
You need to create a new string with the character replaced.
String myName = "domanokz";
String newName = myName.substring(0,4)+'x'+myName.substring(5);
Or you can use a StringBuilder:
StringBuilder myName = new StringBuilder("domanokz");
myName.setCharAt(4, 'x');
System.out.println(myName);
Turn the String into a char[], replace the letter by index, then convert the array back into a String.
String myName = "domanokz";
char[] myNameChars = myName.toCharArray();
myNameChars[4] = 'x';
myName = String.valueOf(myNameChars);
String is an immutable class in java. Any method which seems to modify it always returns a new string object with modification.
If you want to manipulate a string, consider StringBuilder or StringBuffer in case you require thread safety.
I agree with Petar Ivanov but it is best if we implement in following way:
public String replace(String str, int index, char replace){
if(str==null){
return str;
}else if(index<0 || index>=str.length()){
return str;
}
char[] chars = str.toCharArray();
chars[index] = replace;
return String.valueOf(chars);
}
As previously answered here, String instances are immutable. StringBuffer and StringBuilder are mutable and suitable for such a purpose whether you need to be thread safe or not.
There is however a way to modify a String but I would never recommend it because it is unsafe, unreliable and it can can be considered as cheating : you can use reflection to modify the inner char array the String object contains. Reflection allows you to access fields and methods that are normally hidden in the current scope (private methods or fields from another class...).
public static void main(String[] args) {
String text = "This is a test";
try {
//String.value is the array of char (char[])
//that contains the text of the String
Field valueField = String.class.getDeclaredField("value");
//String.value is a private variable so it must be set as accessible
//to read and/or to modify its value
valueField.setAccessible(true);
//now we get the array the String instance is actually using
char[] value = (char[])valueField.get(text);
//The 13rd character is the "s" of the word "Test"
value[12]='x';
//We display the string which should be "This is a text"
System.out.println(text);
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
You can overwrite a string, as follows:
String myName = "halftime";
myName = myName.substring(0,4)+'x'+myName.substring(5);
Note that the string myName occurs on both lines, and on both sides of the second line.
Therefore, even though strings may technically be immutable, in practice, you can treat them as editable by overwriting them.
First thing I should have noticed is that charAt is a method and assigning value to it using equal sign won't do anything. If a string is immutable, charAt method, to make change to the string object must receive an argument containing the new character. Unfortunately, string is immutable. To modify the string, I needed to use StringBuilder as suggested by Mr. Petar Ivanov.
You can overwrite on same string like this
String myName = "domanokz";
myName = myName.substring(0, index) + replacement + myName.substring(index+1);
where index = the index of char to replacement.
index+1 to add rest of your string
this will work
String myName="domanokz";
String p=myName.replace(myName.charAt(4),'x');
System.out.println(p);
Output : domaxokz