web-dev-qa-db-ja.com

n文字の文字列を作成します

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

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

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

119
C. Ross

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

編集:ところで、n個のスペース文字を含む文字列を作成する方法がある場合は、ちょうどあなたがやったのと同じ方法でコーディングされています。

35
kalkin

おそらくString AP​​Iを使用した最短のコード。

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 ) );
154

うーん、私はそれについて考えているので、多分 Arrays.fill

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

もちろん、fillメソッドはコードと同じことを行うため、おそらくほぼ同じパフォーマンスを発揮しますが、少なくともこれは少ない行です。

ループを手書きで書かないことを強くお勧めします。あなたはあなたのプログラミングのキャリアの中で何度もそれを繰り返します。あなたを含むあなたのコードを読んでいる人々は、たとえほんの数秒であっても、ループの意味を消化するために常に時間を費やさなければなりません。

代わりにreuseStringUtils.repeatfromのようなコードを提供する利用可能なライブラリの1つ Apache Commons Lang

StringUtils.repeat(' ', length);

そうすれば、パフォーマンスを気にする必要もありません。したがって、StringBuilderやコンパイラの最適化などの詳細はすべて隠されます。関数が遅いと判明した場合、ライブラリのバグになります。

Java 11 を使用すると、さらに簡単になります。

" ".repeat(length);
56
mfuchs

Java 8では、String.joinを使用できます。

String.join("", Collections.nCopies(n, s));
22

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

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

その結果、abs(n)スペースが発生します。

12
BryceCicada

私はこれが可能な限り少ないコードだと思う、それはグアバジョイナークラスを使用します:

Joiner 。on( "")。join( Collections.nCopies (10、 ""));

8
meilechh

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

/**
 * 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ループ
  • StringBuilderを使用した通常のforループ

テストコード(forループとString.concat()を使用した連結は、大きな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の場合-再帰的アプローチを使用します
  • For small n-forループには十分な速度があります
5
Niels Billen

N個のスペースを生成するには、標準のString.format関数を使用できます。例えば:

String.format("%5c", ' ');

5つのスペースで文字列を作成します。

または

int count = 15;
String fifteenSpacebars = String.format("%" + count + "c", ' ');

15個のスペースバーの文字列を作成します。

別のシンボルを繰り返したい場合は、スペースを目的のシンボルに置き換える必要があります。

int count = 7;
char mySymbol = '#';
System.out.println(String.format("%" + count + "c", ' ').replaceAll("\\ ", "\\" + mySymbol));

出力:

#######
4
Alexey Gusev

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

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(nCopiesを使用)

String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc
4
i_am_zero

これはどう?

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

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

2
Icegras

RandomStringUtils には、指定された入力サイズから文字列を作成する機能があります。カントは速度についてコメントしますが、それはライナーです。

RandomStringUtils.random(5,"\t");

出力を作成します

\ t\t\t\t\t

コードで\ 0を見たくない場合に望ましい。

2
Mulki

Java 11以降では、単に String.repeat(count) を使用して問題を解決できます。

値がcount回繰り返されたこの文字列の連結である文字列を返します。

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

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

" ".repeat(length);
1
Samuel Philipp

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

1
Andreas_D

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

また、必要なたびに作成する代わりに、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をインスタンス変数として保持すると、インスタンスの作成にかかる時間を節約できます。

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

0
OscarRyz

良好なパフォーマンスを得るには、 aznilamirFrustratedWithFormsDesigner の回答を組み合わせてください

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文字の長さです。

0
olibre
Stream.generate(() -> ch).limit(n).collect(joining());

どこ:

import static Java.util.stream.Collectors.joining;
import Java.util.stream.Stream;
...

  String ch = " ";
  int n = 10;

  Stream
      .generate(() -> ch)
      .limit(n)
      .collect(joining());
0
epox

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の答え)を試すこともできます。

0
leonbloy

このような方法があります。これにより、特定の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());
}
0
Anil