2013-09-11 53 views
1

這裏是我的Java編碼嘗試覆蓋toString來整齊地格式化輸出。toString覆蓋使用StringBuilder的特定tab的格式

@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」是否會按照我希望的方式均勻分配輸出。

+0

你試過在每個追加之間追加(「\ t」)嗎? –

+0

哪個施特勞斯是「布奇」? – ajb

+0

@ajb:別告訴我你不知道施特勞斯?他是理查德的鄉下兄弟。 –

回答

2

我會將StringBuilder包裝在格式化程序中,並使用格式字符串一次添加所有字段。

例如...

@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模板中的字符串爲好,但我覺得它更符合邏輯和安全只使用數字與格式說明。如果單個屬性的字符串長度存在重大變化,則製表可能會失敗。這些數字甚至可以是包含數字的變量,然後將這些數字轉換爲模板字符串中的字符串表示形式。

代碼和數字只是一個粗略的估計,將不得不改變,但希望你明白了。


編輯
幽州的評論:

這一個看起來像它會在所有類別的進入幾乎任何長度的工作,但是你能不能給我解釋一下格式化是什麼在做什麼?它只是在我的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 
+0

現在我讀了你的答案,比我的哈哈哈乾淨得多,看起來不錯。 – unmultimedio

+0

這個看起來像它可以適用於所有類別的任意長度的輸入,但是您能否向我解釋Formatter正在做什麼?它只是在我的return語句中替換String.format調用? – cupojava

+0

@cupojava:請參閱編輯以回答。 –

0

我會做它只是串聯的標籤,所以它會是這樣的:

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

    return sb; 
} 

我知道是不是那麼幹淨,但它應該工作。

+0

如果從特定字段返回的任何字符串具有各種各樣的長度,則這將失敗。 –

+0

是真的,儘管'firstName'字段應該是有限的,對嗎?這只是尋找適當數量的選項卡來連接的問題。 – unmultimedio

+1

不,使用更多選項卡將不起作用。如果最大字符串與任何單個屬性的最小字符串之間的差異> =製表符寬度,則無論使用多少個製表符,您的建議都會失敗。 –