2008-09-05 11 views
245

Printfは1.5リリースでJavaに追加されましたが、ファイルではなく文字列に出力を送信する方法を見つけることができません(これはsprintfがC言語で行うものです)。誰もこれを行う方法を知っていますか?JavaのSprintf相当ファイル

答えて

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

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

formatとそのsyntax

22

@ericksonを参照してください。

文字列は不変型です。それらを変更することはできず、新しい文字列インスタンスのみを返します。それは

string newString = "foo".format(); 

元のJava著者(および.NET著者)のように呼ばれなければならないとして、そのための

は、「foo」という.format()は、ほとんど意味がない、という静的メソッドを決めましたこのような状況では、 "foo"を変更するのではなく、代わりにフォーマットメソッドを呼び出して入力文字列を渡すようになりました。

EDIT:このサイトはとても面白いかもしれません。私は文字列が不変型であるという事実に言及するために、下線を引いた。

ここでは、Format()がインスタンスメソッドとしてダムになる理由の例を示します。 .NET(そしておそらくJava)では、Replace()はインスタンスメソッドです。

あなたはこれを行うことができます。

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

は、しかし、何も起こりません、文字列は不変ですので。 Replaceは新しい文字列を返そうとしますが、何も割り当てられません。

これは、のような一般的な新人のミスがたくさん原因:あなたは、文字列は不変であることを理解していれば、それが作る、

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

を今:ここでも、何もあなたがしなければならない代わりに、起こりません

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

を完璧なセンス。あなたがしなければ、あなたはちょうど混乱しています。 Replaceの適切な場所は、Stringの静的メソッドとしてFormatがある場所です。

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

ここで何が起こっているかについて疑問はありません。

実際の質問は、なぜこれらのフレームワークの作者がインスタンスメソッドでなければならないと決定したのですか?私の意見では、どちらも静的メソッドとしてよりエレガントに表現されていますが、ericksonはインスタンスメソッドとして両方が属すると考えるようです。

あなたの意見にかかわらず、真実は静的バージョンを使用して間違いを起こす可能性が少なく、コードはわかりやすい(隠されていないこと)です。

もちろんのインスタンスメソッドとして最適ですいくつかの方法がある、(String.lengthですを取ることは)このような状況で

int length = "123".Length(); 

、我々はそれを検査し、「123」を変更しようとしていないのは明白、そしてその長さを返す...これは、インスタンスメソッドのための完全な候補です。不変オブジェクトのインスタンスメソッドのための

私の単純なルールは:

  • あなたは、同じタイプの新しいインスタンスを返すために必要がある場合は、静的メソッドを使用します。
  • それ以外の場合は、インスタンスメソッドを使用します。
+3

私は、あなたが何とかフォーマット文字列を修正することを提案しているという考えを持っていることが分かります。彼らの不変性はとても基本的なものなので、誰かが文字列を変更すると予想する可能性は考えられませんでした。 – erickson

+4

フォーマット文字列として見えるのは、通常、 "価格は%4d"であり、 "%4d"ではなく、私はまだ混乱の可能性が非常に高いです。あなたは静的メソッドに対して何を持っていますか? :) – FlySwat

+38

この答えは質問とは関係がないようです。 –

2

どちらのソリューションもprintfをシミュレートしますが、別の方法で動作します。やや高速ですが、かなり限られたreplace(char oldchar , char newchar)

final static String HexChars = "abcdef"; 

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; 
} 
  • 、:format()

    • 、最も近いsprintf()へ: たとえば、16進数文字列に値を変換するには、2次のソリューションを持っています:

      ... 
          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))); 
          ... 
      
    • 鼎一つret 1に文字などのように(チャーは互いにに追加という数字です!):

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

    ...それは、本当に醜いだろう。

  • +0

    すべての素晴らしいアイデアがありますが、コードを書き込み専用コードに変えて、あなたの同僚には理解できません。 – Ben