Printf 1.5 sürümüyle Java'ya eklendi, ancak çıktıyı bir dosya yerine bir dizeye nasıl göndereceğimi göremiyorum (sprintf'in yaptığı şey budur). Bunu nasıl yapacağını bilen var mı?
Printf 1.5 sürümüyle Java'ya eklendi, ancak çıktıyı bir dosya yerine bir dizeye nasıl göndereceğimi göremiyorum (sprintf'in yaptığı şey budur). Bunu nasıl yapacağını bilen var mı?
Yanıtlar:
// Store the formatted string in 'result'
String result = String.format("%4d", i * j);
// Write the result to standard output
System.out.println( result );
Biçime ve sözdizimine bakın
Dizeler değişmez türlerdir. Bunları değiştiremezsiniz, yalnızca yeni dize örnekleri döndürürsünüz.
Bu nedenle, bir örnek yöntemiyle biçimlendirme, şöyle adlandırılması gerektiği için çok az mantıklıdır:
String formatted = "%s: %s".format(key, value);
Orijinal Java yazarları (ve .NET yazarları), hedefi değiştirmediğinizden, bunun yerine bir biçim yöntemini çağırdığınızda ve bir giriş dizesi geçirdiğinden, bu durumda statik bir yöntemin daha anlamlı olduğuna karar verdiler.
Örnek format()
bir yöntem olarak neden aptal olabileceğinin bir örneği. .NET'te (ve muhtemelen Java'da) Replace()
bir örnek yöntemidir.
Bunu yapabilirsiniz:
"I Like Wine".Replace("Wine","Beer");
Ancak, hiçbir şey olmaz, çünkü dizeler değişmezdir. Replace()
yeni bir dize döndürmeye çalışır, ancak hiçbir şeye atanmaz.
Bu, aşağıdakiler gibi birçok yaygın çaylak hatasına neden olur:
inputText.Replace(" ", "%20");
Yine, hiçbir şey olmuyor, bunun yerine yapmanız gerekenler:
inputText = inputText.Replace(" ","%20");
Şimdi, dizelerin değişmez olduğunu anlarsanız, bu çok mantıklıdır. Eğer yapmazsan, o zaman kafan karışır. İçin uygun bir yer Replace()
nerede olacağını format()
ise statik yöntemi olarak, String
:
inputText = String.Replace(inputText, " ", "%20");
Şimdi neler olduğu hakkında bir soru yok.
Asıl soru şu ki, bu çerçevelerin yazarları neden birinin örnek yöntem ve diğerinin statik olması gerektiğine karar verdiler? Bence, her ikisi de statik yöntemler olarak daha zarif bir şekilde ifade ediliyor.
Fikriniz ne olursa olsun, gerçek şu ki, statik sürümü kullanarak hata yapmaya daha az eğilimlisiniz ve kodun anlaşılması daha kolay (Gizli Gotchas yok).
Tabii ki örnek yöntemler olarak mükemmel olan bazı yöntemler vardır, String.Length ()
int length = "123".Length();
Bu durumda, "123" ü değiştirmeye çalışmadığımız açıktır, sadece inceliyoruz ve uzunluğunu döndürüyoruz. Bu, bir örnek yöntemi için mükemmel bir adaydır.
Değişken Nesneler Üzerindeki Örnek Yöntemleri için basit kurallarım:
Her iki çözüm de printf'i simüle etmek için çalışır, ancak farklı bir şekilde. Örneğin, bir değeri onaltılı bir dizeye dönüştürmek için aşağıdaki 2 çözüme sahip olursunuz:
ile format()
, en yakın 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;
}
ile replace(char oldchar , char newchar)
biraz daha hızlı ama oldukça sınırlı:
...
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)));
...
Aşağıdaki gibi sadece karakterleri ret
tek tek eklemekten oluşan üçüncü bir çözüm var (karakter birbirine eklenen sayılardır !):
...
ret += HexChars.charAt((int) ((v >> 12) & 0x0f)));
ret += HexChars.charAt((int) ((v >> 8) & 0x0f)));
...
... ama bu gerçekten çirkin olurdu .
PrintStream ile bir OutputStream olan herhangi bir şeye printf yapabilirsiniz. Her nasılsa, bir dize akışına yazdırmak:
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();
Dize akışı şu ByteArrayOutputStream gibi oluşturulabilir:
ByteArrayOutputStream baos = new ByteArrayOutputStream();