-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Prohibit String.replace() and String.replaceAll(), fix and prohibit some toString()-related redundancies #6607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -153,16 +153,6 @@ public static String toUpperCase(String s) | |
| return s.toUpperCase(Locale.ENGLISH); | ||
| } | ||
|
|
||
| public static String removeChar(String s, char c) | ||
| { | ||
| for (int i = 0; i < s.length(); i++) { | ||
| if (s.charAt(i) == c) { | ||
| return removeChar(s, c, i); | ||
| } | ||
| } | ||
| return s; | ||
| } | ||
|
|
||
| public static String urlEncode(String s) | ||
| { | ||
| try { | ||
|
|
@@ -173,16 +163,81 @@ public static String urlEncode(String s) | |
| } | ||
| } | ||
|
|
||
| private static String removeChar(String s, char c, int firstOccurranceIndex) | ||
| /** | ||
| * Removes all occurrences of the given char from the given string. This method is an optimal version of | ||
| * {@link String#replace(CharSequence, CharSequence) s.replace("c", "")}. | ||
| */ | ||
| public static String removeChar(String s, char c) | ||
| { | ||
| int pos = s.indexOf(c); | ||
| if (pos < 0) { | ||
| return s; | ||
| } | ||
| StringBuilder sb = new StringBuilder(s.length() - 1); | ||
| sb.append(s, 0, firstOccurranceIndex); | ||
| for (int i = firstOccurranceIndex + 1; i < s.length(); i++) { | ||
| char charOfString = s.charAt(i); | ||
| if (charOfString != c) { | ||
| sb.append(charOfString); | ||
| } | ||
| int prevPos = 0; | ||
| do { | ||
| sb.append(s, prevPos, pos); | ||
| prevPos = pos + 1; | ||
| pos = s.indexOf(c, pos + 1); | ||
| } while (pos > 0); | ||
| sb.append(s, prevPos, s.length()); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| /** | ||
| * Replaces all occurrences of the given char in the given string with the given replacement string. This method is an | ||
| * optimal version of {@link String#replace(CharSequence, CharSequence) s.replace("c", replacement)}. | ||
| */ | ||
| public static String replaceChar(String s, char c, String replacement) | ||
| { | ||
| int pos = s.indexOf(c); | ||
| if (pos < 0) { | ||
| return s; | ||
| } | ||
| StringBuilder sb = new StringBuilder(s.length() - 1 + replacement.length()); | ||
| int prevPos = 0; | ||
| do { | ||
| sb.append(s, prevPos, pos); | ||
| sb.append(replacement); | ||
| prevPos = pos + 1; | ||
| pos = s.indexOf(c, pos + 1); | ||
| } while (pos > 0); | ||
| sb.append(s, prevPos, s.length()); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
| /** | ||
| * Replaces all occurrences of the given target substring in the given string with the given replacement string. This | ||
| * method is an optimal version of {@link String#replace(CharSequence, CharSequence) s.replace(target, replacement)}. | ||
| */ | ||
| public static String replace(String s, String target, String replacement) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. although the original method
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are uses for it yet. BTW even the new OpenJDK 9+ version converts the |
||
| { | ||
| // String.replace() is suboptimal in JDK8, but is fixed in JDK9+. When the minimal JDK version supported by Druid is | ||
| // JDK9+, the implementation of this method should be replaced with simple delegation to String.replace(). However, | ||
| // the method should still be prohibited to use in all other places except this method body, because it's easy to | ||
| // suboptimally call String.replace("a", "b"), String.replace("a", ""), String.replace("a", "abc"), which have | ||
| // better alternatives String.replace('a', 'b'), removeChar() and replaceChar() respectively. | ||
| int pos = s.indexOf(target); | ||
| if (pos < 0) { | ||
| return s; | ||
| } | ||
| int sLength = s.length(); | ||
| int targetLength = target.length(); | ||
| // This is needed to work correctly with empty target string and mimic String.replace() behavior | ||
| int searchSkip = Math.max(targetLength, 1); | ||
| StringBuilder sb = new StringBuilder(sLength - targetLength + replacement.length()); | ||
| int prevPos = 0; | ||
| do { | ||
| sb.append(s, prevPos, pos); | ||
| sb.append(replacement); | ||
| prevPos = pos + targetLength; | ||
| // Break from the loop if the target is empty | ||
| if (pos == sLength) { | ||
| break; | ||
| } | ||
| pos = s.indexOf(target, pos + searchSkip); | ||
| } while (pos > 0); | ||
| sb.append(s, prevPos, sLength); | ||
| return sb.toString(); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think the description is not accurate, what is
""in terms of char ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an empty string.
s.replace(":", "")is literally the pattern that should be replaced withremoveChar(s, ':')in the Druid code.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i see.