Wie bekomme ich die ersten N -Zeichen einer Zeichenfolge, ohne die Größe zu überprüfen oder aus den Grenzen zu gehen?
-
21-09-2019 - |
Frage
Wie komme ich zum ersten Mal auf n
Zeichen einer Zeichenfolge in Java, ohne zuerst eine Größenüberprüfung durchzuführen (Inline ist akzeptabel) oder ein Risiko eines IndexOutOfBoundsException
?
Lösung
Hier ist eine ordentliche Lösung:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Meinung: Während diese Lösung "ordentlich" ist, denke ich, dass es tatsächlich ist Weniger lesbar als eine Lösung, die verwendet if
/ else
Auf die offensichtliche Weise. Wenn der Leser diesen Trick nicht gesehen hat, muss er/sie Denken Sie härter nach den Code verstehen. IMO, die Bedeutung des Codes ist in der offensichtlicher if
/ else
Ausführung. Eine sauberere / lesbarere Lösung finden Sie in der Antwort von @paxdiablo.
Andere Tipps
Erfinden Sie das Rad nicht neu ...:
org.apache.commons.lang.StringUtils.substring(String s, int start, int len)
Javadoc sagt:
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"
Daher:
StringUtils.substring("abc", 0, 4) = "abc"
Apache Commons Lang hat ein StringUtils.left
Methode dafür.
String upToNCharacters = StringUtils.left(s, n);
Es gibt eine Frage der Frage, dass diese manchmal weniger als perfekter Sinn machen. Dieser ist gefährlich nahe :-)
Vielleicht könnten Sie Ihre Abneigung erklären, eine der beiden Methoden zu verwenden, die Sie ausgeschlossen haben.
Wenn es nur daran liegt, dass Sie Ihren Code nicht pfeffern möchten if
Aussagen oder Ausnahme -Catching -Code, eine Lösung besteht darin, eine Helferfunktion zu verwenden, die sich darum kümmert, so etwas wie:
static String substring_safe (String s, int start, int len) { ... }
Dies prüft die Längen vorher und handelt entsprechend (entweder kleinerer Saite oder Pad mit Leerzeichen zurück).
Dann müssen Sie sich in Ihrem Code überhaupt keine Sorgen machen, rufen Sie einfach an:
String s2 = substring_safe (s, 10, 7);
Anstatt von:
String s2 = s.substring (10,7);
Dies würde für den Fall funktionieren, über den Sie sich besorgt zu machen scheinen (basierend auf Ihren Kommentaren zu anderen Antworten), ohne den Fluss des Codes zu brechen, wenn Sie viele Sachen aufbauen.
String upToNCharacters = String.format("%."+ n +"s", str);
Schrecklich wenn n
ist eine Variable (Sie müssen also die Formatzeichenfolge konstruieren), aber ziemlich klar, wenn eine Konstante:
String upToNCharacters = String.format("%.10s", str);
Verwenden Sie die Substring -Methode wie folgt:
int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);
Wenn n größer als die Länge der Zeichenfolge ist, wird dies eine Ausnahme auswerfen, wie ein Kommentator hervorgehoben hat. Eine einfache Lösung besteht darin, all dies in den Zustand zu wickeln if(s.length()<n)
in deiner else
Klausel können Sie wählen, ob Sie nur die gesamte Zeichenfolge ausdrucken/zurückgeben oder einen anderen Weg behandeln möchten.
Wenn Sie das Glück haben, sich mit Kotlin zu entwickeln,
Sie können verwenden take
Ihr Ziel erreichen.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
ApacheKommons überraschte mich,StringUtils.abbreviate(String str, int maxWidth)
Angehörige "..." gibt es keine Möglichkeit, Postfix zu ändern.WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
Schaut zum nächsten leeren Raum.
Ich werde das nur hier lassen:
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;
}