Como obtenho os primeiros n caracteres de uma corda sem verificar o tamanho ou sair dos limites?
-
21-09-2019 - |
Pergunta
Como faço para chegar ao primeiro n
caracteres de uma string em java sem fazer uma verificação de tamanho primeiro (em linha é aceitável) ou arriscando um IndexOutOfBoundsException
?
Solução
Aqui está uma solução interessante:
String upToNCharacters = s.substring(0, Math.min(s.length(), n));
Opinião: enquanto esta solução é "legal", 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 tem que Pense mais para entender o código. IMO, o significado do código é mais óbvio no if
/ else
versão. Para uma solução mais limpa / mais legível, consulte a resposta de @paxdiablo.
Outras dicas
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"
Desta forma:
StringUtils.substring("abc", 0, 4) = "abc"
Apache Commons Lang tem um StringUtils.left
método para isso.
String upToNCharacters = StringUtils.left(s, n);
Há uma classe de pergunta para que, às vezes, faça um sentido menos do que perfeito, este é perigosamente próximo :-)
Talvez você possa explicar sua aversão ao uso de um dos dois métodos que você descartou.
Se é só porque você não quer apimentamento seu código com if
Declarações ou exceção de captura de código, uma solução é usar uma função auxiliar que cuidará dele para você, algo como:
static String substring_safe (String s, int start, int len) { ... }
que verificará os comprimentos de antemão e agirá de acordo (retornará uma corda ou almofada menor com espaços).
Então você não precisa se preocupar com isso em seu código, basta ligar:
String s2 = substring_safe (s, 10, 7);
ao invés de:
String s2 = s.substring (10,7);
Isso funcionaria no caso de você estar preocupado (com base em seus comentários com outras respostas), não quebrando o fluxo do código ao fazer muitas coisas de construção de cordas.
String upToNCharacters = String.format("%."+ n +"s", str);
Terrível se n
é uma variável (então você deve construir a string do formato), mas bem claro se uma constante:
String upToNCharacters = String.format("%.10s", str);
Use o método de substring, como segue:
int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);
Se n for maior que o comprimento da corda, isso lançará uma exceção, como um comentarista apontou. Uma solução simples é envolver tudo isso na condição if(s.length()<n)
na tua else
Cláusula, você pode escolher se deseja apenas imprimir/devolver a string inteira ou lidar com outra maneira.
Se você tiver a sorte de desenvolver com Kotlin,
você pode usar take
para atingir seu objetivo.
val someString = "hello"
someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))
ApacheCommons me surpreendeu,StringUtils.abbreviate(String str, int maxWidth)
Anexos "..." Não há opção para alterar o Postfix.WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)
olha para 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;
}