![](/img/trans.png)
[英]Convert List of Objects to List of String with filter using Java Streams
[英]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
包含整数1
、 2
和3
,我希望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 的答案的StringBuilder
或mutable 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);
测试Shail016和bpedroso答案( 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.