Alternative L-Trim e R-Trim in Java

1. Panoramica

Il metodo String.trim () rimuove gli spazi bianchi finali e iniziali . Ma non c'è supporto per fare solo un L-Trim o R-Trim.

In questo tutorial vedremo alcuni modi in cui possiamo implementarlo; alla fine, confronteremo le loro prestazioni.

2. while Loop

La soluzione più semplice è passare attraverso la stringa utilizzando un paio di cicli while .

Per L-Trim, leggeremo la stringa da sinistra a destra fino a quando non incontreremo un carattere diverso da uno spazio bianco:

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

ltrim è quindi una sottostringa che inizia dal primo carattere diverso da uno spazio vuoto .

O per R-Trim, leggeremo la nostra stringa da destra a sinistra fino a quando non incontreremo un carattere diverso da uno spazio bianco:

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

rtrim è quindi una sottostringa che inizia all'inizio e termina al primo carattere diverso da uno spazio vuoto.

3. String.replaceAll utilizzando espressioni regolari

Un'altra opzione è usare String.replaceAll () e un'espressione regolare:

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

(\\ s +) è la regex che corrisponde a uno o più caratteri di spazio bianco. L'accento circonflesso (^) e il ($) all'inizio e alla fine dell'espressione regolare corrispondono all'inizio e alla fine di una riga.

4. Pattern.compile () e .matcher ()

Possiamo riutilizzare le espressioni regolari anche con java.util.regex.Pattern :

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

Inoltre, possiamo sfruttare i metodi Apache Commons StringUtils # stripStart e #stripEnd per rimuovere gli spazi.

Per questo, aggiungiamo prima la dipendenza commons-lang3 :

 org.apache.commons commons-lang3 3.8.1 

Seguendo la documentazione, usiamo null per rimuovere gli spazi:

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

6. Guava

Infine, sfrutteremo i metodi Guava CharMatcher # trimLeadingFrom e #trimTrailingFrom per ottenere lo stesso risultato.

Ancora una volta, aggiungiamo la dipendenza Maven appropriata, questa volta la sua guava :

 com.google.guava guava 28.2-jre 

E in Guava, è abbastanza simile a come è fatto in Apache Commons, solo con metodi più mirati:

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

7. Confronto delle prestazioni

Vediamo le prestazioni dei metodi. Come al solito, utilizzeremo il framework open-source Java Microbenchmark Harness (JMH) per confrontare le diverse alternative in nanosecondi.

7.1. Configurazione benchmark

Per la configurazione iniziale del benchmark, abbiamo utilizzato cinque fork e tempi di calcolo del tempo medio in nanosecondi:

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

Nel metodo di configurazione, stiamo inizializzando il campo del messaggio originale e la stringa risultante da confrontare con:

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

Tutti i benchmark rimuovono prima lo spazio bianco sinistro, quindi lo spazio bianco destro e infine confrontano i risultati con le stringhe previste.

7.2. mentre Loop

Per il nostro primo benchmark, utilizziamo l' approccio del ciclo while :

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

7.3. String.replaceAll () con espressione regolare

Quindi, proviamo String.replaceAll () :

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

7.4. Pattern.compile (). Corrisponde a ()

Successivamente arriva Pattern.compile (). Match () :

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

7.5. Apache Commons

Quarto, Apache Commons:

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

7.6. Guaiava

E infine, usiamo Guava:

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

7.7. Analisi dei risultati

E dovremmo ottenere alcuni risultati simili ai seguenti:

# 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

E sembra che i nostri vincitori siano il ciclo while , Apache Commons e Guava!

8. Conclusione

In questo tutorial, abbiamo esaminato alcuni modi diversi per rimuovere i caratteri di spazio bianco all'inizio e alla fine di una stringa .

Abbiamo usato il ciclo while , String.replaceAll (), Pattern.matcher (). ReplaceAll (), Apache Commons e Guava per ottenere questo risultato.

Come sempre, il codice è disponibile su GitHub.