Reputation: 412
I have requirement replacing the escape sequences [\n, \r, \t] to "." when building the String. I am using StringBuilder
to append multiple strings.
For Example
public class TempClass {
public static void main(String[] args) throws IOException, ScriptException {
StringBuilder sb = new StringBuilder();
String s1 = "This is John\n He is good guy";
String s2 = " Another String";
System.out.println(sb.append(s1).append(s2).toString().replaceAll("[\\r\\n\\t\\f]","."));
}
}
The above code is working fine.. My question is, is there any efficient way to do this without affecting the performance ? I worry about replaceAll will cause performance issue. I may need to replace all each and every String I need to append.
Upvotes: 0
Views: 333
Reputation: 40062
Nothing fancier that this is required. How you want to package the two strings is up to you. I put them in an array. I also arranged the conditional tests in the order of most to least expected in an attempt to trigger the conditional asap. This order could be different depending on the environment that generated the strings.
StringBuilder sb = new StringBuilder();
String s1 = "This is John\n He is good guy";
String s2 = " Another String";
for(String str : new String[]{s1,s2}) {
for (char ch : str.toCharArray()) {
if (ch == '\n' || ch == '\r' || ch == '\t'||ch == '\f') {
continue; // skip this character
}
sb.append(ch);
}
}
System.out.println(sb.toString());
Upvotes: 1
Reputation: 827
The str.replaceAll() method uses Pattern inside.
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
The only performance issue here is it creates and compiles the pattern everytime you call replaceAll() method. In fact, it can easily take longer to compile the regex and instantiate the Pattern object, than it does to perform an actual match.
So the optimised approach would be to create and compile pattern before hand and use it to replace the escape sequences.
String regex = "[\\r\\n\\t\\f]";
Pattern escapeSequencePattern = Pattern.compile(regex)
So to replace escape sequences, use this pattern instead of replaceAll() method.
public class TempClass {
public static Pattern escapeSequencePattern = Pattern.compile("[\\r\\n\\t\\f]");;
public static void main(String[] args) throws IOException, ClassNotFoundException
{
StringBuilder sb = new StringBuilder();
String s1 = "This is John\n He is good guy";
String s2 = " Another String";
String finalString = sb.append(s1).append(s2).toString();
finalString = escapeSequencePattern.matcher(finalString).replaceAll("");
System.out.println(finalString);
}
}
Upvotes: 1
Reputation: 43391
Unless your string is really big, I wouldn't worry about it. You're still in O(N) time here -- it's just that you need to create two strings, one from the StringBuilder and then another with an O(N) replacement of the chars to .
.
That said, you could just use a for loop, iterating over 0 <= i < sb.length(). For each index, call charAt(int)
to get the char, and if it's one of the four chars you're looking for, call setCharAt
to set it to '.'
. This will save on a char[]
copy for the replacement, but that's about it.
Upvotes: 2