L-Trim- und R-Trim-Alternativen in Java

1. Übersicht

Die Methode String.trim () entfernt nachgestellte und führende Leerzeichen. Es gibt jedoch keine Unterstützung dafür, nur eine L-Trimmung oder eine R-Trimmung durchzuführen.

In diesem Tutorial sehen wir einige Möglichkeiten, wie wir dies implementieren können. Am Ende werden wir ihre Leistung vergleichen.

2. while- Schleife

Die einfachste Lösung besteht darin, die Zeichenfolge mit ein paar while- Schleifen zu durchlaufen .

Bei L-Trim lesen wir die Zeichenfolge von links nach rechts, bis wir auf ein Nicht-Leerzeichen stoßen:

int i = 0; while (i < s.length() && Character.isWhitespace(s.charAt(i))) { i++; } String ltrim = s.substring(i); 

ltrim ist dann eine Teilzeichenfolge, die mit dem ersten Nicht-Leerzeichen beginnt.

Oder für R-Trim lesen wir unsere Zeichenfolge von rechts nach links, bis wir auf ein Nicht-Leerzeichen stoßen:

int i = s.length()-1; while (i >= 0 && Character.isWhitespace(s.charAt(i))) { i--; } String rtrim = s.substring(0,i+1);

rtrim ist dann eine Teilzeichenfolge, die am Anfang beginnt und beim ersten Nicht-Leerzeichen endet.

3. String.replaceAll Verwenden regulärer Ausdrücke

Eine andere Option ist die Verwendung von String.replaceAll () und eines regulären Ausdrucks:

String ltrim = src.replaceAll("^\\s+", ""); String rtrim = src.replaceAll("\\s+$", "");

(\\ s +) ist der reguläre Ausdruck, der einem oder mehreren Leerzeichen entspricht. Das Caret (^) und das ($) am Anfang und am Ende des regulären Ausdrucks stimmen mit dem Anfang und dem Ende einer Zeile überein.

4. Pattern.compile () und .matcher ()

Wir können reguläre Ausdrücke auch mit java.util.regex.Pattern wiederverwenden :

private static Pattern LTRIM = Pattern.compile("^\\s+"); private static Pattern RTRIM = Pattern.compile("\\s+$"); String ltrim = LTRIM.matcher(s).replaceAll(""); String rtim = RTRIM.matcher(s).replaceAll("");

5. Apache Commons

Darüber hinaus können wir die Apache Commons StringUtils # stripStart- und # stripEnd- Methoden nutzen, um Leerzeichen zu entfernen.

Fügen wir dazu zunächst die Abhängigkeit commons-lang3 hinzu :

 org.apache.commons commons-lang3 3.8.1 

Nach der Dokumentation verwenden wir null, um das Leerzeichen zu entfernen:

String ltrim = StringUtils.stripStart(src, null); String rtrim = StringUtils.stripEnd(src, null);

6. Guave

Schließlich werden wir die Methoden Guava CharMatcher # trimLeadingFrom und #trimTrailingFrom nutzen , um das gleiche Ergebnis zu erzielen .

Fügen wir noch einmal die entsprechende Maven-Abhängigkeit hinzu, diesmal die Guave :

 com.google.guava guava 28.2-jre 

Und in Guava ist es ziemlich ähnlich wie in Apache Commons, nur mit gezielteren Methoden:

String ltrim = CharMatcher.whitespace().trimLeadingFrom(s); String rtrim = CharMatcher.whitespace().trimTrailingFrom(s);

7. Leistungsvergleich

Lassen Sie uns die Leistung der Methoden sehen. Wie üblich werden wir das Open-Source-Framework Java Microbenchmark Harness (JMH) verwenden, um die verschiedenen Alternativen in Nanosekunden zu vergleichen.

7.1. Benchmark-Setup

Für die Erstkonfiguration des Benchmarks haben wir fünf Gabeln und durchschnittliche Zeitberechnungszeiten in Nanosekunden verwendet:

@Fork(5) @State(Scope.Benchmark) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS)

In der Setup-Methode initialisieren wir das ursprüngliche Nachrichtenfeld und die resultierende Zeichenfolge, um sie zu vergleichen:

@Setup public void setup() { src = " White spaces left and right "; ltrimResult = "White spaces left and right "; rtrimResult = " White spaces left and right"; }

Alle Benchmarks entfernen zuerst das linke Leerzeichen, dann das rechte Leerzeichen und vergleichen schließlich die Ergebnisse mit den erwarteten Zeichenfolgen.

7.2. während Schleife

Verwenden wir für unseren ersten Benchmark den while- Loop-Ansatz:

@Benchmark public boolean whileCharacters() { String ltrim = whileLtrim(src); String rtrim = whileRtrim(src); return checkStrings(ltrim, rtrim); }

7.3. String.replaceAll () mit regulärem Ausdruck

Versuchen wir dann String.replaceAll () :

@Benchmark public boolean replaceAllRegularExpression() { String ltrim = src.replaceAll("^\\s+", ""); String rtrim = src.replaceAll("\\s+$", ""); return checkStrings(ltrim, rtrim); }

7.4. Pattern.compile (). Matches ()

Danach kommt Pattern.compile (). Matches () :

@Benchmark public boolean patternMatchesLTtrimRTrim() { String ltrim = patternLtrim(src); String rtrim = patternRtrim(src); return checkStrings(ltrim, rtrim); }

7.5. Apache Commons

Viertens Apache Commons:

@Benchmark public boolean apacheCommonsStringUtils() { String ltrim = StringUtils.stripStart(src, " "); String rtrim = StringUtils.stripEnd(src, " "); return checkStrings(ltrim, rtrim); }

7.6. Guave

Und zum Schluss verwenden wir Guava:

@Benchmark public boolean guavaCharMatcher() { String ltrim = CharMatcher.whitespace().trimLeadingFrom(src); String rtrim = CharMatcher.whitespace().trimTrailingFrom(src); return checkStrings(ltrim, rtrim); }

7.7. Analyse der Ergebnisse

Und wir sollten einige ähnliche Ergebnisse erzielen:

# Run complete. Total time: 00:16:57 Benchmark Mode Cnt Score Error Units LTrimRTrim.apacheCommonsStringUtils avgt 100 108,718 ± 4,503 ns/op LTrimRTrim.guavaCharMatcher avgt 100 113,601 ± 5,563 ns/op LTrimRTrim.patternMatchesLTtrimRTrim avgt 100 850,085 ± 17,578 ns/op LTrimRTrim.replaceAllRegularExpression avgt 100 1046,660 ± 7,151 ns/op LTrimRTrim.whileCharacters avgt 100 110,379 ± 1,032 ns/op

Und es sieht so aus , als wären unsere Gewinner die while- Schleife, Apache Commons und Guava!

8. Fazit

In diesem Tutorial haben wir uns verschiedene Möglichkeiten angesehen, um Leerzeichen am Anfang und am Ende eines Strings zu entfernen .

Wir haben while- Schleife, String.replaceAll (), Pattern.matcher (). ReplaceAll (), Apache Commons und Guava verwendet, um dieses Ergebnis zu erhalten.

Wie immer ist der Code auf GitHub verfügbar.