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”。


当前回答

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

其他回答

我将使用streams api将整数流转换为单个字符串。提供的一些答案的问题是,由于构建String,它们产生了O(n²)运行时。更好的解决方案是使用StringBuilder,然后在最后一步将字符串连接在一起。

//              Create a stream of integers 
    String result = Arrays.stream(new int[]{1,2,3,4,5,6 })                
            // collect into a single StringBuilder
            .collect(StringBuilder::new, // supplier function
                    // accumulator - converts cur integer into a string and appends it to the string builder
                    (builder, cur) -> builder.append(Integer.toString(cur)),
                    // combiner - combines two string builders if running in parallel
                    StringBuilder::append) 
            // convert StringBuilder into a single string
            .toString();

您可以通过将object的集合转换为单个字符串来进一步执行此过程。

// Start with a class definition
public static class AClass {
    private int value;
    public int getValue() { return value; }
    public AClass(int value) { this.value = value; }

    @Override
    public String toString() {
        return Integer.toString(value);
    }
}

// Create a stream of AClass objects
        String resultTwo = Arrays.stream(new AClass[]{
                new AClass(1),
                new AClass(2),
                new AClass(3),
                new AClass(4)
        })
                // transform stream of objects into a single string
                .collect(StringBuilder::new,
                        (builder, curObj) -> builder.append(curObj.toString()),
                        StringBuilder::append
                )
            // finally transform string builder into a single string
            .toString();

你也可以这样做。

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

我们可以试试这个吗?

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

    }

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

Java 8+

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

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