Come faccio ad arrivare ai primi n
caratteri di una stringa in Java senza prima fare un controllo dimensionale (inline è accettabile) o rischiare un IndexOutOfBoundsException
?
Come faccio ad arrivare ai primi n
caratteri di una stringa in Java senza prima fare un controllo dimensionale (inline è accettabile) o rischiare un IndexOutOfBoundsException
?
Risposte:
Ecco una soluzione pulita:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Opinione: sebbene questa soluzione sia "pulita", penso che in realtà sia meno leggibile di una soluzione che usa if
/ else
nel modo ovvio. Se il lettore non ha visto questo trucco, deve pensare di più per capire il codice. IMO, il significato del codice è più evidente nella versione if
/ else
. Per una soluzione più pulita / più leggibile, vedere la risposta di @ paxdiablo.
Non reinventare la ruota ...:
org.apache.commons.lang.StringUtils.substring(String s, int start, int len)
Javadoc dice:
StringUtils.substring(null, *, *) = null StringUtils.substring("", * , *) = ""; StringUtils.substring("abc", 0, 2) = "ab" StringUtils.substring("abc", 2, 0) = "" StringUtils.substring("abc", 2, 4) = "c" StringUtils.substring("abc", 4, 6) = "" StringUtils.substring("abc", 2, 2) = "" StringUtils.substring("abc", -2, -1) = "b" StringUtils.substring("abc", -4, 2) = "ab"
Così:
StringUtils.substring("abc", 0, 4) = "abc"
StringUtils.substring(yourString, 0, n)
non è lo stesso di yourString.substring(0, n)
. Il primo proviene da StringUtils
, mentre il secondo sta usando String.substring
(il che dà un'eccezione se l'indice finale supera la lunghezza della stringa).
if (end > str.length()) { end = str.length();}
StringUtils.substring(String s, int start, int len)
non è len, è l'indice di fine.
Apache Commons Lang ha un StringUtils.left
metodo per questo.
String upToNCharacters = StringUtils.left(s, n);
C'è una classe di domande su SO che a volte hanno meno di un senso perfetto, questa è pericolosamente vicina :-)
Forse potresti spiegare la tua avversione all'uso di uno dei due metodi che hai escluso.
Se è solo perché non vuoi aggiungere il tuo codice con if
istruzioni o codice di rilevazione delle eccezioni, una soluzione è quella di utilizzare una funzione di supporto che se ne occuperà per te, qualcosa come:
static String substring_safe (String s, int start, int len) { ... }
che controllerà in anticipo le lunghezze e agirà di conseguenza (o restituisce una stringa più piccola o un pad con spazi).
Quindi non devi preoccuparti di questo nel tuo codice, basta chiamare:
String s2 = substring_safe (s, 10, 7);
invece di:
String s2 = s.substring (10,7);
Ciò funzionerebbe nel caso in cui sembri preoccupato (in base ai tuoi commenti ad altre risposte), non interrompere il flusso del codice quando si eseguono molte operazioni di creazione di stringhe.
String upToNCharacters = String.format("%."+ n +"s", str);
Pessimo se n
è una variabile (quindi è necessario costruire la stringa di formato), ma abbastanza chiaro se una costante:
String upToNCharacters = String.format("%.10s", str);
Utilizzare il metodo di sottostringa, come segue:
int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);
Se n è maggiore della lunghezza della stringa, ciò genererà un'eccezione, come ha sottolineato un commentatore. una soluzione semplice è quella di avvolgere tutto questo nella condizione if(s.length()<n)
nella else
clausola, puoi scegliere se vuoi solo stampare / restituire l'intera stringa o gestirla in un altro modo.
Se sei abbastanza fortunato da sviluppare con Kotlin,
puoi usarlo take
per raggiungere il tuo obiettivo.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
ApacheCommons mi ha sorpreso,
StringUtils.abbreviate(String str, int maxWidth)
aggiunge "..." non c'è alcuna opzione per cambiare postfix.
WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
guarda al prossimo spazio vuoto.
Lo lascerò qui:
public static String abbreviate(String s, int maxLength, String appendToEnd) {
String result = s;
appendToEnd = appendToEnd == null ? "" : appendToEnd;
if (maxLength >= appendToEnd.length()) {
if (s.length()>maxLength) {
result = s.substring(0, Math.min(s.length(), maxLength - appendToEnd.length())) + appendToEnd;
}
} else {
throw new StringIndexOutOfBoundsException("maxLength can not be smaller than appendToEnd parameter length.");
}
return result;
}