Самый простой путь к запятой - разграничивает список?

Что самый ясный путь к запятой - разграничивают список в Java?

Я знаю несколько способов сделать его, но я задаюсь вопросом, что лучший способ (где "лучше всего" означает самый ясный и/или самый короткий, не самое эффективное.

У меня есть список, и я хочу циклично выполниться по нему, печатая каждое значение. Я хочу распечатать запятую между каждым объектом, но не после последнего (ни перед первым).

List --> Item ( , Item ) *
List --> ( Item , ) * Item

Демонстрационное решение 1:

boolean isFirst = true;
for (Item i : list) {
  if (isFirst) {
    System.out.print(i);        // no comma
    isFirst = false;
  } else {
    System.out.print(", "+i);   // comma
  }
}

Демонстрационное решение 2 - создает подсписок:

if (list.size()>0) {
  System.out.print(list.get(0));   // no comma
  List theRest = list.subList(1, list.size());
  for (Item i : theRest) {
    System.out.print(", "+i);   // comma
  }
}

Демонстрационное решение 3:

  Iterator i = list.iterator();
  if (i.hasNext()) {
    System.out.print(i.next());
    while (i.hasNext())
      System.out.print(", "+i.next());
  }

Они рассматривают первый объект особенно; можно было вместо этого рассматривать последний особенно.

Кстати, вот то, как List toString реализован (это наследовано от AbstractCollection), в Java 1.6:

public String toString() {
    Iterator i = iterator();
    if (! i.hasNext())
        return "[]";

    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = i.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! i.hasNext())
            return sb.append(']').toString();
        sb.append(", ");
    }
}

Это выходит из цикла рано для предотвращения запятой после последнего объекта. BTW: это - первый раз, когда я вспоминаю наблюдение" (этот Набор)"; вот код для вызова его:

List l = new LinkedList();
l.add(l);
System.out.println(l);

Я приветствую какое-либо решение, даже если они пользуются неожиданными библиотеками (regexp?); и также решения на языках кроме Java (например, Я думаю Python/Ruby, имеют вкраплять функцию - как это реализовано?).

Разъяснение: библиотеками я имею в виду стандартные библиотеки Java. Для других библиотек я полагаю, что они с другими языками, и заинтересованный знают, как они реализованы.

ОТРЕДАКТИРУЙТЕ инструментарий, упомянул подобный вопрос: Последнее повторение расширенных для цикла в Java

И другой: последний элемент в цикле заслуживают отдельной обработки?

100
задан Samet ÖZTOPRAK 9 November 2019 в 20:15
поделиться

17 ответов

Java 8 и позже

Используя StringJoiner класс:

StringJoiner joiner = new StringJoiner(",");
for (Item item : list) {
    joiner.add(item.toString());
}
return joiner.toString();

Используя Stream , и Collectors :

return list.stream().
       map(Object::toString).
       collect(Collectors.joining(",")).toString();

Java 7 и ранее

См. также #285523

String delim = "";
for (Item i : list) {
    sb.append(delim).append(i);
    delim = ",";
}
218
ответ дан Basil Bourque 24 November 2019 в 04:45
поделиться
if (array.length>0)          // edited in response Joachim's comment
  sb.append(array[i]);
for (int i=1; i<array.length; i++)
  sb.append(",").append(array[i]);

На основе Самый Ясный путь к запятой - разграничивают список (Java)?

Используя эту идею: Делает последний элемент в цикле, заслуживают отдельной обработки?

0
ответ дан Community 24 November 2019 в 04:45
поделиться

Можно также безусловно добавить строку разделителя, и после того, как цикл удалит дополнительный разделитель в конце. Тогда, "если список пуст тогда, возвращаются, эта строка" вначале позволит Вам избегать проверки в конце (поскольку Вы не можете удалить символы из пустого списка)

, Таким образом, вопрос действительно:

, "Учитывая цикл и, если, что, Вы думаете, самый ясный путь состоит в том, чтобы иметь их вместе?"

0
ответ дан Thorbjørn Ravn Andersen 24 November 2019 в 04:45
поделиться
StringBuffer sb = new StringBuffer();

for (int i = 0; i < myList.size(); i++)
{ 
    if (i > 0) 
    {
        sb.append(", ");
    }

    sb.append(myList.get(i)); 
}
1
ответ дан Aries McRae 24 November 2019 в 04:45
поделиться

В Python ее легкое

"", .join (yourlist)

В C# существует статический метод для Строки Строкового класса

. Соединение ("", yourlistofstrings)

Извините, не уверенный в Java, но думало, что я заговорю, когда Вы спросили о других языках. Я уверен, что в Java было бы что-то подобное.

0
ответ дан tarn 24 November 2019 в 04:45
поделиться

Это очень коротко, очень ясно, но дает моей чувствительности вползающие ужасы. Это также немного неудобно адаптировать к различным разделителям, особенно если Строка (не символ).

for (Item i : list)
  sb.append(',').append(i);
if (sb.charAt(0)==',') sb.deleteCharAt(0);

Вдохновленный: Последнее повторение расширенных для цикла в java

1
ответ дан Community 24 November 2019 в 04:45
поделиться

Я не скомпилировал его..., но должен работать (или быть близко к работе).

public static <T> String toString(final List<T> list, 
                                  final String delim)
{
    final StringBuilder builder;

    builder = new StringBuilder();

    for(final T item : list)
    {
        builder.append(item);
        builder.append(delim);
    }

    // kill the last delim
    builder.setLength(builder.length() - delim.length());

    return (builder.toString());
}
1
ответ дан TofuBeer 24 November 2019 в 04:45
поделиться

Я обычно использую что-то подобное версии 3. Это работает хорошо c/c ++/bash/...: P

1
ответ дан sfossen 24 November 2019 в 04:45
поделиться

(Вставка копии моего собственного ответа от здесь .) Многие решения, описанные здесь, немного чрезмерны, по моему скромному мнению, особенно те, которые полагаются на внешние библиотеки. Существует хорошая чистая, ясная идиома для достижения списка разделенных запятой значений, который я всегда использовал. Это полагается на условный (?) оператор:

Редактирование : Исходное корректное решение, но неоптимальное согласно комментариям. Попытка во второй раз:

int[] array = {1, 2, 3};
StringBuilder builder = new StringBuilder();
for (int i = 0 ;  i < array.length; i++)
       builder.append(i == 0 ? "" : ",").append(array[i]);

Там Вы идете в 4 строках кода включая объявление массива и StringBuilder.

2-е Редактирование : Если Вы имеете дело с Итератором:

    List<Integer> list = Arrays.asList(1, 2, 3);
    StringBuilder builder = new StringBuilder();
    for (Iterator it = list.iterator(); it.hasNext();)
        builder.append(it.next()).append(it.hasNext() ? "," : "");
2
ответ дан Community 24 November 2019 в 04:45
поделиться

Если можно использовать Groovy (который работает на JVM):

def list = ['a', 'b', 'c', 'd']
println list.join(',')
2
ответ дан kungfoo 24 November 2019 в 04:45
поделиться

Я обычно делаю это:

StringBuffer sb = new StringBuffer();
Iterator it = myList.iterator();
if (it.hasNext()) { sb.append(it.next().toString()); }
while (it.hasNext()) { sb.append(",").append(it.next().toString()); }

, Хотя я думаю, что буду к этой проверке с этого времени согласно реализации Java;)

2
ответ дан Alex Marshall 24 November 2019 в 04:45
поделиться
for(int i=0, length=list.size(); i<length; i++)
  result+=(i==0?"":", ") + list.get(i);
3
ответ дан cherouvim 24 November 2019 в 04:45
поделиться
StringBuffer result = new StringBuffer();
for(Iterator it=list.iterator; it.hasNext(); ) {
  if (result.length()>0)
    result.append(", ");
  result.append(it.next());
}

Обновление : Как Dave Webb упомянул в комментариях, это не может привести к корректным результатам, если первые объекты в списке являются пустыми строками.

2
ответ дан cherouvim 24 November 2019 в 04:45
поделиться

На основе Списка Java toString реализация:

Iterator i = list.iterator();
for (;;) {
  sb.append(i.next());
  if (! i.hasNext()) break;
  ab.append(", ");
}

Это использует грамматику как это:

List --> (Item , )* Item

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

6
ответ дан 13ren 24 November 2019 в 04:45
поделиться

При использовании Платформы Spring, можно сделать это с StringUtils:

public static String arrayToDelimitedString(Object[] arr)
public static String arrayToDelimitedString(Object[] arr, String delim)
public static String collectionToCommaDelimitedString(Collection coll)
public static String collectionToCommaDelimitedString(Collection coll, String delim)
7
ответ дан Eric 24 November 2019 в 04:45
поделиться
org.apache.commons.lang3.StringUtils.join(list,",");
82
ответ дан trunkc 24 November 2019 в 04:45
поделиться

Мне несколько нравится этот подход, который я нашел на блоге некоторое время назад. К сожалению, я не помню ИМЯ/URL блога.

Можно создать класс утилиты/помощника, который похож на это:

private class Delimiter
{
    private final String delimiter;
    private boolean first = true;

    public Delimiter(String delimiter)
    {
        this.delimiter = delimiter;
    }

    @Override
    public String toString()
    {
        if (first) {
            first = false;
            return "";
        }

        return delimiter;
    }
}

Используя помощника класс прост как это:

StringBuilder sb = new StringBuilder();
Delimiter delimiter = new Delimiter(", ");

for (String item : list) {
    sb.append(delimiter);
    sb.append(item);
}
1
ответ дан Tobias Müller 24 November 2019 в 04:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: