Faster alternatives to replace method in a Java String?

后端 未结 10 1400
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-14 11:07

The fact that the replace method returns a string object rather than replacing the contents of a given string is a little obtuse (but understandable when you know that strin

相关标签:
10条回答
  • 2020-12-14 11:42

    The follow code is approx. 30 times faster if there is no match and 5 times faster if there is a match.

    static String fastReplace( String str, String target, String replacement ) {
        int targetLength = target.length();
        if( targetLength == 0 ) {
            return str;
        }
        int idx2 = str.indexOf( target );
        if( idx2 < 0 ) {
            return str;
        }
        StringBuilder buffer = new StringBuilder( targetLength > replacement.length() ? str.length() : str.length() * 2 );
        int idx1 = 0;
        do {
            buffer.append( str, idx1, idx2 );
            buffer.append( replacement );
            idx1 = idx2 + targetLength;
            idx2 = str.indexOf( target, idx1 );
        } while( idx2 > 0 );
        buffer.append( str, idx1, str.length() );
        return buffer.toString();
    }
    
    0 讨论(0)
  • 2020-12-14 11:43

    This is what StringBuilder is meant for. If you're going to be doing a lot of manipulation, do it on a StringBuilder, then turn that into a String whenever you need to.

    StringBuilder is described thus:

    "A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization".

    It has replace (and append, insert, delete, et al) and you can use toString to morph it into a real String.

    0 讨论(0)
  • 2020-12-14 11:43

    If you have a number of strings to replace (such as XML escape sequences), especially where the replacements are different length from the pattern, FSM lexer type algorithm seems like it might be most efficient, similar to the suggestion of processing in a stream fashion, where the output is incrementally built.

    Perhaps a Matcher object could be used to do that efficiently.

    0 讨论(0)
  • 2020-12-14 11:46

    Because String.replace(CharSequence target, CharSequence replacement) has Pattern.compile, matcher, replaceAll inside, one can slightly optimize it by for using precompiled target pattern constant, like this:

    private static final Pattern COMMA_REGEX = Pattern.compile(",");
    ...
    COMMA_REGEX.matcher(value).replaceAll(replacement);
    
    0 讨论(0)
  • 2020-12-14 11:47

    I agree with the above. Use StringBuffer for thread-safety and StringBuilder when working with single threads.

    0 讨论(0)
  • 2020-12-14 11:47

    Just get the char[] of the String and iterate through it. Use a temporary StringBuilder.

    Look for the pattern you want to replace while iterating if you don't find the pattern, write the stuff you scanned to the StringBuilder, else write the replacement text to the StringBuilder.

    0 讨论(0)
提交回复
热议问题