Domanda

Printf è stato aggiunto a Java con la versione 1.5 ma non riesco a trovare come inviare l'output a una stringa anziché a un file (che è ciò che fa sprintf in C).Qualcuno sa come fare questo?

È stato utile?

Soluzione

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

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

Vedere formato e il suo sintassi

Altri suggerimenti

@erickson.

Le stringhe sono tipi immutabili.Non puoi modificarli, restituisci solo nuove istanze di stringa.

Per questo motivo "foo".format() ha poco senso, poiché dovrebbe essere chiamato così

string newString = "foo".format();

Gli autori Java originali (e gli autori .NET), hanno deciso che un metodo statico aveva più senso in questa situazione, poiché non si sta modificando "foo", ma si chiama invece un metodo di formato e si passa una stringa di input.

MODIFICARE:Eh, questo sito può essere così divertente a volte.Sono stato sottovalutato per aver menzionato il fatto che le stringhe sono tipi immutabili.

Ecco un esempio del motivo per cui Format() sarebbe stupido come metodo di istanza.In .NET (e probabilmente in Java), replace() è un metodo di istanza.

Puoi farlo:

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

Tuttavia, non succede nulla, perché le stringhe sono immutabili.Sostituisci tenta di restituire una nuova stringa, ma non viene assegnata a nulla.

Ciò causa molti errori comuni da principiante come:

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

Ancora una volta, non succede nulla, invece devi fare:

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

Ora, se capisci che le stringhe sono immutabili, ha perfettamente senso.Se non lo fai, allora sei solo confuso.Il posto corretto per Sostituisci sarebbe dove si trova Format, come metodo statico di String:

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

Ora non ci sono più dubbi su cosa sta succedendo.

La vera domanda è: perché gli autori di questi framework hanno deciso che uno dovesse essere un metodo di istanza e l'altro statico?A mio parere, entrambi sono espressi in modo più elegante come metodi statici, ma erickson sembra pensare che entrambi appartengano a metodi di istanza.

Indipendentemente dalla tua opinione, la verità è che sei meno incline a commettere errori utilizzando la versione statica e il codice è più facile da capire (No Hidden Gotchas).

Naturalmente ci sono alcuni metodi perfetti come metodi di istanza, prendi String.Length()

int length = "123".Length();

In questa situazione, è ovvio che non stiamo cercando di modificare "123", lo stiamo semplicemente ispezionando e restituendo la sua lunghezza... Questo è un candidato perfetto per un metodo di istanza.

Le mie semplici regole per i metodi di istanza su oggetti immutabili:

  • Se è necessario restituire una nuova istanza dello stesso tipo, utilizzare un metodo statico.
  • Altrimenti, usa un metodo di istanza.

Entrambe le soluzioni funzionano per simulare printf, ma in modo diverso.Ad esempio, per convertire un valore in una stringa esadecimale, hai le 2 soluzioni seguenti:

  • con format(), il più vicino 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), un po' più veloce ma piuttosto limitato:

        ...
        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)));
        ...
    
  • Esiste una terza soluzione che consiste semplicemente nell'aggiungere il carattere a ret uno per uno (i caratteri sono numeri che sommarsi tra loro!) come in:

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

...ma sarebbe così Veramente brutto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top