2012-05-17 29 views
1

我必須生成一個包含一個類的所有數據成員的單個字符串。例如,如果一個類定義快速添加空白字符串的方法。

class A  
{ 
    private String field1; 
    private String field2; 
    private String field3; 
    ... 
    ... 
} 

然後我想生成包含字段1,依次場2和字段3的字符串。然而,我想要做的事情更多的是確保以下規則 -

field1 is of length 20. If it is less than 20, pad it with blank spaces. 
    field2 is of length 10. If it is less than 10, pad it with blank spaces. 
    field1 is of length 15. If it is less than 15, pad it with blank spaces. 
    ... 
    ... 

我打算使用一個輔助類來建立這個字符串。我想使用一個StringBuilder來獲取最終的字符串。所以我有類似的東西 -

StringBuilder builder = new StringBuilder(); 

    Helper.addString(field1,20,builder); 

現在這個addString函數的實現是我所關心的。對於不同的類,這個函數將被調用數千次。所以我想盡可能提高效率。問題是,什麼是最有效的方法?目前,我有以下實現 -

public static void addString(String field, int totalLengthOfField, StringBuilder builder) 
{ 
    int lengthOfField = field.length(); 
    int numberOfBlankSpacesToPutAfterString = totalLengthOfField - lengthOfField; 

    if(numberOfBlankSpacesToPutAfterString >=0) 
     { 
     builder.append(field); 
     for(int i=1; i<= numberOfBlankSpacesToPutAfterString; i++) 
      { 
      builder.append(" "); // append a blank space 
      } 
     } 
    else 
     { 
     // throw exception - field is longer than the maximum allowed length. 
     } 
} 
+0

什麼是正在引起你的關注性能測量? – Jeremy

+0

@JeremyHeiler,我只是想讓它運行得儘可能快。 – CodeBlue

+0

我猜想花費一堆空格的子字符串比追加循環要快,但是沒有任何時間數據,我不會依賴直覺。你知道你有性能問題嗎? –

回答

4

Java有Formatter類支持與特定的字段寬度定義來創建字符串,很像C. String.format()sprintf()還採用了Formatter對象內部。

也就是說,Formatter並不是那麼快。你可能會更好的將字符串手動附加到StringBuilder,並使用具有不同數量空格的字符串的小緩存,以避免總是附加單個空格...

例如,如果您知道填充大小將始終爲少於20個空格,您可以創建一個String[]表,其中包含0,1,2 ...空格的字符串,並完全跳過循環。如果沒有這樣的限制,你仍然可以追加20個空格塊,直到你達到必要的填充尺寸。

+0

這是一個很好的建議。 – CodeBlue

+0

格式可能會很沉重,看看http://stackoverflow.com/questions/513600/should-i-use-javas-string-format-if-performance-is-important也許是一個好主意,使一個基準 –

0

任何不使用的原因String.format

+0

'String.format'我覺得很慢。 – Kai

+1

你知道什麼,你是對的。 [這裏](http://stackoverflow.com/questions/513600/should-i-use-javas-string-format-if-performance-is-important)是另一個帶有數字的SO問題來支持它。 – Matt

+0

@Matt現在如果只有那個基準測試真的有效:)那麼除非你對解釋器的性能感興趣,在這種情況下 - 這是一個很好的測試。 – Voo

0

使用靜態方法

String.format("%"+numberOfBlankSpacesToPutAfterString+"s",string)' 
0

我可以看到至少一個優化。變化:

if(numberOfBlankSpacesToPutAfterString >=0) 

要:

if(numberOfBlankSpacesToPutAfterString >0) 

這樣,如果你有0位加你永遠不會進入for循環。不是一個大問題,但它聽起來像是每一點點重要。

第二件事:建設者對象是否需要?你可以使用

if(numberOfBlankSpacesToPutAfterString >0) 
    { 
    for(int i=1; i<= numberOfBlankSpacesToPutAfterString; i++) 
     { 
     field +=(" "); // append a blank space 
     } 
    } 

讀什麼別人提到的,你可以通過添加2

if(numberspaces > 16) 
     {field +="16spaceshere" 
     numberspaces -= 16; 
     } 
if(numberspaces > 8)... 
if(numberspaces > 4)... 

權力的間距進一步加快速度,這將變成場上最多4個操作數字空間加4,共8個。

+0

但是,然後我的其他條件將需要再次測試== 0之前拋出一個異常。 – CodeBlue

+0

對於字符串循環中的''+ ='是* slow *。每個調用都會創建一個新的StringBuilder對象... – thkala

+0

如果沒有構建器,實際上會在內存中創建更多的字符串。 – CodeBlue

0

考慮到檢查如何阿帕奇百科全書(StringUtils的)來實現,他們已經擁有了如您有和他們已經優化的方法相同的問題:

public static String rightPad(String str, int size, char padChar) { 
    if (str == null) { 
     return null; 
    } 
    int pads = size - str.length(); 
    if (pads <= 0) { 
     return str; // returns original String when possible 
    } 
    if (pads > PAD_LIMIT) { 
     return rightPad(str, size, String.valueOf(padChar)); 
    } 
    return str.concat(repeat(padChar, pads)); 
} 

public static String repeat(String str, int repeat) { 
    // Performance tuned for 2.0 (JDK1.4) 

    if (str == null) { 
     return null; 
    } 
    if (repeat <= 0) { 
     return EMPTY; 
    } 
    int inputLength = str.length(); 
    if (repeat == 1 || inputLength == 0) { 
     return str; 
    } 
    if (inputLength == 1 && repeat <= PAD_LIMIT) { 
     return repeat(str.charAt(0), repeat); 
    } 

    int outputLength = inputLength * repeat; 
    switch (inputLength) { 
     case 1 : 
      return repeat(str.charAt(0), repeat); 
     case 2 : 
      char ch0 = str.charAt(0); 
      char ch1 = str.charAt(1); 
      char[] output2 = new char[outputLength]; 
      for (int i = repeat * 2 - 2; i >= 0; i--, i--) { 
       output2[i] = ch0; 
       output2[i + 1] = ch1; 
      } 
      return new String(output2); 
     default : 
      StringBuilder buf = new StringBuilder(outputLength); 
      for (int i = 0; i < repeat; i++) { 
       buf.append(str); 
      } 
      return buf.toString(); 
    } 
} 
0

只要你知道最大填充你需要(20)這很簡單。

private static String spaces = "     "; // Whatever you need max! 

// your code to compute numberOfBlankSpacesToPutAfterString 

if(numberOfBlankSpacesToPutAfterString >= 0) { 
    builder.append(field); 
    builder.append(spaces, 0, numberOfBlankSpacesToPutAfterString); 
} else { 
    // Report error 
} 
0
import com.google.common.base.Strings 

foo = Strings.repeat(" ", 10)