Der Nachteil des Codes, den Sie verwendet haben (und den ich in ähnlichen Situationen verwendet habe), ist, dass er etwas klobig erscheint und theoretisch mindestens zwei temporäre Zeichenfolgen erzeugt, die sofort weggeworfen werden. Außerdem stellt sich die Frage, was passiert, wenn Ihre Zeichenkette weniger als zwei Zeichen lang ist.
Der Vorteil ist, dass Sie diese temporären Zeichenketten nicht außerhalb des Ausdrucks referenzieren (was eine Optimierung durch den Bytecode-Compiler oder den JIT-Optimierer zulässt) und dass Ihre Absicht für jeden zukünftigen Code-Maintainer klar ist.
Es sei denn, Sie müssen in jeder Sekunde mehrere Millionen dieser Aufgaben erledigen y Wenn ich dabei ein spürbares Leistungsproblem feststelle, würde ich mir keine Sorgen um die Leistung machen und lieber Klarheit schaffen. Ich würde es auch irgendwo in einer Utility-Klasse vergraben :-) Siehe auch jambjos Antwort auf eine andere Antwort, die darauf hinweist, dass es einen wichtigen Unterschied gibt zwischen String#toLowerCase
y Character.toLowerCase
. ( Edit: Die Antwort und damit der Kommentar wurden entfernt. Im Grunde gibt es einen großen Unterschied in Bezug auf Gebietsschemata und Unicode und die Dokumentation empfiehlt die Verwendung von String#toLowerCase
ではなく Character.toLowerCase
; mehr hier . )
bearbeiten Da ich in einer komischen Stimmung bin, dachte ich, ich schaue mal, ob es einen messbaren Unterschied in der Leistung in einem einfachen Test gibt. Den gibt es. Es könnte an den lokalen Unterschieden liegen (z.B. Äpfel vs. Orangen):
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();
}
}
Ich habe die Reihenfolge in verschiedenen Tests durcheinander gebracht (indem ich sie verschoben und neu kompiliert habe), um Probleme mit der Anlaufzeit zu vermeiden (und habe anfangs trotzdem versucht, einige zu erzwingen). Sehr unwissenschaftlich, aber uncap1
war durchweg langsamer als uncap2
y uncap3
um etwa 40 %. Nicht, dass das wichtig wäre, wir reden hier von einem Unterschied von 400 ms bei einer Million Iterationen auf einem Intel Atom Prozessor :-)
Also: Ich würde Ihren einfachen, geradlinigen Code verwenden, der in eine Utility-Funktion verpackt ist.
1 Stimmen
Prüfen Sie StringUtils: commons.apache.org/lang/api-2.3/org/apache/commons/lang/