Pergunta

Printf foi adicionado ao Java com a versão 1.5, mas não consigo descobrir como enviar a saída para uma string em vez de um arquivo (que é o que o sprintf faz em C).Alguém sabe como fazer isso?

Foi útil?

Solução

// Store the formatted string in 'result'
String result = String.format("%4d", i * j);

// Write the result to standard output
System.out.println( result );

Ver formatar e os seus sintaxe

Outras dicas

@erickson.

Strings são tipos imutáveis.Você não pode modificá-los, apenas retornar novas instâncias de string.

Por causa disso, "foo".format() faz pouco sentido, pois teria que ser chamado como

string newString = "foo".format();

Os autores originais do Java (e autores do .NET) decidiram que um método estático fazia mais sentido nessa situação, já que você não está modificando "foo", mas em vez disso chamando um método de formato e passando uma string de entrada.

EDITAR:Heh, este site pode ser tão divertido às vezes.Fui rejeitado por mencionar o fato de que strings são tipos imutáveis.

Aqui está um exemplo de por que Format() seria burro como método de instância.Em .NET (e provavelmente em Java), Replace() é um método de instância.

Você consegue fazer isso:

 "I Like Wine".Replace("Wine","Beer");

Porém, nada acontece, pois Strings são imutáveis.Substituir tenta retornar uma nova string, mas ela não é atribuída a nada.

Isso causa muitos erros comuns de novato, como:

// Contrived Example
inputText.Replace(" ","%20");

Novamente, nada acontece, em vez disso você tem que fazer:

inputText = inputText.Replace(" ","%20");

Agora, se você entende que strings são imutáveis, isso faz todo o sentido.Se não, então você está apenas confuso.O local apropriado para Substituir seria onde Format está, como um método estático de String:

 inputText = String.Replace(inputText," ", "%20");

Agora não há dúvida sobre o que está acontecendo.

A verdadeira questão é: por que os autores desses frameworks decidiram que um deveria ser um método de instância e o outro estático?Na minha opinião, ambos são expressos de maneira mais elegante como métodos estáticos, mas Erickson parece pensar que ambos pertencem a métodos de instância.

Independentemente da sua opinião, a verdade é que você está menos propenso a cometer erros usando a versão estática e o código é mais fácil de entender (Sem pegadinhas ocultas).

Claro que existem alguns métodos que são perfeitos como métodos de instância, veja String.Length()

int length = "123".Length();

Nesta situação, é óbvio que não estamos tentando modificar "123", apenas inspecionando-o e retornando seu comprimento...Este é um candidato perfeito para um método de instância.

Minhas regras simples para métodos de instância em objetos imutáveis:

  • Se precisar retornar uma nova instância do mesmo tipo, use um método estático.
  • Caso contrário, use um método de instância.

Ambas as soluções funcionam para simular printf, mas de uma maneira diferente.Por exemplo, para converter um valor em uma string hexadecimal, você tem as 2 soluções a seguir:

  • com format(), mais perto de sprintf():

    final static String HexChars = "0123456789abcdef";
    
    public static String getHexQuad(long v) {
        String ret;
        if(v > 0xffff) ret = getHexQuad(v >> 16); else ret = "";
        ret += String.format("%c%c%c%c",
            HexChars.charAt((int) ((v >> 12) & 0x0f)),
            HexChars.charAt((int) ((v >>  8) & 0x0f)),
            HexChars.charAt((int) ((v >>  4) & 0x0f)),
            HexChars.charAt((int) ( v        & 0x0f)));
        return ret;
    }
    
  • com replace(char oldchar , char newchar), um pouco mais rápido, mas bastante limitado:

        ...
        ret += "ABCD".
            replace('A', HexChars.charAt((int) ((v >> 12) & 0x0f))).
            replace('B', HexChars.charAt((int) ((v >>  8) & 0x0f))).
            replace('C', HexChars.charAt((int) ((v >>  4) & 0x0f))).
            replace('D', HexChars.charAt((int) ( v        & 0x0f)));
        ...
    
  • Existe uma terceira solução que consiste em apenas adicionar o char ao ret um por um (char são números que adicionar um ao outro!) como em:

    ...
    ret += HexChars.charAt((int) ((v >> 12) & 0x0f)));
    ret += HexChars.charAt((int) ((v >>  8) & 0x0f)));
    ...
    

...mas isso seria realmente feio.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top