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).
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.
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 ) );
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.repeat
from 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);
En Java 8, vous pouvez utiliser String.join
:
String.join("", Collections.nCopies(n, s));
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);
Je pense que c'est le moins de code possible, il utilise la classe Guava Joiner:
Joiner . On (""). Join ( Collections.nCopies (10, ""));
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:
String.concat()
pour concaténer une chaîneStringBuilder
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:
n
- utilisez l'approche récursiven
- la boucle a une vitesse suffisanteQue dis-tu de ça?
char[] bytes = new char[length];
Arrays.fill(bytes, ' ');
String str = new String(bytes);
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.
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);
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:
#######
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)
String resultOne = IntStream.range(0,n)
.mapToObj(i->c).collect(Collectors.joining(EMPTY_STRING)); // cccc
String resultTwo = String.join(EMPTY_STRING, Collections.nCopies(n, c)); //cccc
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.
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.
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.
Utilisez StringUtils: StringUtils.repeat ('', 10)
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());
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).
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());
}