web-dev-qa-db-fra.com

Créer une chaîne de n caractères

Existe-t-il un moyen en Java de créer une chaîne avec le nombre spécifié du caractère spécifié? Dans mon cas, il me faudrait créer une chaîne de 10 espaces. Mon code actuel est:

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

Y a-t-il une meilleure façon d'accomplir la même chose? En particulier, j'aimerais quelque chose de rapide (en termes d'exécution).

113
C. Ross

La boucle for sera optimisée par le compilateur. Dans de tels cas, comme le vôtre, vous n'avez pas besoin de vous soucier de l'optimisation par vous-même. Faites confiance au compilateur. :)

Edit: Btw s’il existe un moyen de créer une chaîne avec n caractères d’espace, elle est codée de la même manière que vous venez de le faire. 

34
kalkin

Probablement le code le plus court utilisant l'API String, exclusivement:

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

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

En tant que méthode, sans instancier directement 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', ' ' );
}

Invoquer en utilisant:

System.out.printf( "[%s]%n", spaces( 10 ) );
145

Hmm maintenant que j'y pense, peut-être Arrays.fill :

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

Bien entendu, je suppose que la méthode fill fait la même chose que votre code. Elle fonctionnera donc probablement de la même manière, mais au moins, cela fait moins de lignes.

Je suggère fortement de ne pas écrire la boucle à la main ... vous le ferez encore et encore au cours de votre carrière de programmeur ... les gens qui lisent votre code - qui vous comprend - doivent toujours investir du temps, ce ne sont que quelques secondes pour digérer le sens de la boucle.

Au lieu de cela, réutilise l’une des bibliothèques disponibles fournissant un code faisant exactement cela, comme StringUtils.repeatfrom Apache Commons Lang :

StringUtils.repeat(' ', length);

De cette façon, vous n'avez pas à vous soucier de la performance, ainsi tous les détails sanglants de StringBuilder, optimisations du compilateur, etc. sont masqués . Si la fonction s'avérait aussi lente, ce serait un bug de la bibliothèque.

Avec Java 11 cela devient encore plus facile:

" ".repeat(length);
51
mfuchs

En Java 8, vous pouvez utiliser String.join:

String.join("", Collections.nCopies(n, s));
21
Vitalii Fedorenko

Si vous ne voulez que des espaces, que diriez-vous de:

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

ce qui entraînera des espaces abs (n);

11
BryceCicada

Je pense que c'est le moins de code possible, il utilise la classe Guava Joiner: 

Joiner . On (""). Join ( Collections.nCopies (10, ""));

8
meilechh

Ma contribution basée sur l'algorithme pour une exponentiation rapide.

/**
 * 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));
}

J'ai testé l'algorithme contre deux autres approches:

  • Boucle for normale utilisant String.concat() pour concaténer une chaîne
  • Normal pour une boucle utilisant une StringBuilder

Code de test (la concaténation utilisant une boucle for et String.concat() devient trop lente pour n, alors je l'ai laissée de côté après la cinquième itération).

/**
 * 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);
    }
}

Résultats:

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

Conclusion:

  • Pour les grands n - utilisez l'approche récursive
  • Pour les petits n - la boucle a une vitesse suffisante
5
Niels Billen

Que dis-tu de ça?

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

RandomStringUtils a la possibilité de créer une chaîne à partir de la taille d'entrée indiquée ..___.

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

crée une sortie 

\ t\t\t\t\t

préférable si vous ne voulez pas voir \ 0 dans votre code.

2
Mulki

Depuis Java 11, vous pouvez simplement utiliser String.repeat(count) pour résoudre votre problème.

Retourne une chaîne dont la valeur est la concaténation de cette chaîne répétée count fois.

Si cette chaîne est vide ou que count vaut zéro, la chaîne vide est renvoyée.

Ainsi, au lieu d’une boucle, votre code ressemblerait à ceci:

" ".repeat(length);
1
Samuel Philipp

Vous pouvez utiliser la fonction standard String.format pour générer N espaces . Par exemple: 

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

Fait une chaîne avec 5 espaces.

ou

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

Fait une chaîne de 15 barres d'espace.

Si vous souhaitez qu'un autre symbole se répète, vous devez remplacer les espaces par le symbole souhaité:

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

Sortie:

#######
1
Alexey Gusev

Considérant que nous avons:

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 (Utilisation du flux)

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

Java 8 (Utilisation de nCopies)

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

Dans la plupart des cas, vous n’avez besoin que de chaînes jusqu’à une certaine longueur, disons 100 espaces. Vous pouvez préparer un tableau de chaînes dont le numéro d'index est égal à la taille de la chaîne remplie avec un espace et rechercher la chaîne si la longueur requise est comprise dans les limites ou la créer à la demande si elle se situe en dehors de la limite.

1
Andreas_D

Vous pouvez remplacer StringBuffer par StringBuilder (ce dernier n'est pas synchronisé, il peut être plus rapide dans une application à un seul thread) 

Et vous pouvez créer l'instance StringBuilder une fois, au lieu de la créer à chaque fois que vous en avez besoin. 

Quelque chose comme ça:

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;
      }

  }

Et utilisez-le comme ceci:

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

Si vous conservez votre createA en tant que variable d'instance, vous pouvez gagner du temps en créant des instances.

Ce n'est pas sécuritaire pour les threads, si vous avez plusieurs threads, chaque thread doit avoir sa propre copie. 

0
OscarRyz

Pour de bonnes performances, combinez les réponses de aznilamir et de 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 );
    }
}

Ajustez la taille de BLANKS en fonction de vos besoins. Ma chaîne BLANKS spécifique a une longueur d'environ 200 caractères.

0
olibre

Utilisez StringUtils: StringUtils.repeat ('', 10)

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

où:

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

Il suffit de remplacer votre StringBuffer par un StringBuilder . Difficile de battre ça.

Si votre longueur est un grand nombre, vous pouvez en implémenter quelques-uns plus efficaces .__ (mais plus maladroits), en dupliquant la longueur à chaque itération:

 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();
 }

Vous pouvez également essayer la réponse Arrays.fill() aproach (la réponse de FrustratedWithFormsDesigner).

0
leonbloy

Avoir une méthode comme celle-ci. Ceci ajoute les espaces requis à la fin de la String donnée pour rendre une String donnée à la longueur d'une longueur spécifique. 

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