wake-up-neo.com

Konvertieren Sie eine for-Schleife in einen concat-String in einen Lambda-Ausdruck

Ich habe die folgende for-Schleife, die eine Liste von Strings durchläuft und das erste Zeichen jedes Wortes in einer StringBuilder speichert. Ich würde gerne wissen, wie ich dies in einen Lambda-Ausdruck umwandeln kann

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

Angenommen, Sie rufen nachher toString() für die StringBuilder auf. Ich denke, Sie suchen nur nach Collectors.joining() , nachdem Sie jede Zeichenfolge einem einteiligen Teilstring zugeordnet haben:

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

Beispielcode:

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

Beachten Sie die Verwendung von substring anstelle von charAt, so dass wir immer noch einen Stream von Strings haben, mit dem wir arbeiten können.

37
Jon Skeet

Unzählige Möglichkeiten, dies zu tun - die einfachste Option : Bleiben Sie beim Hinzufügen zu einer StringBuilder und tun Sie dies:

    final StringBuilder chars = new StringBuilder();

    list.forEach(l -> chars.append(l.charAt(0)));
17
Fritz Duchardt

Ohne viele Zwischenobjekte erstellen zu müssen, können Sie dies folgendermaßen tun:

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

Beachten Sie, dass die Verwendung von codePointAt viel besser ist als charAt, als ob Ihre Zeichenfolge mit einem Ersatzpaar beginnt. Wenn Sie charAt verwenden, haben Sie möglicherweise ein unvorhersehbares Ergebnis.

12
Tagir Valeev

Hier sind drei verschiedene Lösungen für dieses Problem. Jede Lösung filtert zuerst leere Zeichenfolgen, da sonst StringIndexOutOfBoundsException ausgelöst werden kann. 

Diese Lösung entspricht der Lösung von Tagir mit dem hinzugefügten Code zum Filtern von leeren Zeichenfolgen. Ich habe es hier hauptsächlich aufgenommen, um es mit den anderen zwei Lösungen zu vergleichen, die ich bereitgestellt habe.

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

Die zweite Lösung verwendet Eclipse Collections und verwendet einen relativ neuen Containertyp namens CodePointAdapter , der in Version 7.0 hinzugefügt wurde.

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

Die dritte Lösung verwendet erneut Eclipse Collections, jedoch mit injectInto und StringBuilder anstelle von 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);

Hinweis: Ich bin ein Committer für Eclipse-Sammlungen.

3
Donald Raab

Einfacher Weg mit Methodenreferenz:

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

list.forEach(sb::append);

String concatString = sb.toString();
0
Rahul Chauhan