Wie komme ich n
in Java zu den ersten Zeichen eines Strings, ohne vorher eine Größenprüfung durchzuführen (Inline ist akzeptabel) oder ein Risiko einzugehen IndexOutOfBoundsException
?
Wie komme ich n
in Java zu den ersten Zeichen eines Strings, ohne vorher eine Größenprüfung durchzuführen (Inline ist akzeptabel) oder ein Risiko einzugehen IndexOutOfBoundsException
?
Antworten:
Hier ist eine gute Lösung:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Meinung: Diese Lösung ist zwar "ordentlich", aber meiner Meinung nach weniger lesbar als eine Lösung, die if
/ else
auf offensichtliche Weise verwendet. Wenn der Leser diesen Trick nicht gesehen hat, muss er genauer nachdenken , um den Code zu verstehen. IMO, die Bedeutung des Codes ist in der if
/ else
Version offensichtlicher . Eine sauberere / besser lesbare Lösung finden Sie in der Antwort von @ paxdiablo.
Das Rad nicht neu erfinden ...:
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"
So:
StringUtils.substring("abc", 0, 4) = "abc"
StringUtils.substring(yourString, 0, n)
nicht dasselbe ist wie yourString.substring(0, n)
. Ersteres stammt von StringUtils
, während Letzteres verwendet String.substring
(was eine Ausnahme darstellt, wenn der Endindex die Zeichenfolgenlänge überschreitet).
if (end > str.length()) { end = str.length();}
StringUtils.substring(String s, int start, int len)
ist nicht len, sondern der Endindex.
Apache Commons Lang hat hierfür eine StringUtils.left
Methode.
String upToNCharacters = StringUtils.left(s, n);
Es gibt eine Klasse von Fragen zu SO, die manchmal weniger als vollkommen sinnvoll sind. Diese Frage ist gefährlich nahe :-)
Vielleicht könnten Sie Ihre Abneigung gegen eine der beiden Methoden erklären, die Sie ausgeschlossen haben.
Wenn es nur darum geht, dass Sie Ihren Code nicht mit if
Anweisungen oder Code zum Ausfangen von Ausnahmen überhäufen möchten , besteht eine Lösung darin, eine Hilfsfunktion zu verwenden, die sich um Sie kümmert, etwa:
static String substring_safe (String s, int start, int len) { ... }
Dadurch werden die Längen im Voraus überprüft und entsprechend gehandelt (entweder kleinere Zeichenfolge oder Pad mit Leerzeichen zurückgeben).
Dann müssen Sie sich in Ihrem Code überhaupt keine Sorgen mehr machen. Rufen Sie einfach an:
String s2 = substring_safe (s, 10, 7);
anstatt:
String s2 = s.substring (10,7);
Dies würde in dem Fall funktionieren, in dem Sie sich Sorgen zu machen scheinen (basierend auf Ihren Kommentaren zu anderen Antworten) und den Code-Fluss nicht unterbrechen, wenn Sie viele Zeichenfolgen erstellen.
String upToNCharacters = String.format("%."+ n +"s", str);
Schrecklich, wenn n
es sich um eine Variable handelt (Sie müssen also die Formatzeichenfolge erstellen), aber ziemlich klar, wenn eine Konstante:
String upToNCharacters = String.format("%.10s", str);
Verwenden Sie die Teilzeichenfolgenmethode 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 eine Ausnahme ausgelöst, wie ein Kommentator hervorgehoben hat. Eine einfache Lösung besteht darin, all dies in die Bedingung if(s.length()<n)
in Ihrer else
Klausel einzuschließen. Sie können wählen, ob Sie nur den gesamten String drucken / zurückgeben oder auf andere Weise behandeln möchten.
Wenn Sie das Glück haben, sich mit Kotlin zu entwickeln, können
Sie damit take
Ihr Ziel erreichen.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
ApacheCommons hat mich überrascht,
StringUtils.abbreviate(String str, int maxWidth)
fügt "..." hinzu, es gibt keine Möglichkeit, Postfix zu ändern.
WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
schaut zum nächsten leeren Raum auf.
Ich werde das hier einfach 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;
}