168

指定された文字の指定された数で文字列を作成するJavaで方法はありますか? 私の場合、10 個のスペースを含む文字列を作成する必要があります。私の現在のコードは次のとおりです。

StringBuffer outputBuffer = new StringBuffer(length);
for (int i = 0; i < length; i++){
   outputBuffer.append(" ");
}
return outputBuffer.toString();

同じことを達成するためのより良い方法はありますか。特に、(実行に関して)速いものが欲しいです。

4

27 に答える 27

182

StringおそらくAPIを使用した最短のコードです。

String space10 = new String(new char[10]).replace('\0', ' ');

System.out.println("[" + space10 + "]");
// prints "[          ]"

メソッドとして、直接インスタンス化せずにchar:

import java.nio.CharBuffer;

/**
 * Creates a string of spaces that is 'spaces' spaces long.
 *
 * @param spaces The number of spaces to add to the string.
 */
public String spaces( int spaces ) {
  return CharBuffer.allocate( spaces ).toString().replace( '\0', ' ' );
}

次を使用して呼び出します。

System.out.printf( "[%s]%n", spaces( 10 ) );
于 2010-05-11T02:35:15.350 に答える
80

ループを手で書かないことを強くお勧めします。プログラミングのキャリアの過程で、これを何度も繰り返します。あなたのコードを読んでいる人 (あなたを含む) は、ループの意味を理解するために、ほんの数秒であっても常に時間を費やす必要があります。

代わりに、Apache Commons Langのようなコードを提供する利用可能なライブラリの 1 つを再利用します。StringUtils.repeat

StringUtils.repeat(' ', length);

そうすれば、パフォーマンスについても気にする必要がないためStringBuilder、コンパイラの最適化などのすべての厄介な詳細が隠されます。関数が遅くなる場合は、ライブラリのバグです。

Java 11ではさらに簡単になります。

" ".repeat(length);
于 2014-07-30T20:51:47.430 に答える
71

うーん、今考えてみると、多分Arrays.fill:

char[] charArray = new char[length];
Arrays.fill(charArray, ' ');
String str = new String(charArray);

もちろん、fillメソッドはコードと同じことを行うと想定しているため、おそらくほぼ同じように実行されますが、少なくともこれは行数が少ない.

于 2010-05-10T17:26:45.093 に答える
40

for ループはコンパイラによって最適化されます。あなたのような場合、自分で最適化を気にする必要はありません。コンパイラを信頼してください。

ところで、n 個の空白文字を含む文字列を作成する方法があれば、先ほどと同じ方法でコード化されます。

于 2010-05-10T17:25:11.930 に答える
13

スペースのみが必要な場合は、次のようにします。

String spaces = (n==0)?"":String.format("%"+n+"s", "");

abs(n) スペースになります。

于 2012-08-15T10:37:19.803 に答える
12

Java 11以降String.repeat(count)、問題を解決するために簡単に使用できます。

この文字列を繰り返し連結した値を持つ文字列を返しますcount

この文字列が空またはcountゼロの場合、空の文字列が返されます。

したがって、ループの代わりに、コードは次のようになります。

" ".repeat(length);
于 2019-06-07T10:12:29.527 に答える
8

これは可能な限り少ないコードだと思います.Guava Joinerクラスを使用しています:

Joiner .on("").join( Collections.nCopies (10, " "));

于 2014-02-13T17:41:55.600 に答える
6

高速累乗のアルゴリズムに基づく私の貢献。

/**
 * Repeats the given {@link String} n times.
 * 
 * @param str
 *            the {@link String} to repeat.
 * @param n
 *            the repetition count.
 * @throws IllegalArgumentException
 *             when the given repetition count is smaller than zero.
 * @return the given {@link String} repeated n times.
 */
public static String repeat(String str, int n) {
    if (n < 0)
        throw new IllegalArgumentException(
                "the given repetition count is smaller than zero!");
    else if (n == 0)
        return "";
    else if (n == 1)
        return str;
    else if (n % 2 == 0) {
        String s = repeat(str, n / 2);
        return s.concat(s);
    } else
        return str.concat(repeat(str, n - 1));
}

このアルゴリズムを他の 2 つのアプローチに対してテストしました。

  • String.concat()文字列の連結に使用する通常の for ループ
  • を使用した通常の for ループStringBuilder

テストコード( for ループを使用した連結でString.concat()、 large の場合は遅くなるためn、5回目の繰り返しで省略しました)。

/**
 * Test the string concatenation operation.
 * 
 * @param args
 */
public static void main(String[] args) {
    long startTime;
    String str = " ";

    int n = 1;
    for (int j = 0; j < 9; ++j) {
        n *= 10;
        System.out.format("Performing test with n=%d\n", n);

        startTime = System.currentTimeMillis();
        StringUtil.repeat(str, n);
        System.out
                .format("\tStringUtil.repeat() concatenation performed in    %d milliseconds\n",
                        System.currentTimeMillis() - startTime);

        if (j <5) {
            startTime = System.currentTimeMillis();
            String string = "";
            for (int i = 0; i < n; ++i)
                string = string.concat(str);
            System.out
                    .format("\tString.concat() concatenation performed in        %d milliseconds\n",
                            System.currentTimeMillis() - startTime);
        } else
            System.out
                    .format("\tString.concat() concatenation performed in        x milliseconds\n");
        startTime = System.currentTimeMillis();
        StringBuilder b = new StringBuilder();
        for (int i = 0; i < n; ++i)
            b.append(str);
        b.toString();
        System.out
                .format("\tStringBuilder.append() concatenation performed in %d milliseconds\n",
                        System.currentTimeMillis() - startTime);
    }
}

結果:

Performing test with n=10
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        0 milliseconds
    StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=100
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        1 milliseconds
    StringBuilder.append() concatenation performed in 0 milliseconds
Performing test with n=1000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        1 milliseconds
    StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=10000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        43 milliseconds
    StringBuilder.append() concatenation performed in 5 milliseconds
Performing test with n=100000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        1579 milliseconds
    StringBuilder.append() concatenation performed in 1 milliseconds
Performing test with n=1000000
    StringUtil.repeat() concatenation performed in    0 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 10 milliseconds
Performing test with n=10000000
    StringUtil.repeat() concatenation performed in    7 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 112 milliseconds
Performing test with n=100000000
    StringUtil.repeat() concatenation performed in    80 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 1107 milliseconds
Performing test with n=1000000000
    StringUtil.repeat() concatenation performed in    1372 milliseconds
    String.concat() concatenation performed in        x milliseconds
    StringBuilder.append() concatenation performed in 12125 milliseconds

結論:

  • 大規模な場合n- 再帰的アプローチを使用
  • 小さい場合n- for ループには十分な速度があります
于 2015-01-06T10:23:22.123 に答える
4

私たちが持っていることを考えると:

String c = "c"; // character to repeat, for empty it would be " ";
int n = 4; // number of times to repeat
String EMPTY_STRING = ""; // empty string (can be put in utility class)

Java 8 (ストリームを使用)

String resultOne = IntStream.range(0,n)
   .mapToObj(i->c).collect(Collectors.joining(EMPTY_STRING)); // cccc

Java 8 (nCopy を使用)

String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc
于 2018-08-20T07:17:34.457 に答える
4

これはどう?

char[] bytes = new char[length];
Arrays.fill(bytes, ' ');
String str = new String(bytes);
于 2010-05-10T18:31:06.377 に答える
2

StringUtils を使用: StringUtils.repeat(' ', 10)

于 2019-02-07T16:06:37.507 に答える
1

ほとんどの場合、必要な文字列は特定の長さ、たとえば100スペースまでです。インデックス番号がスペースで埋められた文字列のサイズと等しい文字列の配列を準備し、必要な長さが制限内にある場合は文字列を検索し、境界外にある場合はオンデマンドで作成できます。

于 2010-05-10T18:15:51.637 に答える
1

優れたパフォーマンスを得るには、 aznilamirからの回答とFrustratedWithFormsDesignerからの回答を組み合わせてください

private static final String BLANKS = "                       ";
private static String getBlankLine( int length )
{
    if( length <= BLANKS.length() )
    {
        return BLANKS.substring( 0, length );
    }
    else
    {
        char[] array = new char[ length ];
        Arrays.fill( array, ' ' );
        return new String( array );
    }
}

BLANKS要件に応じて のサイズを調整します。私の特定のBLANKS文字列の長さは約200文字です。

于 2014-04-25T16:52:38.743 に答える
0

StringBuffer をStringBuilderに置き換えるだけです。それを打ち負かすのは難しい。

長さが大きな数値の場合は、反復ごとに長さを複製して、より効率的な (ただし、より不器用な) 自己追加を実装することができます。

 public static String dummyString(char c, int len) {
  if( len < 1 ) return "";
  StringBuilder sb = new StringBuilder(len).append(c);
  int remnant = len - sb.length();
  while(remnant  > 0) {
   if( remnant  >= sb.length() ) sb.append(sb);
   else sb.append(sb.subSequence(0, remnant));
   remnant  = len - sb.length();
  }
  return sb.toString();
 }

また、アプローチを試すこともできますArrays.fill()( FrustratedWithFormsDesignerの回答)。

于 2010-05-10T17:39:11.670 に答える
0

このような方法があります。これは、指定された長さを特定の長さにStringするために、指定されたの末尾に必要なスペースを追加します。String

public static String fillSpaces (String str) {

    // the spaces string should contain spaces exceeding the max needed
    String spaces = "                                                   ";
    return str + spaces.substring(str.length());
}
于 2014-08-08T19:42:41.157 に答える
0

に置き換えることができますStringBuffer(StringBuilder後者は同期されません。シングル スレッド アプリの方が速い場合があります)。

また、StringBuilder必要になるたびにインスタンスを作成するのではなく、インスタンスを 1 回作成することができます。

このようなもの:

class BuildString {
     private final StringBuilder builder = new StringBuilder();
     public String stringOf( char c , int times ) {

         for( int i = 0 ; i < times ; i++  ) {
             builder.append( c );
         }
         String result = builder.toString();
         builder.delete( 0 , builder.length() -1 );
         return result;
      }

  }

そして、次のように使用します。

 BuildString createA = new BuildString();
 String empty = createA.stringOf( ' ', 10 );

createAインスタンス変数として保持すると、インスタンスを作成する時間を節約できます。

これはスレッドセーフではありません。マルチスレッドがある場合、各スレッドには独自のコピーが必要です。

于 2010-05-10T17:48:07.773 に答える
-1

以下のような簡単な方法も使用できます

public static String padString(String str, int leng,char chr) {
        for (int i = str.length(); i <= leng; i++)
            str += chr;
        return str;
    }
于 2013-03-21T18:11:21.383 に答える
-2

これはどう?

public String fillSpaces(int len) {
    /* the spaces string should contain spaces exceeding the max needed */  
    String spaces = "                                                   ";
    return spaces.substring(0,len);
}

編集:私は概念をテストするための簡単なコードを書きました。ここに私が見つけたものがあります。

方法 1: ループ内に単一のスペースを追加する:

  public String execLoopSingleSpace(int len){
    StringBuilder sb = new StringBuilder();

    for(int i=0; i < len; i++) {
        sb.append(' ');
    }

    return sb.toString();
  }

方法 2: 100 個のスペースを追加してループし、部分文字列:

  public String execLoopHundredSpaces(int len){
    StringBuilder sb = new StringBuilder("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ");

    for (int i=0; i < len/100 ; i++) {
        sb.append("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ")
            .append("          ").append("          ").append("          ");
    }

    return sb.toString().substring(0,len);
  }

12,345,678 個のスペースを作成した結果:

C:\docs\Projects> java FillSpace 12345678
method 1: append single spaces for 12345678 times. Time taken is **234ms**. Length of String is 12345678
method 2: append 100 spaces for 123456 times. Time taken is **141ms**. Length of String is 12345678
Process java exited with code 0

10,000,000 スペースの場合:

C:\docs\Projects> java FillSpace 10000000
method 1: append single spaces for 10000000 times. Time taken is **157ms**. Length of String is 10000000
method 2: append 100 spaces for 100000 times. Time taken is **109ms**. Length of String is 10000000
Process java exited with code 0

直接割り当てと反復を組み合わせると、常に時間が短縮され、巨大なスペースを作成する場合は平均で 60 ミリ秒短縮されます。サイズが小さい場合、どちらの結果も無視できます。

しかし、引き続きコメントしてください:-)

于 2012-04-03T08:34:44.257 に答える
-3

あなたが求めていることに対する組み込みの方法はありません。ただし、10 のような小さな固定長の場合、メソッドは十分に高速になるはずです。

于 2010-05-10T17:25:44.130 に答える