代码之家  ›  专栏  ›  技术社区  ›  paperhorse

爪哇的S喷雾肥当量

  •  265
  • paperhorse  · 技术社区  · 17 年前

    PrpTF在1.5版本中添加到Java中,但我似乎找不到如何将输出发送到字符串而不是文件(这是SCAFTF在C中做的)。有人知道怎么做吗?

    3 回复  |  直到 11 年前
        1
  •  449
  •   Dave Jarvis James Eichele    11 年前
    // 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

        2
  •  23
  •   FlySwat    17 年前

    @埃里克森。

    字符串是不可变的类型。您不能修改它们,只能返回新的字符串实例。

    因此,“foo.format()毫无意义,因为它必须像这样调用

    string newString = "foo".format();
    

    原来的Java作者(和.NET作者)决定了静态方法在这种情况下更有意义,因为您不修改“FO”,而是调用一种格式方法并传入一个输入字符串。

    编辑 :呵呵,这个网站有时候很有趣。我因为提到字符串是不可变类型而被否决了。

    下面是一个例子,说明为什么format()作为一个实例方法是哑的。在.NET中(也可能是在Java中),ReSet()是一个实例方法。

    您可以这样做:

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

    但是,不会发生任何事情,因为字符串是不可变的。replace尝试返回一个新字符串,但它未分配给任何对象。

    这会导致很多新手常见的错误,比如:

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

    同样,什么也不会发生,相反,你必须做:

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

    现在,如果你理解字符串是不可变的,那就完全有道理了。如果你不这样做,那你就是困惑了。作为字符串的静态方法,替换的正确位置应该是格式所在的位置:

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

    现在没有问题了。

    真正的问题是,为什么这些框架的作者决定一个应该是实例方法,另一个应该是静态的?在我看来,两者都更优雅地表示为静态方法,但埃里克森似乎认为两者都属于实例方法。

    不管您的意见如何,事实是您不太容易使用静态版本犯错误,代码更容易理解(没有隐藏的gotchas)。

    当然,有一些方法非常适合作为实例方法,比如string.length()。

    int length = "123".Length();
    

    在这种情况下,很明显我们没有试图修改“123”,我们只是检查它,并返回它的长度……这是一个实例方法的完美候选者。

    我的简单规则,例如不可变对象上的方法:

    • 如果需要返回相同类型的新实例,请使用静态方法。
    • 否则,请使用实例方法。
        3
  •  2
  •   догонят    11 年前

    这两种解决方案都可以模拟printf,但方式不同。 例如,要将值转换为十六进制字符串,您有以下两种解决方案:

    • 具有 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添加到 ret 一个接一个(char是 互相补充 !)如:

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

    …但那是 真的? 丑陋的