Как получить первые n символов строки без проверки размера или выхода за пределы?

Как мне перейти к первым символам n строки в Java, не делая сначала проверку размера (inline является допустимым) или рискует IndexOutOfBoundsException?

Ответ 1

Здесь аккуратное решение:

String upToNCharacters = s.substring(0, Math.min(s.length(), n));

Мнение: хотя это решение является "опрятным", я думаю, что оно на самом деле менее читаемо, чем решение, использующее if/else очевидным образом. Если читатель не видел этого трюка, ему/ей приходится усерднее понимать код. ИМО, значение кода более очевидно в версии if/else.

Ответ 2

Не изобретайте велосипед...:

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"

Ответ 3

Существует класс вопросов о 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);

Это будет работать в том случае, если вы, кажется, беспокоитесь (на основе ваших комментариев к другим ответам), не нарушая поток кода, когда делаете много строковых материалов.

Ответ 5

String upToNCharacters = String.format("%."+ n +"s", str);

Ужасно, если n является переменной (поэтому вы должны построить строку формата), но довольно ясно, если константа:

String upToNCharacters = String.format("%.10s", str);

docs

Ответ 6

Используйте метод подстроки следующим образом:

int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);

Если n больше длины строки, это вызовет исключение, как указал один комментатор. одним простым решением является обернуть все это в условие if(s.length()<n) в вашем предложении else, вы можете выбрать, хотите ли вы просто печатать/возвращать всю строку или обрабатывать ее по-другому.

Ответ 7

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;
}