Jak uzyskać dostęp do pierwszych n
znaków ciągu w Javie bez sprawdzania rozmiaru (inline jest dopuszczalne) lub ryzykowania IndexOutOfBoundsException
?
Jak uzyskać dostęp do pierwszych n
znaków ciągu w Javie bez sprawdzania rozmiaru (inline jest dopuszczalne) lub ryzykowania IndexOutOfBoundsException
?
Odpowiedzi:
Oto zgrabne rozwiązanie:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Opinia: chociaż to rozwiązanie jest „zgrabne”, myślę, że jest w rzeczywistości mniej czytelne niż rozwiązanie, które wykorzystuje if
/ else
w oczywisty sposób. Jeśli czytelnik nie widział tej sztuczki, musi się zastanowić, aby zrozumieć kod. IMO, znaczenie kodu jest bardziej oczywiste w wersji if
/ else
. Aby uzyskać czystsze / bardziej czytelne rozwiązanie, zobacz odpowiedź @ paxdiablo.
Nie wynajduj koła na nowo ...:
org.apache.commons.lang.StringUtils.substring(String s, int start, int len)
Javadoc mówi:
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"
A zatem:
StringUtils.substring("abc", 0, 4) = "abc"
StringUtils.substring(yourString, 0, n)
to nie to samo co yourString.substring(0, n)
. Pierwsza jest z StringUtils
, podczas gdy druga używa String.substring
(co daje wyjątek, jeśli indeks końcowy przekracza długość ciągu).
if (end > str.length()) { end = str.length();}
StringUtils.substring(String s, int start, int len)
nie jest długi, jest to indeks końcowy.
Apache Commons Lang ma na to StringUtils.left
metodę.
String upToNCharacters = StringUtils.left(s, n);
Jest pewna klasa pytań dotyczących SO, które czasami mają mniej niż doskonały sens, ten jest niebezpiecznie bliski :-)
Być może mógłbyś wyjaśnić swoją niechęć do używania jednej z dwóch metod, które wykluczałeś.
Jeśli dzieje się tak tylko dlatego, że nie chcesz zasypywać swojego kodu if
instrukcjami lub kodem przechwytującym wyjątki, jednym z rozwiązań jest użycie funkcji pomocniczej, która zajmie się tym za Ciebie, na przykład:
static String substring_safe (String s, int start, int len) { ... }
który wcześniej sprawdzi długości i odpowiednio zareaguje (zwróci mniejszy ciąg lub wypełnienie ze spacjami).
Wtedy nie musisz się o to martwić w swoim kodzie, wystarczy zadzwonić:
String s2 = substring_safe (s, 10, 7);
zamiast:
String s2 = s.substring (10,7);
To zadziała w przypadku, gdy wydaje się, że martwisz się (na podstawie swoich komentarzy do innych odpowiedzi), nie przerywając przepływu kodu podczas tworzenia wielu rzeczy związanych z budowaniem ciągów.
String upToNCharacters = String.format("%."+ n +"s", str);
Okropne, jeśli n
jest zmienną (więc musisz skonstruować ciąg formatu), ale całkiem jasne, jeśli jest stałą:
String upToNCharacters = String.format("%.10s", str);
Użyj następującej metody podciągów:
int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);
Jeśli n jest większe niż długość łańcucha, zgłosi to wyjątek, jak zauważył jeden z komentatorów. jednym prostym rozwiązaniem jest zawinięcie tego wszystkiego w warunek if(s.length()<n)
w else
klauzuli, możesz wybrać, czy chcesz po prostu wydrukować / zwrócić cały String, czy też obsłużyć to w inny sposób.
Jeśli masz szczęście rozwijać się z Kotlinem,
możesz użyć, take
aby osiągnąć swój cel.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
ApacheCommons mnie zaskoczyło,
StringUtils.abbreviate(String str, int maxWidth)
dopisuje "..." nie ma możliwości zmiany postfiksa.
WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
wyszukuje następną pustą przestrzeń.
Zostawię to tutaj:
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;
}