Простой способ повторить строку в Java - PullRequest
509 голосов
/ 05 августа 2009

Я ищу простой метод или оператор, который позволяет мне повторять несколько строк n раз. Я знаю, что мог бы написать это, используя цикл for, но я хочу избегать циклов for всякий раз, когда необходимо, и где-то должен существовать простой прямой метод.

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

repeated.equals("abcabcabc");

Относится к:

повтор строки javascript Создать строку NSSt, повторяя другую строку заданное количество раз

Отредактировано

Я стараюсь избегать циклов, когда они не являются полностью необходимыми, потому что:

  1. Они добавляют к числу строк кода, даже если они спрятаны в другой функции.

  2. Кто-то, читающий мой код, должен выяснить, что я делаю в этом цикле for. Даже если он закомментирован и имеет значимые имена переменных, они все равно должны убедиться, что он не делает ничего «умного».

  3. Программисты любят помещать умные вещи в циклы, даже если я пишу это «делай только то, что задумано», что не исключает появления кого-то и добавления некоторого дополнительного умного «исправления».

  4. Очень часто их легко ошибиться. Для циклов, включающих индексы, склонны генерировать по одной ошибке.

  5. Поскольку циклы часто используют одни и те же переменные, повышая вероятность того, что действительно трудно найти ошибки определения объема.

  6. Для циклов увеличьте количество мест, которые должен искать охотник за насекомыми.

Ответы [ 28 ]

2 голосов
/ 08 июня 2015

Используя рекурсию, вы можете сделать следующее (используя троичные операторы, максимум одна строка):

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

Я знаю, это некрасиво и, вероятно, неэффективно, но это одна строка!

2 голосов
/ 25 июня 2013

Простая петля

public static String repeat(String string, int times) {
    StringBuilder out = new StringBuilder();
    while (times-- > 0) {
        out.append(string);
    }
    return out.toString();
}
2 голосов
/ 03 апреля 2013

Мне очень нравится этот вопрос. Здесь много знаний и стилей. Так что я не могу оставить это без шоу моего рок-н-ролла;)

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

Тебе нравится?

1 голос
/ 06 августа 2009

Несмотря на ваше желание не использовать циклы, я думаю, вам следует использовать цикл.

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

Ваши причины не использовать цикл for не очень хорошие. В ответ на вашу критику:

  1. Какое бы решение вы не использовали, оно почти наверняка будет длиннее. Использование предварительно встроенной функции позволяет скрыть ее только под несколькими крышками.
  2. Кто-то, читающий ваш код, должен будет выяснить, что вы делаете в этом цикле. Учитывая, что цикл for является идиоматическим способом сделать это, было бы гораздо проще понять, если бы вы сделали это с помощью цикла for.
  3. Да, кто-то может добавить что-нибудь умное, но, избегая цикла for , вы делаете что-то умное . Это все равно, что умышленно выстрелить себе в ногу, чтобы случайно не выстрелить себе в ногу.
  4. Неоднозначные ошибки также легко обнаружить с помощью одного теста. Учитывая, что вы должны тестировать свой код, легко исправить и отловить ошибку «один за другим». И это стоит отметить: приведенный выше код не содержит ошибки «один за другим». Для петель одинаково легко получить право.
  5. Так что не используйте переменные повторно. Это не ошибка цикла.
  6. Опять, как и любое решение, которое вы используете. И, как я уже отмечал ранее; охотник за ошибками, вероятно, будет ожидать, что вы сделаете это с циклом for, поэтому им будет проще найти его, если вы используете цикл for.
1 голос
/ 31 мая 2013
public static String repeat(String str, int times) {
    int length = str.length();
    int size = length * times;
    char[] c = new char[size];
    for (int i = 0; i < size; i++) {
        c[i] = str.charAt(i % length);
    }
    return new String(c);
}
0 голосов
/ 11 августа 2011

вот последняя версия Stringutils.java StringUtils.java

    public static String repeat(String str, int repeat) {
    // Performance tuned for 2.0 (JDK1.4)

    if (str == null) {
        return null;
    }
    if (repeat <= 0) {
        return EMPTY;
    }
    int inputLength = str.length();
    if (repeat == 1 || inputLength == 0) {
        return str;
    }
    if (inputLength == 1 && repeat <= PAD_LIMIT) {
        return repeat(str.charAt(0), repeat);
    }

    int outputLength = inputLength * repeat;
    switch (inputLength) {
        case 1 :
            return repeat(str.charAt(0), repeat);
        case 2 :
            char ch0 = str.charAt(0);
            char ch1 = str.charAt(1);
            char[] output2 = new char[outputLength];
            for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
                output2[i] = ch0;
                output2[i + 1] = ch1;
            }
            return new String(output2);
        default :
            StringBuilder buf = new StringBuilder(outputLength);
            for (int i = 0; i < repeat; i++) {
                buf.append(str);
            }
            return buf.toString();
    }
    }

он даже не должен быть таким большим, его можно превратить в это, а также скопировать и вставить в служебный класс в вашем проекте.

    public static String repeat(String str, int num) {
    int len = num * str.length();
    StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < times; i++) {
        sb.append(str);
    }
    return sb.toString();
    }

Итак, e5, я думаю, что лучший способ сделать это - просто использовать вышеупомянутый код или любой из ответов здесь. но общий язык слишком велик, если это маленький проект

0 голосов
/ 09 октября 2014
repeated = str + str + str;

Иногда лучше просто. Каждый, кто читает код, может видеть, что происходит.

И компилятор будет делать причудливые вещи с StringBuilder за сценой для вас.

0 голосов
/ 07 января 2016

Я создал рекурсивный метод, который делает то же самое, что вы хотите .. не стесняйтесь использовать это ...

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

у меня тот же ответ на Могу ли я умножить строки в Java для повторения последовательностей?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...