Manera simple de repetir una cadena en Java


Answers

Aquí está la versión más corta (se requiere Java 1.5+):

repeated = new String(new char[n]).replace("\0", s);

Donde n es el número de veces que desea repetir la cadena y s es la cadena para repetir.

No se necesitan importaciones o bibliotecas.

Question

Estoy buscando un método simple u operador común que me permita repetir algunas cadenas n veces. Sé que podría escribir esto usando un bucle for, pero deseo evitar bucles siempre que sea necesario y un método directo simple debería existir en alguna parte.

String str = "abc";
String repeated = str.repeat(3);

repeated.equals("abcabcabc");

Relacionado con:

cadena de repetición javascript Crea NSString repitiendo otra cadena un determinado número de veces

Editado

Intento evitar bucles cuando no son completamente necesarios porque:

  1. Agregan a la cantidad de líneas de código, incluso si están escondidas en otra función.

  2. Alguien que lea mi código tiene que descubrir lo que estoy haciendo en ese ciclo for. Incluso si se comenta y tiene nombres de variables significativas, aún deben asegurarse de que no está haciendo algo "inteligente".

  3. A los programadores les encanta poner cosas ingeniosas en bucles, incluso si lo escribo para "hacer solo lo que se pretende", eso no impide que alguien se acerque y agregue alguna "solución" inteligente adicional.

  4. A menudo son fáciles de equivocarse. Para bucles que implican índices tienden a generar un error por uno.

  5. Para los bucles, a menudo se reutilizan las mismas variables, lo que aumenta las posibilidades de encontrar errores de búsqueda realmente difíciles.

  6. Para los bucles aumenta la cantidad de lugares que debe buscar un cazador de errores.




Usando recursión, puede hacer lo siguiente (usando operadores ternarios, una línea máxima):

public static final String repeat(String string, long number) {
    return number == 1 ? string : (number % 2 == 0 ? repeat(string + string, number / 2) : string + repeat(string + string, (number - 1) / 2));
}

Lo sé, es feo y probablemente no eficiente, ¡pero es una sola línea!




Realmente disfruto esta pregunta. Hay muchos conocimientos y estilos. Así que no puedo dejarlo sin mostrar mi rock and roll;)

{
    String string = repeat("1234567890", 4);
    System.out.println(string);
    System.out.println("=======");
    repeatWithoutCopySample(string, 100000);
    System.out.println(string);// This take time, try it without printing
    System.out.println(string.length());
}

/**
 * The core of the task.
 */
@SuppressWarnings("AssignmentToMethodParameter")
public static char[] repeat(char[] sample, int times) {
    char[] r = new char[sample.length * times];
    while (--times > -1) {
        System.arraycopy(sample, 0, r, times * sample.length, sample.length);
    }
    return r;
}

/**
 * Java classic style.
 */
public static String repeat(String sample, int times) {
    return new String(repeat(sample.toCharArray(), times));
}

/**
 * Java extreme memory style.
 */
@SuppressWarnings("UseSpecificCatch")
public static void repeatWithoutCopySample(String sample, int times) {
    try {
        Field valueStringField = String.class.getDeclaredField("value");
        valueStringField.setAccessible(true);
        valueStringField.set(sample, repeat((char[]) valueStringField.get(sample), times));
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

¿Te gusta?




Probar esto:

public static char[] myABCs = {'a', 'b', 'c'};
public static int numInput;
static Scanner in = new Scanner(System.in);

public static void main(String[] args) {
    System.out.print("Enter Number of Times to repeat: ");
    numInput = in.nextInt();
    repeatArray(numInput);
}

public static int repeatArray(int y) {
    for (int a = 0; a < y; a++) {
        for (int b = 0; b < myABCs.length; b++) {
            System.out.print(myABCs[b]);                
        }
        System.out.print(" ");
    }
    return y;
}



I created a recursive method that do the same thing you want.. feel free to use this...

public String repeat(String str, int count) {
    return count > 0 ?  repeat(str, count -1) + str: "";
}

i have the same answer on Can I multiply strings in java to repeat sequences?




Con java-8 , también puedes usar Stream.generate .

import static java.util.stream.Collectors.joining;
...
String repeated = Stream.generate(() -> "abc").limit(3).collect(joining()); //"abcabcabc"

y puede envolverlo en un sencillo método de utilidad si es necesario:

public static String repeat(String str, int times) {
   return Stream.generate(() -> str).limit(times).collect(joining());
}



Si le preocupa el rendimiento, simplemente use un StringBuilder dentro del bucle y realice un .toString () al salir del bucle. Diablos, escribe tu propia Clase Util y vuelve a utilizarla. 5 líneas de código máx.




Esto es tan simple como se pone:

// create a string made up of n copies of string s
String.format("%0" + n + "d", 0).replace("0",s);

En Java 8 hay una manera aún más fácil:

// create a string made up of n copies of string s
String.join("", Collections.nCopies(n, s));



usar Dollar es simple como escribir:

@Test
public void repeatString() {
    String string = "abc";
    assertThat($(string).repeat(3).toString(), is("abcabcabc"));
}

PD: repetir funciona también para array, List, Set, etc.




Esto contiene menos caracteres que tu pregunta

public static String repeat(String s, int n) {
    if(s == null) {
        return null;
    }
    final StringBuilder sb = new StringBuilder(s.length() * n);
    for(int i = 0; i < n; i++) {
        sb.append(s);
    }
    return sb.toString();
}



Esta es una forma de hacerlo utilizando solo funciones de cadena estándar y sin bucles explícitos:

// create a string made up of  n  copies of  s
repeated = String.format(String.format("%%%ds", n), " ").replace(" ",s);



A pesar de su deseo de no utilizar bucles, creo que debería usar un bucle.

String repeatString(String s, int repetitions)
{
    if(repetitions < 0) throw SomeException();

    else if(s == null) return null;

    StringBuilder stringBuilder = new StringBuilder(s.length() * repetitions);

    for(int i = 0; i < repetitions; i++)
        stringBuilder.append(s);

    return stringBuilder.toString();
}

Sus razones para no usar un bucle for no son buenas. En respuesta a tus críticas:

  1. Cualquier solución que uses seguramente será más larga que esto. El uso de una función preconstruida solo lo coloca debajo de más cubiertas.
  2. Alguien que lea tu código tendrá que descubrir qué estás haciendo en ese bucle que no es para. Dado que un bucle for es la forma idiomática de hacer esto, sería mucho más fácil averiguar si lo hiciste con un bucle for.
  3. Sí, alguien podría agregar algo inteligente, pero al evitar un bucle for está haciendo algo inteligente . Es como dispararse en el pie intencionalmente para evitar dispararse en el pie por accidente.
  4. Los errores de uno por uno también son increíblemente fáciles de atrapar con una sola prueba. Dado que debería probar su código, un error aislado debería ser fácil de corregir y atrapar. Y vale la pena señalar: el código anterior no contiene un error "uno por uno". Para los bucles es igualmente fácil hacerlo bien.
  5. Entonces no reutilices las variables. Eso no es culpa del for-loop.
  6. De nuevo, también lo hace cualquier solución que use. Y como noté antes; un cazador de errores probablemente espera que hagas esto con un bucle for, por lo que les resultará más fácil encontrarlo si usas un bucle for.



usando solo clases JRE ( System.arraycopy ) y tratando de minimizar la cantidad de objetos temporales, puede escribir algo como:

public static String repeat(String toRepeat, int times) {
    if (toRepeat == null) {
        toRepeat = "";
    }

    if (times < 0) {
        times = 0;
    }

    final int length = toRepeat.length();
    final int total = length * times;
    final char[] src = toRepeat.toCharArray();
    char[] dst = new char[total];

    for (int i = 0; i < total; i += length) {
        System.arraycopy(src, 0, dst, i, length);
    }

    return String.copyValueOf(dst);
}

EDITAR

y sin bucles puedes probar con:

public static String repeat2(String toRepeat, int times) {
    if (toRepeat == null) {
        toRepeat = "";
    }

    if (times < 0) {
        times = 0;
    }

    String[] copies = new String[times];
    Arrays.fill(copies, toRepeat);
    return Arrays.toString(copies).
              replace("[", "").
              replace("]", "").
              replaceAll(", ", "");
}

EDIT 2

usar Collections es aún más corto:

public static String repeat3(String toRepeat, int times) {
    return Collections.nCopies(times, toRepeat).
           toString().
           replace("[", "").
           replace("]", "").
           replaceAll(", ", "");
}

sin embargo, todavía me gusta la primera versión.




repeated = str + str + str;

Sometimes simple is best. Everyone reading the code can see what's happening.

And the compiler will do the fancy stuff with StringBuilder behind the scenes for you.




Related



Tags

java java   string