Java 8中有很多有用的新功能。例如,我可以在对象列表上迭代流,然后从对象实例的特定字段中求和。如。

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

假设列表包含整数1,2,3,我期望连接的是“123”或“1,2,3”。


当前回答

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

Or

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

其他回答

你也可以这样做。

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

测试Shail016和bpedroso answer (https://stackoverflow.com/a/24883180/2832140)中建议的两种方法,即for循环中的简单StringBuilder + append(String),似乎比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 VM上,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());
}

API中加入了一个收集器。 它是collections中的一个静态方法。

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

由于必须调用toString,所以并不完美,但可以工作。可以使用不同的分隔符。

一种简单的方法是在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);

解释:map将Integer流转换为String流,然后将其简化为所有元素的连接。

注:这是O(n2)下的正常还原

为了获得更好的性能,请使用StringBuilder或类似F. Böller的答案的可变简化。

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

参考:流还原

Java 8+

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

虽然不是最有效的,但它是一种只需少量代码的解决方案。