Java における Sprintf に相当するもの
-
09-06-2019 - |
質問
Printf は 1.5 リリースで Java に追加されましたが、出力をファイルではなく文字列に送信する方法が見つからないようです (これは C の sprintf が行うことです)。誰かこれを行う方法を知っていますか?
他のヒント
@エリクソン。
文字列は不変型です。それらを変更することはできません。新しい文字列インスタンスのみが返されます。
そのため、「foo」.format() は次のように呼び出す必要があるため、ほとんど意味がありません。
string newString = "foo".format();
オリジナルの Java 作成者 (および .NET 作成者) は、「foo」を変更するのではなく、代わりに format メソッドを呼び出して入力文字列を渡すため、この状況では静的メソッドの方が合理的であると判断しました。
編集:へー、このサイトは時々とても面白いですよ。文字列は不変型であるという事実について言及したため、反対票を投じられました。
以下に、Format() がインスタンス メソッドとして機能しない理由の例を示します。.NET (およびおそらく Java) では、Replace() はインスタンス メソッドです。
あなたはこれを行うことができます:
"I Like Wine".Replace("Wine","Beer");
ただし、文字列は不変であるため、何も起こりません。Replace は新しい文字列を返そうとしますが、その文字列は何も割り当てられません。
これにより、次のようなよくある初歩的な間違いが多く発生します。
// Contrived Example
inputText.Replace(" ","%20");
繰り返しますが、何も起こらず、代わりに次のことを行う必要があります。
inputText = inputText.Replace(" ","%20");
文字列が不変であることを理解していれば、それは完全に理にかなっています。そうしないと、ただ混乱するだけです。Replace の適切な場所は、String の静的メソッドとして Format がある場所になります。
inputText = String.Replace(inputText," ", "%20");
さて、何が起こっているのかについては疑問の余地はありません。
本当の疑問は、なぜこれらのフレームワークの作成者が一方をインスタンス メソッドにし、もう一方を静的メソッドにすることに決めたのかということです。私の意見では、どちらも静的メソッドとしてよりエレガントに表現されていますが、エリクソン氏はどちらもインスタンス メソッドに属すると考えているようです。
あなたの意見はともかく、実際のところ、静的バージョンを使用すると間違いが起こりにくくなり、コードが理解しやすくなります (隠れた落とし穴がない)。
もちろん、インスタンス メソッドとして最適なメソッドもいくつかあります。たとえば String.Length() です。
int length = "123".Length();
この状況では、「123」を変更しようとしているわけではなく、単にそれを検査してその長さを返しているだけであることは明らかです。これはインスタンス メソッドの完璧な候補です。
不変オブジェクトのインスタンス メソッドに関する私の簡単なルール:
- 同じ型の新しいインスタンスを返す必要がある場合は、静的メソッドを使用します。
- それ以外の場合は、インスタンス メソッドを使用します。
どちらのソリューションも printf をシミュレートするために機能しますが、方法が異なります。たとえば、値を 16 進文字列に変換するには、次の 2 つの解決策があります。
と
format()
, に最も近い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; }
と
replace(char oldchar , char newchar)
, 、多少高速ですがかなり制限があります:... 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))); ...
にcharを追加するだけで構成される3番目の解決策があります。
ret
1 つずつ (char は、 お互いに追加し合う!) 次のように:... ret += HexChars.charAt((int) ((v >> 12) & 0x0f))); ret += HexChars.charAt((int) ((v >> 8) & 0x0f))); ...
...でもそれはそうなるだろう 本当に 醜い。