【问题标题】:toString override formatting with specific tabbing using StringBuildertoString 使用 StringBuilder 使用特定的制表符覆盖格式
【发布时间】:2013-09-11 00:25:05
【问题描述】:

这是我的 Java 编码尝试覆盖 toString 以整齐地格式化输出。

@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append(getEmpID())
.append(getLastName())
.append(getFirstName())
.append(getHours())
.append(getRate())
.append(getGross());

return String.format("%-58", sb.toString());

下面是输出的样子:

42345 Bruch      Max             40.00    21.50 $  860.00 

23456 Elgar      Eddie           43.00    20.00 $  890.00 

34567 Bach       John            30.00    30.00 $  900.00 

12345 Wagner     Rick            41.00    30.00 $ 1245.00 

88888 Mozart     Wolfie          36.00    40.00 $ 1440.00 

65432 Chopin     Fred            45.00    23.25 $ 1104.38 

72345 Strauss    Butch           50.00    25.00 $ 1375.00

我的问题是:有没有办法在 return 语句中放置特定附加的 \t 选项卡?

例如,与姓氏相比,工作时间比名字更远。

我不确定“%-58”是否会按照我想要的方式均匀分布输出。

【问题讨论】:

  • 你有没有在每次追加之间尝试append("\t")
  • 施特劳斯是“布奇”?
  • @ajb:别告诉我你不认识布奇·施特劳斯?他是理查德的乡巴佬兄弟。
  • 啊,是的,是歌剧《萨拉米香肠》的作者。我现在想起来了。

标签: java formatting tostring


【解决方案1】:

我会将 StringBuilder 包装在 Formatter 中,并使用格式字符串一次性添加所有字段。

例如...

@Override
public String toString() {
  StringBuilder stringBuilder = new StringBuilder();
  Formatter formatter = new Formatter(stringBuilder);

  String template = "%-7s %-15s %-15s %-35.2f %-5.2f $ %-8.2f"; // a rough guess!
  formatter.format(template, getEmpID(), getLastName(), getFirstName(), 
            getHours(), getRate(), getGross());
  return stringBuilder.toString();
}

您也可以将\t 放在模板字符串中,但我发现仅使用带有格式说明符的数字更合乎逻辑更安全。如果单个属性的字符串长度存在显着差异,则选项卡可能会失败。这些数字甚至可以是保存数字的变量,然后将其转换为模板字符串中的字符串表示形式。

代码和数字只是粗略估计,需要更改,但希望您能明白。


编辑
您在评论中声明:

这个看起来几乎适用于所有类别的任何长度的条目,但是你能向我解释一下 Formatter 在做什么吗?它只是替换了我的 return 语句中的 String.format 调用吗?

是的,事实上String.format(...) 可能在幕后使用了 java.util.Formatter 对象。有关详细信息,请查看 API。通过使用单个模板字符串将所有数据收集在一起,您可以为每个属性赋予其自己的格式大小、精度和说明符。

例如:

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;

public class FormatExample {
   public static void main(String[] args) {
      List<FormatExData> data = new ArrayList<>();
      data.add(new FormatExData("42345", "Max", "Bruch", 40, 21.5));
      data.add(new FormatExData("23456", "Eddie", "Elgar", 43, 20));
      data.add(new FormatExData("1111", "John", "Bach", 30, 30));
      data.add(new FormatExData("00001", "Donald", "Duck", 50, 40));
      data.add(new FormatExData("99999", "Mickey", "Mouse", 20, 15));
      data.add(new FormatExData("666", "Satan", "Mephistopheles", 100, 100));

      for (FormatExData datum : data) {
         System.out.println(datum);
      }
   }
}

class FormatExData {
   private String id;
   private String firstName;
   private String lastName;
   private double hours;
   private double rate;

   public FormatExData(String id, String firstName, String lastName,
         double hours, double rate) {
      this.id = id;
      this.firstName = firstName;
      this.lastName = lastName;
      this.hours = hours;
      this.rate = rate;
   }

   public String getId() {
      return id;
   }

   public String getFirstName() {
      return firstName;
   }

   public String getLastName() {
      return lastName;
   }

   public double getHours() {
      return hours;
   }

   public double getRate() {
      return rate;
   }

   public double getGross() {
      return hours * rate;
   }

   @Override
   public String toString() {
      NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
      StringBuilder stringBuilder = new StringBuilder();
      Formatter formatter = new Formatter(stringBuilder);
      String template = "%-7s %-15s %-10s %10.2f %10.2f %11s";
      formatter.format(template, getId(), getLastName(), getFirstName(),
            getHours(), getRate(), currencyFormat.format(getGross()));
      formatter.close();
      return stringBuilder.toString();
   }

}

哪个会返回:

42345   Bruch           Max             40.00      21.50     $860.00
23456   Elgar           Eddie           43.00      20.00     $860.00
1111    Bach            John            30.00      30.00     $900.00
00001   Duck            Donald          50.00      40.00   $2,000.00
99999   Mouse           Mickey          20.00      15.00     $300.00
666     Mephistopheles  Satan          100.00     100.00  $10,000.00

【讨论】:

  • 现在我看了你的回答,比我的干净多了哈哈哈,看起来不错。
  • 这个看起来几乎适用于所有类别的任何长度的条目,但是你能向我解释一下 Formatter 在做什么吗?它只是替换了我的 return 语句中的 String.format 调用吗?
【解决方案2】:

我会这样做只是连接标签,所以它会是这样的:

@Override
public String toString(){
    String sb = getEmpID() + "\t" + getLastName() + "\t\t" +
                getFirstName() + "\t\t\t" + getHours() + "\t" +
                getRate() + "\t" + getGross());

    return sb;
}

我知道不是那么干净,但它应该可以工作。

【讨论】:

  • 如果从特定字段返回的任何字符串具有多种长度,这将失败。
  • 是的,虽然 'firstName' 字段应该是有限的,对吗?只需找到合适数量的选项卡进行连接即可。
  • 不,使用更多标签将不起作用。如果任何单个属性的最大字符串和最小字符串之间的差异 >= 选项卡宽度,则无论使用多少选项卡,您的建议都会失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 2023-03-30
  • 1970-01-01
  • 2013-10-10
  • 2021-09-02
  • 2013-06-12
  • 1970-01-01
相关资源
最近更新 更多