1

クラスのすべてのデータメンバーを含む単一の文字列を生成する必要があります。たとえば、クラス定義が

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

次に、field1、field2、field3をこの順序で含む文字列を生成します。ただし、私がやりたい追加のことは、次のルールを確認することです-

  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.
      }
 }
4

7 に答える 7

4

Javaには、CのFormatter場合と同様に、特定のフィールドの幅を定義した文字列の作成をサポートするクラスがあります。これも内部でオブジェクトを使用します。sprintf()String.format()Formatter

とはいえ、Formatterそれほど速くはありません。StringBuilder常に単一のスペースを追加することを避けるために、文字列を手動で追加し、さまざまな数のスペースを持つ文字列の小さなキャッシュを使用する方がよい場合があります。

たとえば、パディングサイズが常に20スペース未満であることがわかっている場合は、String[]0、1、2 ...のスペースを持つ文字列を使用してテーブルを作成し、ループを完全にスキップできます。そのような制限がない場合でも、必要なパディングサイズに達するまで、たとえば20スペースのブロックを一度に追加できます。

于 2012-05-17T17:50:10.783 に答える
0

使用しない理由はありますString.formatか?

于 2012-05-17T17:49:32.050 に答える
0

静的メソッドを使用する

String.format("%"+numberOfBlankSpacesToPutAfterString+"s",string)'
于 2012-05-17T17:49:36.280 に答える
0

少なくとも1つの最適化を見ることができます。変化する:

 if(numberOfBlankSpacesToPutAfterString >=0)

に:

 if(numberOfBlankSpacesToPutAfterString >0)

そうすれば、追加するスペースが0の場合、forループに入ることがありません。大したことではありませんが、少しでも重要なようです。

2番目のこと:ビルダーオブジェクトは必要ですか?あなたが使用している可能性があります

 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つの操作になります。

于 2012-05-17T17:51:09.620 に答える
0

Apache Commons(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();
    }
}
于 2012-05-17T17:59:10.327 に答える
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
}
于 2012-05-17T18:02:22.573 に答える
0
import  com.google.common.base.Strings

foo = Strings.repeat(" ", 10)
于 2017-11-01T16:45:54.443 に答える