Использование 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);