Как мне получить первые n
символы строки в Java, не выполнив сначала проверку размера (inline допускается) или не рискуя IndexOutOfBoundsException
?
Как мне получить первые n
символы строки в Java, не выполнив сначала проверку размера (inline допускается) или не рискуя IndexOutOfBoundsException
?
Ответы:
Вот изящное решение:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Мнение: хотя это решение «аккуратное», я думаю, что оно на самом деле менее читабельно, чем решение, которое использует if
/ else
очевидным образом. Если читатель не видел этот трюк, он должен подумать, чтобы понять код. ИМО, смысл кода более очевиден в if
/ else
версии. Более чистое / читабельное решение смотрите в ответе @ paxdiablo.
Не изобретай велосипед ...:
org.apache.commons.lang.StringUtils.substring(String s, int start, int len)
Javadoc говорит:
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"
Таким образом:
StringUtils.substring("abc", 0, 4) = "abc"
StringUtils.substring(yourString, 0, n)
это не то же самое, что yourString.substring(0, n)
. Первый из StringUtils
, а последний использует String.substring
(что дает исключение, если конечный индекс превышает длину строки).
if (end > str.length()) { end = str.length();}
StringUtils.substring(String s, int start, int len)
не длинен, это конечный индекс.
У Apache Commons Lang есть StringUtils.left
метод для этого.
String upToNCharacters = StringUtils.left(s, n);
Есть класс вопросов по SO, который иногда имеет смысл не совсем идеальный, этот опасно близок :-)
Возможно, вы могли бы объяснить свое отвращение к использованию одного из двух методов, которые вы исключили.
Если это просто потому, что вы не хотите перетекать свой код if
заявлениями или кодом перехвата исключений, одним из решений является использование вспомогательной функции, которая позаботится об этом за вас, что-то вроде:
static String substring_safe (String s, int start, int len) { ... }
который заранее проверит длину и будет действовать соответственно (вернет меньшую строку или пробел с пробелами).
Тогда вам не нужно беспокоиться об этом в вашем коде, просто позвоните:
String s2 = substring_safe (s, 10, 7);
вместо того:
String s2 = s.substring (10,7);
Это сработает в том случае, если вы, кажется, беспокоитесь (основываясь на ваших комментариях к другим ответам), не нарушая поток кода при выполнении большого количества работ по построению строк.
String upToNCharacters = String.format("%."+ n +"s", str);
Ужасно, если n
это переменная (поэтому вы должны создать строку формата), но довольно ясно, если константа:
String upToNCharacters = String.format("%.10s", str);
Используйте метод подстроки следующим образом:
int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);
Если n больше длины строки, это вызовет исключение, как указал один из комментариев. Одно простое решение - обернуть все это в условие if(s.length()<n)
в вашем else
предложении, вы можете выбрать, хотите ли вы просто напечатать / вернуть всю строку или обработать ее другим способом.
Если вам повезло в разработке с Kotlin,
вы можете использовать take
для достижения своей цели.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
ApacheCommons удивил меня,
StringUtils.abbreviate(String str, int maxWidth)
добавляет "..." нет возможности изменить постфикс.
WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
смотрит на следующее пустое место.
Я просто собираюсь оставить это здесь:
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;
}