Printf wurde mit der Version 1.5 zu Java hinzugefügt, aber ich kann anscheinend nicht herausfinden, wie die Ausgabe an eine Zeichenfolge anstatt an eine Datei gesendet werden kann (was sprintf in C tut). Weiß jemand, wie man das macht?
Printf wurde mit der Version 1.5 zu Java hinzugefügt, aber ich kann anscheinend nicht herausfinden, wie die Ausgabe an eine Zeichenfolge anstatt an eine Datei gesendet werden kann (was sprintf in C tut). Weiß jemand, wie man das macht?
Antworten:
// Store the formatted string in 'result'
String result = String.format("%4d", i * j);
// Write the result to standard output
System.out.println( result );
Strings sind unveränderliche Typen. Sie können sie nicht ändern, sondern nur neue Zeichenfolgeninstanzen zurückgeben.
Aus diesem Grund ist die Formatierung mit einer Instanzmethode wenig sinnvoll, da sie wie folgt aufgerufen werden müsste:
String formatted = "%s: %s".format(key, value);
Die ursprünglichen Java-Autoren (und .NET-Autoren) haben entschieden, dass eine statische Methode in dieser Situation sinnvoller ist, da Sie das Ziel nicht ändern, sondern stattdessen eine Formatmethode aufrufen und eine Eingabezeichenfolge übergeben.
Hier ist ein Beispiel dafür, warum format()
dies als Instanzmethode dumm wäre. In .NET (und wahrscheinlich in Java) Replace()
ist eine Instanzmethode.
Du kannst das:
"I Like Wine".Replace("Wine","Beer");
Es passiert jedoch nichts, da Zeichenfolgen unveränderlich sind. Replace()
versucht, eine neue Zeichenfolge zurückzugeben, die jedoch nichts zugewiesen ist.
Dies verursacht viele häufige Anfängerfehler wie:
inputText.Replace(" ", "%20");
Auch hier passiert nichts, stattdessen müssen Sie tun:
inputText = inputText.Replace(" ","%20");
Wenn Sie verstehen, dass Zeichenfolgen unveränderlich sind, ist dies absolut sinnvoll. Wenn Sie dies nicht tun, sind Sie nur verwirrt. Der richtige Ort dafür Replace()
wäre, wo format()
ist, als statische Methode von String
:
inputText = String.Replace(inputText, " ", "%20");
Jetzt gibt es keine Frage mehr, was los ist.
Die eigentliche Frage ist, warum die Autoren dieser Frameworks entschieden haben, dass eine Instanzmethode und die andere statisch sein soll. Meiner Meinung nach werden beide eleganter als statische Methoden ausgedrückt.
Unabhängig von Ihrer Meinung ist die Wahrheit, dass Sie mit der statischen Version weniger anfällig für Fehler sind und der Code leichter zu verstehen ist (No Hidden Gotchas).
Natürlich gibt es einige Methoden, die sich perfekt als Instanzmethoden eignen. Nehmen Sie String.Length ()
int length = "123".Length();
In dieser Situation ist es offensichtlich, dass wir nicht versuchen, "123" zu ändern, sondern es nur untersuchen und seine Länge zurückgeben. Dies ist ein perfekter Kandidat für eine Instanzmethode.
Meine einfachen Regeln für Instanzmethoden für unveränderliche Objekte:
Beide Lösungen simulieren printf, jedoch auf unterschiedliche Weise. Um beispielsweise einen Wert in eine Hex-Zeichenfolge zu konvertieren, haben Sie die folgenden 2 Lösungen:
mit format()
, am nächsten an 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;
}
mit replace(char oldchar , char newchar)
, etwas schneller aber ziemlich begrenzt:
...
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)));
...
Es gibt eine dritte Lösung, die darin besteht, das Zeichen ret
nacheinander zu addieren (Zeichen sind Zahlen, die sich gegenseitig addieren !), Wie in:
...
ret += HexChars.charAt((int) ((v >> 12) & 0x0f)));
ret += HexChars.charAt((int) ((v >> 8) & 0x0f)));
...
... aber das wäre wirklich hässlich.
Sie können mit einem PrintStream alles drucken, was ein OutputStream ist. Irgendwie so, in einen String-Stream drucken:
PrintStream ps = new PrintStream(baos);
ps.printf("there is a %s from %d %s", "hello", 3, "friends");
System.out.println(baos.toString());
baos.reset(); //need reset to write new string
ps.printf("there is a %s from %d %s", "flip", 5, "haters");
System.out.println(baos.toString());
baos.reset();
Der String-Stream kann wie folgt erstellt werden: ByteArrayOutputStream:
ByteArrayOutputStream baos = new ByteArrayOutputStream();