Pregunta

Printf se agregó a Java con la versión 1.5, pero parece que no puedo encontrar cómo enviar la salida a una cadena en lugar de a un archivo (que es lo que hace sprintf en C).¿Alguien sabe como hacer esto?

¿Fue útil?

Solución

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

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

Ver formato y es sintaxis

Otros consejos

@erickson.

Las cadenas son tipos inmutables.No puede modificarlos, solo devolver nuevas instancias de cadena.

Por eso, "foo".format() tiene poco sentido, ya que tendría que llamarse así

string newString = "foo".format();

Los autores originales de Java (y autores de .NET) decidieron que un método estático tenía más sentido en esta situación, ya que no se modifica "foo", sino que se llama a un método de formato y se pasa una cadena de entrada.

EDITAR:Je, este sitio puede ser muy divertido a veces.Me rechazaron por mencionar el hecho de que las cadenas son tipos inmutables.

Aquí hay un ejemplo de por qué Format() sería tonto como método de instancia.En .NET (y probablemente en Java), Reemplazar() es un método de instancia.

Puedes hacerlo:

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

Sin embargo, no sucede nada porque las cadenas son inmutables.Reemplazar intenta devolver una nueva cadena, pero no se le asigna nada.

Esto provoca muchos errores comunes de los novatos como:

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

De nuevo, no pasa nada, en su lugar tienes que hacer:

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

Ahora bien, si comprende que las cadenas son inmutables, eso tiene mucho sentido.Si no lo hace, entonces simplemente está confundido.El lugar adecuado para Reemplazar sería donde está Formato, como método estático de Cadena:

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

Ahora no hay dudas sobre lo que está pasando.

La verdadera pregunta es, ¿por qué los autores de estos marcos decidieron que uno debería ser un método de instancia y el otro estático?En mi opinión, ambos se expresan de manera más elegante como métodos estáticos, pero Erickson parece pensar que ambos pertenecen como métodos de instancia.

Independientemente de su opinión, la verdad es que es menos propenso a cometer errores al usar la versión estática y el código es más fácil de entender (sin errores ocultos).

Por supuesto, hay algunos métodos que son perfectos como métodos de instancia, tome String.Length()

int length = "123".Length();

En esta situación, es obvio que no estamos intentando modificar "123", simplemente lo inspeccionamos y devolvemos su longitud... Este es un candidato perfecto para un método de instancia.

Mis reglas simples para métodos de instancia en objetos inmutables:

  • Si necesita devolver una nueva instancia del mismo tipo, utilice un método estático.
  • De lo contrario, utilice un método de instancia.

Ambas soluciones funcionan para simular printf, pero de forma diferente.Por ejemplo, para convertir un valor en una cadena hexadecimal, tiene las dos soluciones siguientes:

  • con format(), más cercano a 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;
    }
    
  • con replace(char oldchar , char newchar), algo más rápido pero 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 una tercera solución que consiste simplemente en agregar el carácter a ret uno por uno (char son números que agregarse el uno al otro!) como en:

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

...pero eso sería en realidad feo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top