Insert string in beginning of another string - java

How to insert a string enclosed with double quotes in the beginning of the StringBuilder and String?
Eg:
StringBuilder _sb = new StringBuilder("Sam");
I need to insert the string "Hello" to the beginning of "Sam" and O/p is "Hello Sam".
String _s = "Jam";
I need to insert the string "Hello" to the beginning of "Jam" and O/p is "Hello Jam".
How to achieve this?

The first case is done using the insert() method:
_sb.insert(0, "Hello ");
The latter case can be done using the overloaded + operator on Strings. This uses a StringBuilder behind the scenes:
String s2 = "Hello " + _s;

Other answers explain how to insert a string at the beginning of another String or StringBuilder (or StringBuffer).
However, strictly speaking, you cannot insert a string into the beginning of another one. Strings in Java are immutable1.
When you write:
String s = "Jam";
s = "Hello " + s;
you are actually causing a new String object to be created that is the concatenation of "Hello " and "Jam". You are not actually inserting characters into an existing String object at all.
1 - It is technically possible to use reflection to break abstraction on String objects and mutate them ... even though they are immutable by design. But it is a really bad idea to do this. Unless you know that a String object was created explicitly via new String(...) it could be shared, or it could share internal state with other String objects. Finally, the JVM spec clearly states that the behavior of code that uses reflection to change a final is undefined. Mutation of String objects is dangerous.

Sure, use StringBuilder.insert():
_sb.insert(0, _s);

You can add a string at the front of an already existing one. for example, if I have a name string name, I can add another string name2 by using:
name = name2 + name;
Don't know if this is helpful or not, but it works. No need to use a string builder.

private static void appendZeroAtStart() {
String strObj = "11";
int maxLegth = 5;
StringBuilder sb = new StringBuilder(strObj);
if (sb.length() <= maxLegth) {
while (sb.length() < maxLegth) {
sb.insert(0, '0');
}
} else {
System.out.println("error");
}
System.out.println("result: " + sb);
}

import java.lang.StringBuilder;
public class Program {
public static void main(String[] args) {
// Create a new StringBuilder.
StringBuilder builder = new StringBuilder();
// Loop and append values.
for (int i = 0; i < 5; i++) {
builder.append("abc ");
}
// Convert to string.
String result = builder.toString();
// Print result.
System.out.println(result);
}
}

It is better if you find quotation marks by using the indexof() method and then add a string behind that index.
string s="hai";
int s=s.indexof(""");

Related

How do I get around the limitation of having to place super constructor in the first line?

public NoWheelsException(Car[] carArray){
String holder = "";
for (int i=0; i<carArray.length; i++) {
if (i == carArray.length - 1) {
holder = holder + carArray[i].name;
}else{
holder = holder + carArray[i].name + ", ";
}
}
String message = holder + " has/have no wheels.";
super(message);
}
Written above is the ideal scenario that I'd have for my code, with the super constructor at the end. Although, since super has to be the first statement, I cannot figure out how to develop the string out of the array inline. I can't straight up use .toString() as there's certain criteria into what the string should look like. I've managed to figure out everything regarding Exceptions except this itty bitty detail. Any help would be greatly appreciated!
Update
I got suggested to try Strin.join in order to link them together although unfortunately the object reference names differ from the name variable in the array objects...
One way is to create a private static method, since static methods exist irrespective of constructors and instantiation:
public NoWheelsException(Car[] carArray){
super(buildMessageFrom(carArray));
}
private static String buildMessageFrom(Car[] cars) {
StringBuilder message = new StringBuilder();
String separator = "";
for (Car car : cars) {
message.append(separator);
message.append(car.name);
separator = ", ";
}
return message.toString();
}
(When building a String in a loop, StringBuilder is much more efficient than string concatenation. Each iteration of ‘holder = holder + …’ would create a new String object that eventually needs to be garbage collected.)
If you’re comfortable with Streams, you can do it all on one line:
public NoWheelsException(Car[] carArray){
super(Arrays.stream(carArray).map(c -> c.name).collect(Collectors.joining(", ")));
}

Concatenate is not being used

I have a simple method where the goal is to add "[" and "]" before and after every "."
For example:
Input: address = "1.1.1.1"
Output: "1[.]1[.]1[.]1"
Here is the function I've written, the problem here is where I have concatenate, why is this happening?
public static String defangIPaddr(String address) {
String returnStr = "";
for(int i = 0; i < address.length(); i++) {
char c = address.charAt(i);
if(c == '.') {
returnStr.concat("[");
returnStr.concat(".");
returnStr.concat("]");
} else {
returnStr.concat(address);
}
}
return returnStr;
}
Use replace() instead, just like this:
public static String defangIPaddr(String address) {
return address.replace(".", "[.]");
}
As has been explained, concat doesn't change the string, but rather returns a new string which is the concatenation of the two strings.
returnStr = returnStr.concat("[");
However, don't use concat. You rarely (if ever) need to use this. Instead use +=:
returnStr += "[";
But you don't even really want to use this, because it inefficiently creates a new string every time you do this. That's fine if the concatenation is a one-off, but you don't want to do this in a loop.
Use a StringBuilder instead, which allows you to append to the string without creating a new object each time:
String returnStr = new StringBuilder();
for(int i = 0; i < address.length(); i++) {
// ...
returnStr.append("[");
// ...
}
return returnStr.toString();
Or, of course, in this simple case, use replace.

How to get the new value of new replaced string? [duplicate]

This question already has answers here:
String replace method is not replacing characters
(5 answers)
replace String with another in java
(7 answers)
Closed 4 years ago.
Im still new at java. Is there a way to get the new string that have been replaced ?
import java.io.*;
public class Test {
public static void main(String args[]) {
String str = new String("wew");
System.out.println(str.replaceAll("w", "61"));
System.out.println(str.replaceAll("e", "31"));
}
}
output:
61e61
w31w
Desired new output:
613161
I want to get the output string 61e61 then replaced the e to 31
You can chain replaceAll as:
System.out.println(str.replaceAll("w", "61").replaceAll("e", "31"));
Currently, you're returning two different strings with both your print statements.
System.out.println(str.replaceAll("w", "61")); // returns new string '61e61'
System.out.println(str.replaceAll("e", "31")); // returns new string 'w31w'
You're using it wrong. The method replaceAll of the Class String returns a String.
You have to use the return value again (which can be written in one line):
String str = "wew".replaceAll("w", "61").replaceAll("e", "31");
System.out.println(str);
Outputs: 613161
Let's review why your code doesn't provide what you expect.
You create an instance with "wew".
String str = new String("wew");
Then you replace "w" in "wew" with "61" and print the result "61e61"
System.out.println(str.replaceAll("w", "61")); //61e61
Now, the important part here is that the result of str.replaceAll is a new instance, so str is still "wew".
System.out.println(str); // wew
This explain why the second replacement will print "w31w"
System.out.println(str.replaceAll("e", "31")); //w31w
The reason is that String are immutable, so when you try to change the value of an immutable instance, a new instance is return. So to keep it, you need to assign that instance to a variable.
str = str.replaceAll("w", "61");
Now, the result is kept in the variable "str"
System.out.println(str); // 61e61
Now, one good thing about immutable classes is that method can usually be chained because the return value is an instance of the class itself. So you can call multiple method at one.
str = str.replaceAll("w", "61").replaceAll("e", "31");
System.out.println(str); // 613161
But if you want to print the intermediate result, you will need do it in two statement
str = str.replaceAll("w", "61");
System.out.println(str); // 61e61
System.out.println(str = str.replaceAll("e", "31")); // 613161
Note the last statement, it is possible to merge both assignment and print statement.
First str = .. will be evaluated then the result will be printed.
String.replaceAll() will return a new String so that your code System.out.println(str.replaceAll("w", "61")); and System.out.println(str.replaceAll("e", "31")); need to be chained, else will return wrong result,
you can use StringUtils.replaceEach() from commons-lang3:
StringUtils.replaceEach("wew", new String[]{"w", "e"}, new String[]{"61", "31"});
str = str.replaceAll("w", "61") //Output = 61e61
str = str.replaceAll("e", "31") //Output = 613161

Recursively reversing a sentence using void reverse() method (Java)

The tester class is:
public class SentenceWithReverseTester
{
public static void main(String[] args)
{
String[] list = new String[]{"aba",
"Madam, I'm Adam",
"nut",
"A man, a plan, a canal, Panama",
"wonderful",
"Go hang a salami, I'm a lasagna hog",
"race car",
"1",
"",
"zero",
"#!:"} ;
for (String line : list) {
SentenceWithReverse sentence = new SentenceWithReverse(line) ;
sentence.reverse() ;
System.out.println(line + " reversed becomes........") ;
System.out.println(sentence.toString()) ;
System.out.println("----------------------------") ;
}
}
}
And for the reverse method I have:
public void reverse()
{
String s = super.toString();
if(s.length() > 0)
{
String first = s.substring(0,1);
String remaining = s.substring(1, s.length());
SentenceWithReverse shorter = new SentenceWithReverse(remaining);
shorter.reverse();
System.out.println(shorter + first);
}
}
I'm not getting the result I want, and I'm not sure what I'm doing wrong here.
You should make reverse() actually return a String, rather than void, so that you can use the result of the reversal. So change void to String in the method's declaration. Then you'll need a couple of return statements inside the method - one for the base case and one for the recursive case.
In the recursive case, the return statement will be something like
return shorter.reverse() + first;
that is, you take the reverse of the shorter sentence, and put the first character back at the end.
In the base case, that is, where the input to the method is "", you can just write
return "";
I'll leave it to you to figure out where to insert these two return statements, within the logic of your method. Good luck.
You're not assigning any member fields in your reverse method. You don't show what fields you have, but I would guess you have a single String field that is returned from toString. You should assign the shorter + first to it where you have the System.out.println call.

StringBuilder vs. String considering replace

When doing concatenating lots of strings, I have been recommended to do it using a StringBuilder as such:
StringBuilder someString = new StringBuilder("abc");
someString.append("def");
someString.append("123");
someString.append("moreStuff");
as opposed to
String someString = "abc";
someString = someString + "def";
someString = someString + "123";
someString = someString + "moreStuff";
which would result in the creation of quite a few Strings, as opposed to one.
Now, I need to do a similar thing, but instead of using concatenation I use the replace method of String as such:
String someString = SOME_LARGE_STRING_CONSTANT;
someString = someString.replace("$VARIABLE1", "abc");
someString = someString.replace("$VARIABLE2", "def");
someString = someString.replace("$VARIABLE3", "123");
someString = someString.replace("$VARIABLE4", "moreStuff");
To accomplish the same thing using StringBuilder, I have to do this, just for one replace:
someString.replace(someString.indexOf("$VARIABLE1"), someString.indexOf("$VARIABLE1")+10, "abc");
So my question is: "Is it better to use String.replace and have lots of extra Strings created, or to use StringBuilder still, and have lots of long winded lines such as the one above?"
It is true that StringBuilder tends to be better than concatenating or modifying Strings manually, since StringBuilder is mutable, while String is immutable and you need to create a new String for each modification.
Just to note, though, the Java compiler will automatically convert an example like this:
String result = someString + someOtherString + anotherString;
into something like:
String result = new StringBuilder().append(someString).append(someOtherString).append(anotherString).toString();
That said, unless you're replacing a whole lot of Strings, go for whichever is more readable and more maintainable. So if you can keep it cleaner by having a sequence of 'replace' calls, go ahead and do that over the StringBuilder method. The difference will be negligible compared to the stress you save from dealing with the sad tragedy of micro-optimizations.
PS
For your code sample (which, as OscarRyz pointed out, won't work if you have more than one "$VARIABLE1" in someString, in which case you'll need to use a loop), you could cache the result of the indexOf call in:
someString.replace(someString.indexOf("$VARIABLE1"), someString.indexOf("$VARIABLE1")+10, "abc");
With
int index = someString.indexOf("$VARIABLE1");
someString.replace(index, index+10, "abc");
No need to search the String twice :-)
Guess what? If you are running with Java 1.5+ the concatenation works the same with string literals
String h = "hello" + "world";
and
String i = new StringBuilder().append("hello").append("world").toString();
Are the same.
So, the compiler did the work for you already.
Of course better would be:
String j = "hellworld"; // ;)
As for the second, yeap, that's preferred, but should't be that hard, with the power of "search and replace" and a bit of regex foo
For instance you can define a method like the one in this sample:
public static void replace( String target, String replacement,
StringBuilder builder ) {
int indexOfTarget = -1;
while( ( indexOfTarget = builder.indexOf( target ) ) >= 0 ) {
builder.replace( indexOfTarget, indexOfTarget + target.length() , replacement );
}
}
And your code currently looks like this:
someString = someString.replace("VARIABLE1", "abc");
someString = someString.replace("VARIABLE2", "xyz");
All you have to do is grab text editor an trigger something like this vi search and replace:
%s/^.*("\(.*\)".\s"\(.*\)");/replace("\1","\2",builder);
That read: "take anything in parenthesis and that looks like a string literal, and put it in this other string".
And your code will look from this:
someString = someString.replace("VARIABLE1", "abc");
someString = someString.replace("VARIABLE2", "xyz");
to this:
replace( "VARIABLE1", "abc", builder );
replace( "VARIABLE2", "xyz", builder );
In no time.
Here's a working demo:
class DoReplace {
public static void main( String ... args ) {
StringBuilder builder = new StringBuilder(
"LONG CONSTANT WITH VARIABLE1 and VARIABLE2 and VARIABLE1 and VARIABLE2");
replace( "VARIABLE1", "abc", builder );
replace( "VARIABLE2", "xyz", builder );
System.out.println( builder.toString() );
}
public static void replace( String target, String replacement,
StringBuilder builder ) {
int indexOfTarget = -1;
while( ( indexOfTarget = builder.indexOf( target ) ) > 0 ) {
builder.replace( indexOfTarget, indexOfTarget + target.length() ,
replacement );
}
}
}
I would say go for using StringBuilder but simply write a wrapper that facilitates making the code more readable and thus more maintainable, while still maintaining efficiency. =D
import java.lang.StringBuilder;
public class MyStringBuilder
{
StringBuilder sb;
public MyStringBuilder()
{
sb = new StringBuilder();
}
public void replace(String oldStr, String newStr)
{
int start = -1;
while ((start = sb.indexOf(oldStr)) > -1)
{
int end = start + oldStr.length();
sb.replace(start, end, newStr);
}
}
public void append(String str)
{
sb.append(str);
}
public String toString()
{
return sb.toString();
}
//.... other exposed methods
public static void main(String[] args)
{
MyStringBuilder sb = new MyStringBuilder();
sb.append("old old olD dudely dowrite == pwn");
sb.replace("old", "new");
System.out.println(sb);
}
}
OUTPUT:
new new olD dudely dowrite == pwn
Now you can just use the new version that is one easy liner
MyStringBuilder mySB = new MyStringBuilder();
mySB.append("old dudley dowrite == pwn");
mySB.replace("old", "new"):
Instead of having long lines like that, you could just write a method for replacing parts of StringBuilder strings, something along the lines of this:
public StringBuilder replace(StringBuilder someString, String replaceWhat, String replaceWith) {
return someString.replace(someString.indexOf(replaceWhat), someString.indexOf(replaceWhat)+replaceWhat.length(), replaceWith);
}
May be the String Class internally uses
indexOf
method to find index of old string and replace it with new string.
And also StringBuilder is not threadsafe so it executes much faster.
If your string really is large and you're worried about performance I would recommend writing a class which takes your template text and a list of variables, then reads over the source string character by character and builds the result using StringBuilder. That should be the most efficient both in terms of CPU and memory usage. Also, if you are reading this template text from a file I wouldn't load it all into memory up front. Process it in chunks as you read it from the file.
If you're just looking for a nice way to build a string that's not quite as efficient as StringBuilder but more efficient than appending strings over and over you can use String.format(). It works like sprintf() in C. MessageFormat.format() is an option too but it uses StringBuffer.
There is another related question here: Inserting a Java string in another string without concatenation?
All guys' codes have a bug .try yourReplace("x","xy").It will loop infinitely
Jam Hong is correct - the above solutions all contain the potential to loop infinitely. I guess the lesson to take away here is that micro optimisations can often cause all sorts of horrible issues and don't really save you much. Still, be that as it may - here is a solution that will not infinite loop.
private static void replaceAll(StringBuilder builder, String replaceWhat, String replaceWith){
int occuranceIndex = builder.indexOf(replaceWhat);
int lastReplace = -1;
while(occuranceIndex >= 0){
if(occuranceIndex >= lastReplace){
builder.replace(occuranceIndex, occuranceIndex+replaceWhat.length(), replaceWith);
lastReplace = occuranceIndex + replaceWith.length();
occuranceIndex = builder.indexOf(replaceWhat);
}else{
break;
}
}
}
while it's true that micro optimizations can be problematic, it sometimes depends on the context, for instance, if your replace happens to run inside of a loop with 10000 iterations, your will see a significant performance difference from the "useless" optimizations.
in most cases however, it's best to err on the side of readability

Categories