将for循环转换为concat String转换为lambda表达式

时间:2015-07-16 14:19:54

标签: java collections lambda java-8 java-stream

我有以下for循环,它循环遍历字符串列表并将每个单词的第一个字符存储在StringBuilder中。我想知道如何将其转换为lambda表达式

StringBuilder chars = new StringBuilder();
for (String l : list) {
    chars.append(l.charAt(0));
}  

5 个答案:

答案 0 :(得分:38)

假设您之后在toString()上致电StringBuilder,我认为在将每个字符串映射到单字符子字符串之后,您只是在寻找Collectors.joining()

String result = list
    .stream()
    .map(s -> s.substring(0, 1))
    .collect(Collectors.joining());

示例代码:

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
    }
}

请注意使用substring代替charAt,因此我们仍然可以使用字符串流。

答案 1 :(得分:17)

很多方法可以做到这一点 - 最简单的选项:坚持添加$i = $i+++1+2+3+4; 并执行此操作:

StringBuilder

答案 2 :(得分:12)

如果不创建许多中间String对象,您可以这样做:

StringBuilder sb = list.stream()
                       .mapToInt(l -> l.codePointAt(0))
                       .collect(StringBuilder::new, 
                                StringBuilder::appendCodePoint, 
                                StringBuilder::append);

请注意,使用codePointAt要好于charAt,就好像您的字符串以代理项对开头一样,使用charAt可能会产生不可预测的结果。

答案 3 :(得分:3)

以下是此问题的三种不同解决方案。每个解决方案首先过滤空字符串,否则可能会抛出StringIndexOutOfBoundsException

此解决方案与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);

第二个解决方案使用Eclipse Collections,并利用在7.0版中添加的名为CodePointAdapter的相对较新的容器类型。

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

第三个解决方案再次使用Eclipse Collections,但使用injectIntoStringBuilder而不是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);

注意:我是Eclipse Collections的提交者。

答案 4 :(得分:0)

使用方法参考的简单方法:

List<String> list = Arrays.asList("ABC", "CDE");
StringBuilder sb = new StringBuilder();

list.forEach(sb::append);

String concatString = sb.toString();