Sobre a questão da função apache versus o formatador de strings, há poucas dúvidas de que a função apache é mais clara e fácil de ler. Envolvendo o formatador em nomes de funções não é o ideal.
Mas observe que - como outros já mencionaram e demonstraram nesta resposta - String.format()e as Formatterclasses no JDK são melhores opções. Use-os sobre o código comum.
@ Jonik, você gostaria de listar algumas de suas razões? As APIs têm a mesma aparência.
Glen3b
3
@ glen3b: Para um utilitário individual, como esses auxiliares de preenchimento de cordas, realmente não faz diferença qual lib usar. Dito isto, o Guava é, em geral, uma lib mais moderna, mais limpa e melhor documentada do que suas contrapartes em vários projetos do Apache Commons (Commons Lang, Commons Collections, Commons IO, etc). Também é construído por caras realmente inteligentes (Kevin Bourrillion et al), muitos dos quais são ativos na SO . Eu mesmo acabei substituindo as várias bibliotecas do Apache Commons por apenas Guava anos atrás, e não me arrependo.
@ Nullw0rm, se você está se referindo a rgagnon.com, estar ciente de que RealHowTo é o autor de rgagnon.com também, então ele seria creditando-se ...
Colin Pickard
3
pelo menos na minha JVM, o "#" não funciona, o "-" está bom. (Apenas apague o #). Isso pode ser consistente com a documentação do formatador, não sei; ele diz "'#' '\ u0023' Requer que a saída use um formulário alternativo. A definição do formulário é especificada pela conversão."
gatoatigrado
6
Obrigado pela resposta incrível. Mas tenho uma dúvida: para que serve 1$? @leo fez uma resposta muito semelhante que não usa 1$e aparentemente tem o mesmo efeito. Isso faz diferença?
Fabrício Matté 8/03/13
257
Preenchimento com 10 caracteres:
String.format("%10s","foo").replace(' ','*');String.format("%-10s","bar").replace(' ','*');String.format("%10s","longer than 10 chars").replace(' ','*');
Contanto que todos nós nos lembramos para não passar uma cadeia com espaços ...: D
leviathanbadger
4
Estou com @ aboveyou00 - esta é uma solução horrenda para strings com espaços, incluindo o exemplo fornecido por leo. Uma solução para preencher uma string à esquerda ou à direita não deve alterar a string de entrada como aparece na saída, a menos que o preenchimento original da string de entrada faça com que ela exceda o comprimento de preenchimento especificado.
Brian Warshaw
3
Reconheça o problema de espaço. .replace(' ', '*')teve a intenção de mostrar o efeito do preenchimento. A expressão oculta da senha não tem esse problema de qualquer maneira ... Para obter uma resposta melhor sobre como personalizar a cadeia de preenchimento esquerda e direita usando o recurso Java nativo, consulte minha outra resposta.
leo
Se a string contém apenas espaços simples e você quer pad com personagens diferentes, você pode usar regex substituir com olhar para trás / frente: String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")ouString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Preste atenção: você inverte os nomes das funções; se você executá-lo, verá.
azulado
mais se o str original contém espaços, em seguida, isso não funciona
Steven Shaw
@StevenShaw Se não me engano, a substituição não tem como alvo o original str, então isso está correto.
Mafu
3
Por convenção, você não deve usar letras maiúsculas para nomes de funções.
principal-ideal-domain
Existe uma condicional ausente no retorno da string como é quando (length - str.length())é 0? O formatador lança a FormatFlagsConversionMismatchExceptionquando %0sé a string de formato.
Devin Walters
7
Demorei um pouco para descobrir. A chave real é ler a documentação do Formatador.
// Get your data from wherever.finalbyte[] data = getData();// Get the digest engine.finalMessageDigest md5=MessageDigest.getInstance("MD5");// Send your data through it.
md5.update(data);// Parse the data as a positive BigInteger.finalBigInteger digest =newBigInteger(1,md5.digest());// Pad the digest with blanks, 32 wide.String hex =String.format(// See: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html// Format: %[argument_index$][flags][width]conversion// Conversion: 'x', 'X' integral The result is formatted as a hexadecimal integer"%1$32x",
digest
);// Replace the blank padding with 0s.
hex = hex.replace(" ","0");System.out.println(hex);
Por que tornar o fim tão complicado? Você poderia ter feito String hex = String.format ("% 032x", resumo); e teve os mesmos resultados, só que sem a desnecessária replace () e ter que usar o $ para variáveis de acesso específicos (só há um, afinal.)
ArtOfWarfare
@ArtOfWarfare fair point. Alguém originalmente pediu preenchimento de valores hexadecimais em outra pergunta. Vi que tinha um link para a documentação do formatador. É complicado para ser completo.
Nthalk
6
Eu sei que este tópico é meio antigo e a pergunta original era para uma solução fácil, mas se deveria ser realmente rápido, você deve usar uma matriz de caracteres.
Se StringBuffernão puder ser acessado por vários encadeamentos de uma só vez (o que neste caso é verdadeiro), você deverá usar um StringBuilder(no JDK1.5 +) para evitar a sobrecarga da sincronização.
glen3b
5
Aqui está outra maneira de colocar à direita:
// put the number of spaces, or any character you like, in your paddedStringString paddedString ="--------------------";String myStringToBePadded ="I like donuts";
myStringToBePadded = myStringToBePadded + paddedString.substring(myStringToBePadded.length());//result:
myStringToBePadded ="I like donuts-------";
Como alternativa, você pode tornar o comprimento do resultado um parâmetro para o pad(...)método Nesse caso, faça o ajuste do preenchimento oculto nesse método em vez de no construtor.
(Dica: para obter crédito extra, torne-o seguro para threads! ;-)
Isso é seguro para threads, exceto para publicação não segura (torne seus campos finais, como é óbvio). Eu acho que o desempenho pode ser melhorado fazendo uma substring antes do + que deve ser substituído por concat (estranhamente).
Ele preencherá sua String XXX até 9 caracteres com um espaço em branco. Depois disso, todos os espaços em branco serão substituídos por um 0. Você pode alterar o espaço em branco e o 0 para o que quiser ...
Você deve invocar o staticmétodo para String.format(…)não abusar de uma sequência vazia. Salvar quatro caracteres no código fonte certamente não vale a perda de legibilidade.
Holger
2
publicstaticString padLeft(String in,int size,char padChar){if(in.length()<= size){char[] temp =newchar[size];/* Llenado Array con el padChar*/for(int i =0;i<size;i++){
temp[i]= padChar;}int posIniTemp = size-in.length();for(int i=0;i<in.length();i++){
temp[posIniTemp]=in.charAt(i);
posIniTemp++;}returnnewString(temp);}return"";}
Deixe-me deixar uma resposta para alguns casos em que você precisa fornecer preenchimento esquerdo / direito (ou sequência ou espaços de prefixo / sufixo) antes de concatenar para outra sequência e não desejar testar o comprimento ou qualquer condição if.
O mesmo que a resposta selecionada, eu preferiria o StringUtilsApache Commons, mas usando desta maneira:
As respostas @ck e @Marlon Tarak são as únicas a usar a char[], o que para aplicativos que têm várias chamadas para métodos de preenchimento por segundo é a melhor abordagem. No entanto, eles não tiram vantagem de nenhuma otimização de manipulação de array e são um pouco substituídos pelo meu gosto; isso pode ser feito sem loops .
publicstaticvoid main(String... args){System.out.println("012345678901234567890123456789");System.out.println(pad("cats",' ',30,true));System.out.println(pad("cats",' ',30,false));System.out.println(pad("cats",' ',20,false));System.out.println(pad("cats",'$',30,true));System.out.println(pad("too long for your own good, buddy",'#',30,true));}
Saídas:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too longfor your own good, buddy
Você pode usar getCharspara permitir que o Stringconteúdo seja copiado diretamente na outmatriz, em vez de chamar source.toCharArray(), seguido por System.arraycopy. Eu consideraria até simplificar a implementação char[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);; embora isso pareça fillmais trabalhoso, na verdade permite que a JVM elimine o preenchimento zero padrão.
Holger
1
java.util.Formatterfará preenchimento esquerdo e direito. Não há necessidade de dependências estranhas de terceiros (você gostaria de adicioná-las para algo tão trivial).
[Deixei de fora os detalhes e criei este post como 'wiki da comunidade', pois não é algo que eu precise.]
Discordo. Em qualquer projeto Java maior, você normalmente realiza tanta manipulação de String, que vale a pena usar o Apache Commons Lang para aumentar a legibilidade e evitar erros. Todos vocês conhecem códigos como someString.subString (someString.indexOf (startCharacter), someString.lastIndexOf (endCharacter)), que pode ser facilmente evitado com StringUtils.
Bananeweizen
1
Toda operação de cadeia geralmente precisa ser muito eficiente - especialmente se você estiver trabalhando com grandes conjuntos de dados. Eu queria algo rápido e flexível, semelhante ao que você obterá no comando plsql pad. Além disso, não quero incluir uma enorme lib por apenas uma pequena coisa. Com essas considerações, nenhuma dessas soluções foi satisfatória. Estas são as soluções que eu encontrei, que tiveram os melhores resultados de benchmarking, se alguém puder melhorar, adicione seu comentário.
note que é chamado com String.toCharArray () e o resultado pode ser convertido em String com o novo resultado de String ((char [])). A razão para isso é que, se você aplicar várias operações, poderá fazê-las todas em char [] e não continuar convertendo entre formatos - nos bastidores, String é armazenada como char []. Se essas operações fossem incluídas na própria classe String, seria duas vezes mais eficiente - velocidade e memória.
Aqui está uma versão paralela para aqueles que têm seqüências muito longas :-)
int width =100;String s ="129018";CharSequence padded =IntStream.range(0,width).parallel().map(i->i-(width-s.length())).map(i->i<0?'0':s.charAt(i)).collect(StringBuilder::new,(sb,c)-> sb.append((char)c),(sb1,sb2)->sb1.append(sb2));
Respostas:
Apache
StringUtils
tem vários métodos:leftPad
,rightPad
,center
erepeat
.Mas observe que - como outros já mencionaram e demonstraram nesta resposta -
String.format()
e asFormatter
classes no JDK são melhores opções. Use-os sobre o código comum.fonte
Desde o Java 1.5,
String.format()
pode ser usado para preencher esquerda / direita uma determinada string.E a saída é:
fonte
1$
? @leo fez uma resposta muito semelhante que não usa1$
e aparentemente tem o mesmo efeito. Isso faz diferença?Preenchimento com 10 caracteres:
resultado:
Exiba '*' para caracteres de senha:
A saída tem o mesmo comprimento que a string da senha:
fonte
.replace(' ', '*')
teve a intenção de mostrar o efeito do preenchimento. A expressão oculta da senha não tem esse problema de qualquer maneira ... Para obter uma resposta melhor sobre como personalizar a cadeia de preenchimento esquerda e direita usando o recurso Java nativo, consulte minha outra resposta.String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
ouString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Na Goiaba , isso é fácil:
fonte
Algo simples:
O valor deve ser uma sequência. converta-o em string, se não estiver. Curtir
"" + 123
ouInteger.toString(123)
Início da cadeia de caracteres do índice de caracteres de comprimento do valor até o comprimento final do preenchimento:
Mais preciso
almofada direita:
almofada esquerda:
fonte
Dê uma olhada
org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.Mas o algoritmo é muito simples (pad até o tamanho dos caracteres):
fonte
Além do Apache Commons, veja também o
String.format
que deve ser capaz de cuidar do preenchimento simples (por exemplo, com espaços).fonte
fonte
str
, então isso está correto.(length - str.length())
é0
? O formatador lança aFormatFlagsConversionMismatchException
quando%0s
é a string de formato.Demorei um pouco para descobrir. A chave real é ler a documentação do Formatador.
fonte
Eu sei que este tópico é meio antigo e a pergunta original era para uma solução fácil, mas se deveria ser realmente rápido, você deve usar uma matriz de caracteres.
a solução do formatador não é ótima. apenas construir a string de formato cria 2 novas strings.
A solução do apache pode ser aprimorada inicializando o sb com o tamanho do destino, substituindo-o abaixo
com
impediria o crescimento do buffer interno do sb.
fonte
StringBuffer
não puder ser acessado por vários encadeamentos de uma só vez (o que neste caso é verdadeiro), você deverá usar umStringBuilder
(no JDK1.5 +) para evitar a sobrecarga da sincronização.Aqui está outra maneira de colocar à direita:
fonte
Desde o Java 11, String.repeat (int) pode ser usado para preencher esquerda / direita uma determinada string.
Resultado:
fonte
Você pode reduzir a sobrecarga por chamada mantendo os dados de preenchimento, em vez de recriá-los sempre:
Como alternativa, você pode tornar o comprimento do resultado um parâmetro para o
pad(...)
método Nesse caso, faça o ajuste do preenchimento oculto nesse método em vez de no construtor.(Dica: para obter crédito extra, torne-o seguro para threads! ;-)
fonte
Encontrei isso no Dzone
Almofada com zeros:
fonte
você pode usar os métodos incorporados StringBuilder append () e insert (), para preenchimento de comprimentos variáveis de string:
Por exemplo:
fonte
Isso funciona:
Ele preencherá sua String XXX até 9 caracteres com um espaço em branco. Depois disso, todos os espaços em branco serão substituídos por um 0. Você pode alterar o espaço em branco e o 0 para o que quiser ...
fonte
static
método paraString.format(…)
não abusar de uma sequência vazia. Salvar quatro caracteres no código fonte certamente não vale a perda de legibilidade.fonte
Deixe-me deixar uma resposta para alguns casos em que você precisa fornecer preenchimento esquerdo / direito (ou sequência ou espaços de prefixo / sufixo) antes de concatenar para outra sequência e não desejar testar o comprimento ou qualquer condição if.
O mesmo que a resposta selecionada, eu preferiria o
StringUtils
Apache Commons, mas usando desta maneira:Explicar:
myString
: a string que eu insiro, pode ser nulaStringUtils.leftPad(myString, 1)
: se a cadeia for nula, esta instrução retornará nulo tambémdefaultString
para dar uma string vazia para evitar concatenar nullfonte
As respostas @ck e @Marlon Tarak são as únicas a usar a
char[]
, o que para aplicativos que têm várias chamadas para métodos de preenchimento por segundo é a melhor abordagem. No entanto, eles não tiram vantagem de nenhuma otimização de manipulação de array e são um pouco substituídos pelo meu gosto; isso pode ser feito sem loops .Método de teste simples:
Saídas:
fonte
getChars
para permitir que oString
conteúdo seja copiado diretamente naout
matriz, em vez de chamarsource.toCharArray()
, seguido porSystem.arraycopy
. Eu consideraria até simplificar a implementaçãochar[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);
; embora isso pareçafill
mais trabalhoso, na verdade permite que a JVM elimine o preenchimento zero padrão.java.util.Formatter
fará preenchimento esquerdo e direito. Não há necessidade de dependências estranhas de terceiros (você gostaria de adicioná-las para algo tão trivial).[Deixei de fora os detalhes e criei este post como 'wiki da comunidade', pois não é algo que eu precise.]
fonte
Toda operação de cadeia geralmente precisa ser muito eficiente - especialmente se você estiver trabalhando com grandes conjuntos de dados. Eu queria algo rápido e flexível, semelhante ao que você obterá no comando plsql pad. Além disso, não quero incluir uma enorme lib por apenas uma pequena coisa. Com essas considerações, nenhuma dessas soluções foi satisfatória. Estas são as soluções que eu encontrei, que tiveram os melhores resultados de benchmarking, se alguém puder melhorar, adicione seu comentário.
fonte
Use esta função.
Como usar?
saída: 01 02 03 04 .. 11 12
fonte
Muitas pessoas têm algumas técnicas muito interessantes, mas eu gosto de simplificar, então eu vou com isso:
fonte
Uma solução simples sem qualquer API será a seguinte:
fonte
Oneliners de Java, nenhuma biblioteca sofisticada.
Almofada à esquerda, não limite
Almofada direita, não limite
Almofada esquerda, limite do comprimento da almofada
Almofada direita, limite ao comprimento da almofada
fonte
Que tal usar recursão? A solução fornecida abaixo é compatível com todas as versões do JDK e sem a necessidade de bibliotecas externas :)
NOTA : Esta solução acrescentará o preenchimento. Com um pequeno ajuste, você pode prefixar o valor do preenchimento.
fonte
Aqui está uma versão paralela para aqueles que têm seqüências muito longas :-)
fonte
Exemplos de preenchimento na goiaba:
Exemplos de preenchimento no Apache Commons:
Exemplos de preenchimento no JDK:
fonte
Uma solução simples seria:
fonte
Como é isso
A string é "olá" e o preenchimento obrigatório é 15 com o pad esquerdo "0"
fonte