开发者

Replace the first letter of a String in Java?

I'm trying to convert the first letter of a string to lowercase.

value.substring(0,1).toLowerCase() + value.substring(1)

This works, but are there any better ways to do this?

I could use a replace function, but Java's replace doesn't accept an index. You have to pass the actual character/substring. It could be done like this:

value.replaceFirst(value.charAt(0), value.charAt(0).toLowerCase())

Except that replaceFirst expects 2 strings, so the value.charAt(0)s would probably need t开发者_如何学JAVAo be replaced with value.substring(0,1).

Is there any standard way to replace the first letter of a String?


I would suggest you to take a look at Commons-Lang library from Apache. They have a class

StringUtils

which allows you to do a lot of tasks with Strings. In your case just use

StringUtils.uncapitalize( value )

read here about uncapitalize as well as about other functionality of the class suggested

Added: my experience tells that Coomon-Lang is quite good optimized, so if want to know what is better from algorithmistic point of view, you could take a look at its source from Apache.


The downside of the code you used (and I've used in similar situations) is that it seems a bit clunky and in theory generates at least two temporary strings that are immediately thrown away. There's also the issue of what happens if your string is fewer than two characters long.

The upside is that you don't reference those temporary strings outside the expression (leaving it open to optimization by the bytecode compiler or the JIT optimizer) and your intent is clear to any future code maintainer.

Barring your needing to do several million of these any given second and detecting a noticeable performance issue doing so, I wouldn't worry about performance and would prefer clarity. I'd also bury it off in a utility class somewhere. :-) See also jambjo's response to another answer pointing out that there's an important difference between String#toLowerCase and Character.toLowerCase. (Edit: The answer and therefore comment have been removed. Basically, there's a big difference related to locales and Unicode and the docs recommend using String#toLowerCase, not Character.toLowerCase; more here.)

Edit Because I'm in a weird mood, I thought I'd see if there was a measureable difference in performance in a simple test. There is. It could be because of the locale difference (e.g., apples vs. oranges):

public class Uncap
{
    public static final void main(String[] params)
    {
        String  s;
        String  s2;
        long    start;
        long    end;
        int     counter;

        // Warm up
        s = "Testing";
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap1(s);
            s2 = uncap2(s);
            s2 = uncap3(s);
        }

        // Test v2
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap2(s);
        }
        end = System.currentTimeMillis();
        System.out.println("2: " + (end - start));

        // Test v1
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap1(s);
        }
        end = System.currentTimeMillis();
        System.out.println("1: " + (end - start));

        // Test v3
        start = System.currentTimeMillis();
        for (counter = 1000000; counter > 0; --counter)
        {
            s2 = uncap3(s);
        }
        end = System.currentTimeMillis();
        System.out.println("3: " + (end - start));

        System.exit(0);
    }

    // The simple, direct version; also allows the library to handle
    // locales and Unicode correctly
    private static final String uncap1(String s)
    {
        return s.substring(0,1).toLowerCase() + s.substring(1);
    }

    // This will *not* handle locales and unicode correctly
    private static final String uncap2(String s)
    {
        return Character.toLowerCase(s.charAt(0)) + s.substring(1);
    }

    // This will *not* handle locales and unicode correctly
    private static final String uncap3(String s)
    {
        StringBuffer sb;

        sb = new StringBuffer(s);
        sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
        return sb.toString();
    }
}

I mixed up the order in various tests (moving them around and recompiling) to avoid issues of ramp-up time (and tried to force some initially anyway). Very unscientific, but uncap1 was consistently slower than uncap2 and uncap3 by about 40%. Not that it matters, we're talking a difference of 400ms across a million iterations on an Intel Atom processor. :-)

So: I'd go with your simple, straightforward code, wrapped up in a utility function.


Watch out for any of the character functions in strings. Because of unicode, it is not always a 1 to 1 mapping. Stick to string based methods unless char is really what you want. As others have suggested, there are string utils out there, but even if you don't want to use them for your project, just make one yourself as you work. The worst thing you can do is to make a special function for lowercase and hide it in a class and then use the same code slightly differently in 12 different places. Put it somewhere it can easily be shared.


Use StringBuffer:

buffer.setCharAt(0, Character.toLowerCase(buffer.charAt(0)));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜