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 to 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With