Crea una cadena con n caracteres

¿Hay alguna manera en java para crear una cadena con un número especificado de un carácter específico? En mi caso, necesitaría crear una cadena con 10 espacios. Mi código actual es:

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

¿Hay una mejor manera de lograr lo mismo? En particular, me gustaría algo que sea rápido (en términos de ejecución).

    El bucle for será optimizado por el comstackdor. En tales casos, como el suyo, no necesita preocuparse por la optimización por su cuenta. Confía en el comstackdor. 🙂

    Editar: Por cierto, si hay una manera de crear una cadena con n caracteres espaciales, entonces está codificada de la misma manera que lo que acabas de hacer.

    Probablemente el código más corto que utiliza la API String , exclusivamente:

     String space10 = new String(new char[10]).replace('\0', ' '); System.out.println("[" + space10 + "]"); // prints "[ ]" 

    Como método, sin instanciar directamente 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', ' ' ); } 

    Invocar usando:

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

    Hmm ahora que lo pienso, quizás Arrays.fill :

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

    Por supuesto, supongo que el método de fill hace lo mismo que tu código, por lo que probablemente tendrá el mismo rendimiento, pero al menos esto es menos líneas.

    Recomiendo encarecidamente no escribir el ciclo a mano. Lo hará una y otra vez durante el transcurso de su carrera de progtwigción. Las personas que leen tu código, eso te incluye a ti, siempre tienen que invertir tiempo, incluso si solo son algunos segundos, para digerir el significado del ciclo.

    En su lugar, reutilice una de las bibliotecas disponibles que proporciona código que hace exactamente eso como StringUtils.repeat de Apache Commons Lang :

     return StringUtils.repeat(' ', length); 

    De esta forma, no tiene que preocuparse por el rendimiento, por lo que se ocultan todos los detalles sangrientos de StringBuilder , las optimizaciones del comstackdor, etc. Si la función fuera tan lenta, sería un error de la biblioteca.

    En Java 8 puedes usar String.join :

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

    Si solo quieres espacios, ¿qué tal?

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

    que dará como resultado espacios abs (n);

    Creo que este es el código menos posible, usa la clase Guava Joiner:

    Joiner .on (“”). Join ( Collections.nCopies (10, “”));

    Mi contribución basada en el algoritmo de exponenciación rápida.

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

    Probé el algoritmo frente a otros dos enfoques:

    • Bucle regular para usar String.concat() para concatenar cadena
    • Bucle regular para usar un StringBuilder

    Código de prueba (concatenación usando un bucle for y String.concat() vuelve lento para n grande, por lo que lo dejé después de la quinta iteración).

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

    Resultados:

     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 

    Conclusión:

    • Para n grande: use el enfoque recursivo
    • Para pequeños n - for bucle tiene suficiente velocidad

    ¿Qué tal esto?

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

    En la mayoría de los casos, solo necesita Cadenas de hasta cierta longitud, digamos 100 espacios. Puede preparar una matriz de cadenas donde el número de índice es igual al tamaño de la cadena llena de espacio y buscar la cadena, si la longitud requerida está dentro de los límites o crearla bajo demanda si está fuera del límite.

    RandomStringUtils tiene una disposición para crear una cadena a partir del tamaño de entrada dado. No puedo comentar sobre la velocidad, pero es un trazador de líneas.

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

    crea una salida

    \ t \ t \ t \ t \ t

    preferible si no quieres ver \ 0 en tu código.

    Simplemente reemplace su StringBuffer con un StringBuilder . Difícil de superar eso.

    Si su longitud es un número grande, puede implementar algunos autoependientes más eficientes (pero más torpes), duplicando la longitud en cada iteración:

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

    Además, puede probar el Arrays.fill() ( FrustratedWithFormsDesigner ).

    Puede reemplazar StringBuffer con StringBuilder (este último no está sincronizado, puede ser más rápido en una aplicación de un solo hilo)

    Y puede crear la instancia de StringBuilder una vez, en lugar de crearla cada vez que la necesite.

    Algo como esto:

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

    Y úsalo así:

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

    Si mantiene su createA como una variable de instancia, puede ahorrar tiempo creando instancias.

    Esto no es seguro para subprocesos, si tiene varios subprocesos, cada subproceso debe tener su propia copia.

    Para un buen rendimiento, combine las respuestas de aznilamir y 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 ); } } 

    Ajuste el tamaño de BLANKS según sus requisitos. Mi cadena específica BLANKS tiene una longitud de aproximadamente 200 caracteres.

    Ten un método como este. Esto agrega espacios requeridos al final de la String dada para hacer una String dada a la longitud de longitud específica.

     public static String fillSpaces (String str) { // the spaces string should contain spaces exceeding the max needed String spaces = " "; return str + spaces.substring(str.length()); } 

    Puede usar la función String.format estándar para generar N espacios. Por ejemplo:

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

    Hace una cadena con 5 espacios.

    o

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

    Hace una cadena de 15 barras espaciales.

    Si desea que se repita otro símbolo, debe reemplazar espacios con su símbolo deseado:

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

    Salida:

     ####### 

    Considerando que tenemos:

     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 (usando Stream)

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

    Java 8 (usando nCopies)

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

    Un método simple como a continuación también se puede utilizar

     public static String padString(String str, int leng,char chr) { for (int i = str.length(); i < = leng; i++) str += chr; return str; } 

    ¿Qué tal esto?

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

    EDITAR: He escrito un código simple para probar el concepto y aquí lo que encontré.

    Método 1: agregar espacio individual en un bucle:

      public String execLoopSingleSpace(int len){ StringBuilder sb = new StringBuilder(); for(int i=0; i < len; i++) { sb.append(' '); } return sb.toString(); } 

    Método 2: añada 100 espacios y bucle, luego subcadena:

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

    El resultado me da la creación de 12,345,678 espacios:

     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 

    y para 10,000,000 de espacios:

     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 

    combinar la asignación directa y la iteración siempre lleva menos tiempo, en promedio 60 ms menos cuando se crean espacios enormes. Para tamaños más pequeños, ambos resultados son insignificantes.

    Pero por favor continúa comentando 🙂

    No conozco ningún método incorporado para lo que preguntas. Sin embargo, para una longitud fija pequeña como 10, su método debe ser bastante rápido.