簡體   English   中英

使用流將對象列表轉換為從 toString 方法獲得的字符串

[英]Using streams to convert a list of objects into a string obtained from the toString method

Java 8 中有很多有用的新內容。例如,我可以使用 stream 對對象列表進行迭代,然后將來自Object實例的特定字段的值相加。 例如

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

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

因此,我問是否有任何方法可以構建一個String ,該字符串將來自實例的toString()方法的 output 連接在一行中。

List<Integer> list = ...

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

假設list包含整數123 ,我希望concatenated的是"123""1,2,3"

一種簡單的方法是將列表項附加到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(n 2 ) 中執行的normal reduction

為了獲得更好的性能,請使用類似於 F. Böller 的答案的StringBuildermutable reduction

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

參考: 流減少

有一個收集器joining API。 這是Collectors的靜態方法。

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

由於toString的必要調用,並不完美,但有效。 不同的分隔符是可能的。

以防萬一有人試圖在沒有 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 分隔元素,如果您的數據中有方括號,請使用子字符串版本,但對於數字數組,它幾乎是完美的。

對於那些“連接字符串列表”用例,String API 中有一個方法,您甚至不需要 Stream。

List<String> myStringIterable = Arrays.asList("baguette", "bonjour");

String myReducedString = String.join(",", myStringIterable);

// And here you obtain "baguette,bonjour" in your myReducedString variable

其他答案都很好。 但是,您也可以將Collectors.toList()作為參數傳遞給Stream.collect()以將元素作為 ArrayList 返回。

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

StringListName = ObjectListName.stream().map( m -> m.toString() ).collect( Collectors.toList() );

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

測試Shail016bpedroso答案( https://stackoverflow.com/a/24883180/2832140 )中建議的兩種方法, for循環中的簡單StringBuilder + append(String)似乎比list.stream().map([...]執行得快得多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());
}

在我的開發 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());
}

我們可以試試這個。

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

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

我將使用流 api 將整數流轉換為單個字符串。 一些提供的答案的問題在於,由於字符串構建,它們會產生 O(n^2) 運行時。 更好的解決方案是使用 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();

您可以通過將對象集合轉換為單個字符串來進一步執行此過程。

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

一個干凈的方法是將列表的元素映射到字符串,然后使用Collectors class 中的joining操作。

List<Integer> ls = new ArrayList<Integer>();
ls.add(1);
ls.add(2);
ls.add(3);
String s = ls.stream().map(Object::toString).collect(Collectors.joining(","));

使用 Java 8+

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

不是最有效的,但它是一個代碼量很少的解決方案。

另外,你可以這樣做。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM