Использование Java 8 для преобразования списка объектов в строку, полученную из метода toString()

В Java 8 есть много полезных новых вещей. Например, я могу перебирать поток по списку объектов, а затем суммировать значения из определенного поля экземпляров Object. Например.

public class AClass {
  private int value;
  public int getValue() { return value; }
}

Integer sum = list.stream().mapToInt(AClass::getValue).sum();

Таким образом, я спрашиваю, есть ли способ построить String, который объединяет вывод метода toString() из экземпляров в одной строке.

List<Integer> list = ...

String concatenated = list.stream().... //concatenate here with toString() method from java.lang.Integer class

Предположим, что list содержит целые числа 1, 2 и 3, я ожидаю, что concatenated равен "123" или "1,2,3".

Ответ 1

Один простой способ - добавить элементы списка в StringBuilder

   List<Integer> list = new ArrayList<>();
   list.add(1);
   list.add(2);
   list.add(3);

   StringBuilder b = new StringBuilder();
   list.forEach(b::append);

   System.out.println(b);

Вы также можете попробовать:

String s = list.stream().map(e -> e.toString()).reduce("", String::concat);

Объяснение: карта преобразует поток Integer в поток String, а затем уменьшается как объединение всех элементов.

Примечание: это normal reduction которое выполняется в O (n 2)

для лучшей производительности используйте StringBuilder или mutable reduction подобное ответу Ф.Беллера.

String s = list.stream().map(Object::toString).collect(Collectors.joining(","));

Ссылка: сокращение потока

Ответ 2

Существует коллектор joining в API. Это статический метод в Collectors.

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

Не идеально из-за необходимого вызова toString, но работает. Возможны разные разделители.

Ответ 3

На всякий случай, если кто-то пытается это сделать без java 8, есть довольно хороший трюк. List.toString() уже возвращает коллекцию, которая выглядит так:

[1,2,3]

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

Например:

list.toString().replace("[","").replace("]","") 

или если ваши данные могут содержать квадратные скобки:

String s=list.toString();
s = s.substring(1,s.length()-1) 

предоставит вам довольно разумный результат.

Один элемент массива в каждой строке может быть создан следующим образом:

list.toString().replace("[","").replace("]","").replaceAll(",","\r\n")

Я использовал этот метод для создания html-подсказок из списка в небольшом приложении с чем-то вроде:

list.toString().replace("[","<html>").replace("]","</html>").replaceAll(",","<br>")

Если у вас есть массив, тогда начните с Arrays.asList(list).toString() вместо

Я полностью соглашусь с тем, что это не оптимально, но это не так неэффективно, как вы думаете, и довольно просто читать и понимать. Это, однако, довольно негибкое - в частности, не пытайтесь отделить элементы replaceAll, если ваши данные могут содержать запятые и использовать версию подстроки, если у вас есть квадратные скобки в ваших данных, но для массива чисел это в значительной степени совершенны.

Ответ 4

Другие ответы в порядке. Однако вы также можете передать Collectors.toList() в качестве параметра в Поток. collect(), чтобы вернуть элементы как ArrayList.

System.out.println( list.stream().map( e -> e.toString() ).collect( toList() ) );

Ответ 5

String actual = list.stream().reduce((t, u) -> t + "," + u).get();

Ответ 6

StringListName = ObjectListName.stream(). Map (m → m.toString()).collect(Collectors.toList());

Ответ 7

List<String> list = Arrays.asList("One", "Two", "Three");
    list.stream()
            .reduce("", org.apache.commons.lang3.StringUtils::join);

Или же

List<String> list = Arrays.asList("One", "Two", "Three");
        list.stream()
                .reduce("", (s1,s2)->s1+s2);

Этот подход позволяет также построить строковый результат из списка объектов. Пример

List<Wrapper> list = Arrays.asList(w1, w2, w2);
        list.stream()
                .map(w->w.getStringValue)
                .reduce("", org.apache.commons.lang3.StringUtils::join);

Здесь функция Reduce позволяет вам иметь некоторое начальное значение, к которому вы хотите добавить новую строку. Пример:

 List<String> errors = Arrays.asList("er1", "er2", "er3");
            list.stream()
                    .reduce("Found next errors:", (s1,s2)->s1+s2);

Ответ 8

Тестирование обоих подходов, предложенных в Shail016 и ответе bpedroso (fooobar.com/questions/76574/...), простое StringBuilder + append(String) в цикле for, кажется, выполняется намного быстрее, чем list.stream().map([...].

Пример: этот код просматривает Map<Long, List<Long>> создает строку json, используя list.stream().map([...]:

if (mapSize > 0) {
    StringBuilder sb = new StringBuilder("[");

    for (Map.Entry<Long, List<Long>> entry : threadsMap.entrySet()) {

        sb.append("{\"" + entry.getKey().toString() + "\":[");
        sb.append(entry.getValue().stream().map(Object::toString).collect(Collectors.joining(",")));
    }
    sb.delete(sb.length()-2, sb.length());
    sb.append("]");
    System.out.println(sb.toString());
}

На моей виртуальной машине dev для выполнения теста junit обычно занимает от 0,35 до 1,2 секунды. В то время как, используя этот следующий код, это занимает от 0,15 до 0,33 секунды:

if (mapSize > 0) {
    StringBuilder sb = new StringBuilder("[");

    for (Map.Entry<Long, List<Long>> entry : threadsMap.entrySet()) {

        sb.append("{\"" + entry.getKey().toString() + "\":[");

        for (Long tid : entry.getValue()) {
            sb.append(tid.toString() + ", ");
        }
        sb.delete(sb.length()-2, sb.length());
        sb.append("]}, ");
    }
    sb.delete(sb.length()-2, sb.length());
    sb.append("]");
    System.out.println(sb.toString());
}

Ответ 9

Можем ли мы попробовать это.

public static void main(String []args){
        List<String> stringList = new ArrayList<>();
        for(int i=0;i< 10;i++){
            stringList.add(""+i);
        }
        String stringConcated = String.join(",", stringList);
        System.out.println(stringConcated);

    }

Ответ 10

С Java 8 +

String s = Arrays.toString(list.stream().toArray(AClass[]::new));

Не самый эффективный, но это решение с небольшим количеством кода.

Ответ 11

Кроме того, вы можете сделать это следующим образом.

    List<String> list = Arrays.asList("One", "Two", "Three");
    String result = String.join(", ", list);
    System.out.println(result);