java - toString 使用 StringBuilder 覆盖具有特定选项卡的格式

标签 java formatting tostring

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

@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
<小时/>

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

例如,与姓氏相比,工作时间的选项卡范围比名字远得多。

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

最佳答案

我会将 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 放入模板字符串中,但我发现仅使用带有格式说明符的数字更符合逻辑且更安全。如果单个属性的字符串长度存在显着变化,制表符可能会失败。这些数字甚至可以是保存数字的变量,然后将这些数字转换为模板字符串中的字符串表示形式。

代码和数字只是一个粗略的估计,必须更改,但希望您能明白。

<小时/>

编辑
您在评论中指出:

This one looks like it will work for pretty much any length of entry in all categories, however could you explain to me what Formatter is doing? is it just replacing the String.format call in my return statement?

是的,事实上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

关于java - toString 使用 StringBuilder 覆盖具有特定选项卡的格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18730828/

相关文章:

java - 交换单个字母单词的大小写

java - 在对象数组上设置监听器

java - 如何使 Joda 使用 String.format 方法(即 java.util.Formatter 类)?

javascript - 如何在javascript中将整数数组转换为十六进制字符串,反之亦然

java - "double Cannot be Dereferenced"toString() - 这种没有错误的替代形式是否意味着同样的事情?

javascript - Obj.toString() 既等于 false 又等于 true?

java - Joda Time - 重复/每周间隔

java - 在 python 和 java 中设置线程关联

c# - 自动格式化自动属性时忽略空格

php - PHP、HTML 和 CSS 的页面布局问题