Como faço para obter os primeiros n
caracteres de uma string em Java sem fazer uma verificação de tamanho primeiro (a linha é aceitável) ou arriscar IndexOutOfBoundsException
?
Como faço para obter os primeiros n
caracteres de uma string em Java sem fazer uma verificação de tamanho primeiro (a linha é aceitável) ou arriscar IndexOutOfBoundsException
?
Respostas:
Aqui está uma solução elegante:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Opinião: embora essa solução seja "pura", acho que é realmente menos legível do que uma solução que usa if
/ else
da maneira óbvia. Se o leitor não viu esse truque, ele / ela precisa pensar mais para entender o código. IMO, o significado do código é mais óbvio na versão if
/ else
. Para uma solução mais limpa / legível, consulte a resposta de @ paxdiablo.
Não reinvente a roda ...:
org.apache.commons.lang.StringUtils.substring(String s, int start, int len)
Javadoc diz:
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"
Portanto:
StringUtils.substring("abc", 0, 4) = "abc"
StringUtils.substring(yourString, 0, n)
não é o mesmo que yourString.substring(0, n)
. O primeiro é de StringUtils
, enquanto o último está usando String.substring
(o que dá exceção se o índice final exceder o comprimento da string).
if (end > str.length()) { end = str.length();}
StringUtils.substring(String s, int start, int len)
não é len, é o índice final.
O Apache Commons Lang tem um StringUtils.left
método para isso.
String upToNCharacters = StringUtils.left(s, n);
Há uma classe de perguntas sobre SO que às vezes fazem menos do que perfeito sentido; esta é perigosamente próxima :-)
Talvez você possa explicar sua aversão ao uso de um dos dois métodos que descartou.
Se é apenas porque você não deseja incluir seu código em if
instruções ou códigos de captura de exceção, uma solução é usar uma função auxiliar que cuidará disso para você, algo como:
static String substring_safe (String s, int start, int len) { ... }
que verificará os comprimentos antecipadamente e agirá de acordo (retorne uma string menor ou use um espaço com espaços).
Então você não precisa se preocupar com isso no seu código, basta ligar para:
String s2 = substring_safe (s, 10, 7);
ao invés de:
String s2 = s.substring (10,7);
Isso funcionaria no caso em que você pareça estar preocupado (com base nos seus comentários para outras respostas), em não interromper o fluxo do código ao fazer várias coisas de construção de strings.
String upToNCharacters = String.format("%."+ n +"s", str);
Horrível se n
for uma variável (portanto, você deve construir a sequência de formatação), mas bem claro se for uma constante:
String upToNCharacters = String.format("%.10s", str);
Use o método de substring, da seguinte maneira:
int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);
Se n for maior que o comprimento da string, isso gerará uma exceção, como apontou um comentarista. Uma solução simples é agrupar tudo isso na condição if(s.length()<n)
de sua else
cláusula, você pode escolher se deseja apenas imprimir / retornar a String inteira ou lidar com ela de outra maneira.
Se você tiver sorte o suficiente para desenvolver com o Kotlin,
poderá usar take
para atingir seu objetivo.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
O ApacheCommons me surpreendeu,
StringUtils.abbreviate(String str, int maxWidth)
acrescenta "...", não há opção para alterar o postfix.
WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
procura o próximo espaço vazio.
Eu só vou deixar isso aqui:
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;
}