Quando você precisa percorrer uma coleção e criar uma sequência de cada dado separada por um delimitador, você sempre acaba com um delimitador extra no final, por exemplo,
for (String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
Fornece algo como: serverId_1, serverId_2, serverId_3,
Gostaria de excluir o último caractere no StringBuilder (sem convertê-lo, porque ainda preciso dele após esse loop).
java
stringbuilder
Mateus
fonte
fonte
StringJoiner
: stackoverflow.com/a/29169233/901641Respostas:
Outros apontaram o
deleteCharAt
método, mas aqui está outra abordagem alternativa:Como alternativa, use a
Joiner
classe Guava :)A partir do Java 8,
StringJoiner
faz parte do JRE padrão.fonte
Joiner
muito em suaStringUtils
. commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)Outra solução simples é:
Uma solução mais complicada:
A solução acima pressupõe que
sb.length() > 0
... ou seja, existe um "último caractere" a ser removido. Se você não pode fazer essa suposição, e / ou não pode lidar com a exceção que resultaria se a suposição estiver incorreta, verifique primeiro o comprimento do StringBuilder; por exemploou
fonte
fonte
sb.length() == 0
tambémseparator.length()
em vez de 1.No Java 8, a classe String possui um método estático
join
. O primeiro argumento é uma string que você deseja entre cada par de strings, e o segundo é umIterable<CharSequence>
(que são ambas interfaces, portanto algo comoList<String>
funciona. Então, você pode fazer isso:Também no Java 8, você pode usar a nova
StringJoiner
classe, para cenários em que deseja começar a construir a sequência antes de ter a lista completa de elementos a serem inseridos.fonte
String.join
vez deStringJoiner
.Apenas obtenha a posição da última ocorrência de caractere.
Desde a
lastIndexOf
a pesquisa inversa será executada e você sabe que ela será encontrada na primeira tentativa, o desempenho não será um problema aqui.EDITAR
Como eu continuo levantando minha resposta (obrigado pessoal 😊), vale a pena:
No Java 8 em diante, seria mais legível e explícito usar o StringJoiner . Ele tem um método para um separador simples e uma sobrecarga para prefixo e sufixo.
Exemplos retirados daqui: exemplo
Exemplo usando separador simples:
Resultado:
Exemplo com sufixo e prefixo:
Resultado
fonte
,
porque foi a última declaração dofor loop
. OlastInfexOf
é mais para facilitar a leitura e torná-lo um acéfalo, se você não quer se lembrar se for 0 indexada ou não. Além disso, você não precisa interferir no comprimento do construtor de cordas. É apenas para a conveniência.Nesse caso,
é preferível, pois apenas atribui o último valor ao
'\0'
passo que excluir o último caractereSystem.arraycopy
fonte
setLength
chamada não está atribuindo nada ao último valor. Os buffers de seqüência de caracteres Java não são nulos / zero finalizados. Na verdade,setLength
é simplesmente atualizar umlength
campo.arraycopy
cópias são 0 elementos, então eu acho que isso pode ser otimizado.Com
Java-8
você pode usar o método estático daString
classe,String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements)
.RESULTADO
fonte
Outra alternativa
fonte
Alternativamente,
fonte
fonte
Ainda outra alternativa:
fonte
Para evitar a reinicialização (afetar o desempenho) do
prefix
uso TextUtils.isEmpty:fonte
Você pode tentar usar a classe 'Joiner' em vez de remover o último caractere do texto gerado;
fonte
Estou fazendo algo como abaixo:
fonte
Aqui está outra solução:
fonte
Pessoalmente, gosto de acrescentar um caractere de backspace (ou mais para um "delimitador" mais longo) no final:
Observe que ele tem problemas:
\b
é exibido depende do ambiente,length()
doString
conteúdo pode ser diferente do comprimento de caracteres "Visível"Quando
\b
parece bom e o comprimento não importa, como fazer login em um console, isso parece bom o suficiente para mim.fonte
stringBuilder.Remove (stringBuilder.Length - 1, 1);
fonte