I have two strings and I am trying to copy one into another. How I can copy character by character a string into another in Java?.
Strings are immutable objects in Java, which means that after they are instantiated, they will not change internal state. Instead, if you want to modify a String, you will always get a new String.
Now, to your question. If you want to copy a String chararcter by character this is highly inefficient, since you would create a new String object each time you copy a character. Luckily, there are plenty of other options.
String a = "a";
String b = "b";
String c = a + b; // "ab"
String d = a.concat(b); // "ab"
If you simply want to copy a String, you can do the following:
String e = a; "a"
Why does that work? As stated earlier, Strings a immutable, thus a new String with the same content is created. You can think of it as String e = new String(a), which is slightly less performant (and therefore an antipattern), but also works.
Related
In the past, I've always used printf to format printing to the console but the assignment I currently have (creating an invoice report) wants us to use StringBuilder, but I have no idea how to do so without simply using " " for every gap needed. For example... I'm supposed to print this out
Invoice Customer Salesperson Subtotal Fees Taxes Discount Total
INV001 Company Eccleston, Chris $ 2357.60 $ 40.00 $ 190.19 $ -282.91 $ 2304.88
But I don't know how to get everything to line up using the StringBuilder. Any advice?
StringBuilder aims to reduce the overhead associated with creating strings.
As you may or may not know, strings are immutable. What this means that something like
String a = "foo";
String b = "bar";
String c = a + b;
String d = c + c;
creates a new string for each line. If all we are concerned about is the final string d, the line with string c is wasting space because it creates a new String object when we don't need it.
String builder simply delays actually building the String object until you call .toString(). At that point, it converts an internal char[] to an actual string.
Let's take another example.
String foo() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++)
sb.append(i);
return sb.toString();
}
Here, we only create one string. StringBuilder will keep track of the chars you have added to your string in its internal char[] value. Note that value.length will generally be larger than the total chars you have added to your StringBuilder, but value might run out of room for what you're appending if the string you are building gets too big. When that happens, it'll resize, which just means replacing value with a larger char[], and copying over the old values to the new array, along with the chars of whatever you appended.
Finally, when you call sb.toString(), the StringBuilder will call a String constructor that takes an argument of a char[].
That means only one String object was created, and we only needed enough memory for our char[] and to resize it.
Compare with the following:
String foo() {
String toReturn = "";
for (int i = 0; i < 100; i++)
toReturn += "" + i;
toReturn;
}
Here, we have 101 string objects created (maybe more, I'm unsure). We only needed one though! This means that at every call, we're disposing the original string toReturn represented, and creating another string.
With a large string, especially, this is very expensive, because at every call you need to first acquire as much memory as the new string needs, and dispose of as much memory as the old string had. It's not a big deal when things are kept short, but when you're working with entire files this can easily become a problem.
In a nutshell: if you're working appending / removing information before finalizing an output: use a StringBuilder. If your strings are very short, I think it is OK to just concatenate normally for convenience, but this is up to you to define what "short" is.
I have been given the following condition?
String A="a";
String B="b";
String c="a"+"b";
My question is is the String c created newly or is assigned from the string pool the value "a" and "b" and total how many strings are formed according to above question?
Yes c is created newly. Strings in Java are effectively immutable (i.e. once created, they never change). One of the consequences of this is that, whenever you do a manipulation that changes a string, you get back a new, different object.
So in your example, 3 strings are created.
Take these two String objects:
String a = "a";
String b = "b";
String c = "a" + "b";
String d = "ab";
The compiler creates and pools three String objects. A line by line explanation follows.
Line 1: One String object is pooled for "a"
Line 2: One String object is pooled for "b"
Line 3: "a" + "b" is computer at compile time and treated as a literal. Therefore, one String object is pooled for "ab"
Line 4: "ab" is already in the pool
Following the same guidelines, your example produces 3 String objects.
Here is one of the constructor for String object in Java:
public String(String original) {
int size = original.count;
char[] originalValue = original.value;
char[] v;
if (originalValue.length > size) {
// The array representing the String is bigger than the new
// String itself. Perhaps this constructor is being called
// in order to trim the baggage, so make a copy of the array.
int off = original.offset;
v = Arrays.copyOfRange(originalValue, off, off+size);
} else {
// The array representing the String is the same
// size as the String, so no point in making a copy.
v = originalValue;
}
this.offset = 0;
this.count = size;
this.value = v;
}
The line of code if (originalValue.length > size) is what I care about, I don't think this condition can be true for all the code inside IF being executed. The String is in fact an array of characters. original.count should be equal to its value's length (its value is an array of characters), so the condition wouldn't happen.
I may be wrong, so I need your explanation. Thanks for your help.
VipHaLong.
The String is infact an array of characters
No it's not. It's an object which internally has a reference to an array of characters.
original.count should be equal to its value's length (its value is an array of characters)
Not necessarily. It depends on the exact version of Java you're looking at, but until recently several strings could refer to the same char[], each using a different portion of the array.
For example, if you have:
String longString = "this is a long string";
String shortString = longString.substring(0, 2);
... the object referred to shortString would use the same char[] that the original string referred to, but with an start offset of 0 and a count of 2. So if you then called:
String copyOfShortString = new String(shortString);
that would indeed go into the if block you were concerned about in your question.
As of Java 7 update 5, the Oracle JRE has changed to make substring always take a copy. (The pros and cons behind this can get quite complicated, but it's worth being aware of both systems.)
It looks like the version of code you're looking at is an older version where string objects could share an underlying array but view different portions.
The String implementation that you are looking at does not copy character data when you create a substring. Instead, multiple String objects can refer to the same character array but have different offset and count (and therefore length).
Therefore, the if condition can, in fact, be true.
Note that this sharing of character arrays has been removed in recent versions of the Oracle JDK.
i want to concatenate a new string to the start of an existing string, for example,
the current string="" and i want always to concatenate the new string to start of my old string:
String msg="Java One",temp;
for(int i=msg.length()-2;i>0;i--){
here i make a loop starting from the end of msg after the end finishes temp should contains "Java One" but in this order
e
ne
one
a one
va one
}
and so on
I want always to concatenate the new string to start of my old string
This is very simple, but not very efficient:
String oldString = "";
for (...) {
// Prepare your new string
String newString = ... ;
// Add the new string at the beginning of the old string
oldString = newString + oldString;
}
You can use String#substring(int,int) to get different substrings in each iteration.
for(int i=msg.length()-1;i>=0;i--){
System.out.println(msg.substring(i,msg.length()));
}
Of course you can store each generated substring and do what you wish with it.
Note that this approach is likely to be more efficient, because though new String objects will be created, it is likely to use the same underlying char[] object for all of them.
Also note that we are iterating from msg.length()-1 (and not -2, as the original code in the question) and while i >= 0 (and not i > 0, as in the original question)
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What is the purpose of the expression “new String(…)” in Java?
Hi,
1) What is difference in thers two statements:
String s1 = "abc";
and
String s1 = new String("abc")
2) as i am not using new in first statement, how string object will be created
Thanks
The first will use a fixed String that will be compiled in the code. The second variant uses the fixed String and creates a new String by copying the characters. This actually creates a new separate object in memory and is not necessary, because Strings are immutable. For more information, you can read this thread.
The main advantage of having internalized strings is that the performance is better (e.g. through caching etc.).
As a programmer there is no real upside to creating a new String, unless you come by the following example:
String sentence = "Lorem ipsum dolor sit amet";
String word = sentence.substring(5);
Now the word has a reference to the sentence (substring does not copy the characters). This is efficient while the sentence is also used, but when this one is thrown away you use a lot more memory than needed. In that case a new String can be created:
word = new String(word);
In the first case, the compiler knows the value of the String s1. Thus, all strings with the same value will use the same memory locations:
String s1 = "abc";
String s2 = "abc";
Although there are two String references (s1 and s2), there is only one "abc" sequence in memory. The new operator is not needed because the compiler does the job.
In the second case, the compiler doesn't perform the evaluation of the String value. Thus, the sentence will generate a new instance of String, at runtime:
String s1 = "abc";
String s2 = new String("abc");
The constant "abc" in line 1 references the same memory as the constant "abc" in line 2. But the net effect of line 2 is the creation of a new String instance.