Java 将 for 循环转换为 concat String 为 lambda 表达式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31456898/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert a for loop to concat String into a lambda expression
提问by Faktor 10
I have the following for loop which iterates through a list of strings and stores the first character of each word in a StringBuilder
. I would like to know how can I transform this to a lambda expression
我有以下 for 循环,它遍历字符串列表并将每个单词的第一个字符存储在StringBuilder
. 我想知道如何将其转换为 lambda 表达式
StringBuilder chars = new StringBuilder();
for (String l : list) {
chars.append(l.charAt(0));
}
采纳答案by Jon Skeet
Assuming you call toString()
on the StringBuilder
afterwards, I think you're just looking for Collectors.joining()
, after mapping each string to a single-character substring:
假设您toString()
在StringBuilder
之后调用,我认为您只是Collectors.joining()
在将每个字符串映射到单个字符子字符串之后寻找:
String result = list
.stream()
.map(s -> s.substring(0, 1))
.collect(Collectors.joining());
Sample code:
示例代码:
import java.util.*;
import java.util.stream.*;
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
String result = list
.stream()
.map(s -> s.substring(0, 1))
.collect(Collectors.joining());
System.out.println(result); // fbb
}
}
Note the use of substring
instead of charAt
, so we still have a stream of strings to work with.
注意使用substring
代替charAt
,所以我们仍然有一个字符串流可以使用。
回答by Tagir Valeev
Without creating many intermediate String objects you can do it like this:
无需创建许多中间 String 对象,您可以这样做:
StringBuilder sb = list.stream()
.mapToInt(l -> l.codePointAt(0))
.collect(StringBuilder::new,
StringBuilder::appendCodePoint,
StringBuilder::append);
Note that using codePointAt
is much better than charAt
as if your string starts with surrogate pair, using charAt
you may have an unpredictable result.
请注意,使用codePointAt
比charAt
字符串以代理对开头好得多,使用charAt
可能会产生不可预测的结果。
回答by Fritz Duchardt
Tons of ways to do this - the most simple option: stick to adding to a StringBuilder
and do this:
很多方法可以做到这一点 -最简单的选择:坚持添加到 aStringBuilder
并执行以下操作:
final StringBuilder chars = new StringBuilder();
list.forEach(l -> chars.append(l.charAt(0)));
回答by Donald Raab
Here are three different solutions to this problem. Each solution filters empty strings first as otherwise StringIndexOutOfBoundsException
may be thrown.
以下是针对此问题的三种不同解决方案。每个解决方案首先过滤空字符串,否则StringIndexOutOfBoundsException
可能会抛出。
This solution is the same as the solution from Tagir with the added code for filtering empty strings. I included it here primarily to compare to the other two solutions I have provided.
此解决方案与来自 Tagir 的解决方案相同,但添加了用于过滤空字符串的代码。我将它包含在这里主要是为了与我提供的其他两个解决方案进行比较。
List<String> list =
Arrays.asList("the", "", "quick", "", "brown", "", "fox");
StringBuilder builder = list.stream()
.filter(s -> !s.isEmpty())
.mapToInt(s -> s.codePointAt(0))
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append);
String result = builder.toString();
Assert.assertEquals("tqbf", result);
The second solution uses Eclipse Collections, and leverages a relatively new container type called CodePointAdapter
that was added in version 7.0.
第二个解决方案使用Eclipse Collections,并利用了CodePointAdapter
在 7.0 版中添加的一种名为的相对较新的容器类型。
MutableList<String> list =
Lists.mutable.with("the", "", "quick", "", "brown", "", "fox");
LazyIntIterable iterable = list.asLazy()
.reject(String::isEmpty)
.collectInt(s -> s.codePointAt(0));
String result = CodePointAdapter.from(iterable).toString();
Assert.assertEquals("tqbf", result);
The third solution uses Eclipse Collections again, but with injectInto
and StringBuilder
instead of CodePointAdapter
.
第三个解决方案再次使用 Eclipse Collections,但使用injectInto
和StringBuilder
代替CodePointAdapter
.
MutableList<String> list =
Lists.mutable.with("the", "", "quick", "", "brown", "", "fox");
StringBuilder builder = list.asLazy()
.reject(String::isEmpty)
.collectInt(s -> s.codePointAt(0))
.injectInto(new StringBuilder(), StringBuilder::appendCodePoint);
String result = builder.toString();
Assert.assertEquals("tqbf", result);
Note: I am a committer for Eclipse Collections.
注意:我是 Eclipse Collections 的提交者。
回答by Rahul Chauhan
Simple way using method reference :
使用方法参考的简单方法:
List<String> list = Arrays.asList("ABC", "CDE");
StringBuilder sb = new StringBuilder();
list.forEach(sb::append);
String concatString = sb.toString();