web-dev-qa-db-fra.com

Utilisation de Java 8 pour convertir une liste d'objets en une chaîne obtenue à l'aide de la méthode toString ()

Il y a beaucoup de nouveautés utiles dans Java 8. Ex., Je peux effectuer une itération avec un flux sur une liste d'objets, puis faire la somme des valeurs d'un champ spécifique des instances de Object. Par exemple.

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

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

Ainsi, je vous demande s’il existe un moyen de construire une variable String qui concatène la sortie de la méthode toString() à partir des instances d’une seule ligne.

List<Integer> list = ...

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

Supposons que list contienne des entiers 1, 2 et 3, je suppose que concatenated est "123" ou "1,2,3".

144
mat_boy

Un moyen simple consiste à ajouter les éléments de votre liste dans une 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);

vous pouvez aussi essayer:

String s = list.stream().map(e -> e.toString()).reduce("", String::concat);

Explication: map convertit le flux Integer en flux String, puis le réduit en tant que concaténation de tous les éléments.

Note: Ceci est normal reduction qui joue dans O (n2)

pour obtenir de meilleures performances, utilisez une variable StringBuilder ou mutable reduction similaire à celle de F. Böller.

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

Ref: Réduction du flux

278
Shail016

Il existe un collecteur joining dans l'API . C'est une méthode statique dans Collectors.

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

Pas parfait à cause de l'appel nécessaire de toString, mais fonctionne. Différents délimiteurs sont possibles.

151
F. Böller

Juste au cas où quelqu'un essaierait de faire cela sans Java 8, il existe un très bon truc. List.toString () retourne déjà une collection qui ressemble à ceci:

[1,2,3]

Selon vos besoins spécifiques, ceci peut être post-traité sur ce que vous voulez tant que vos éléments de liste ne contiennent pas [] ou,.

Par exemple:

list.toString().replace("[","").replace("]","") 

ou si vos données peuvent contenir des crochets, ceci:

String s=list.toString();
s = s.substring(1,s.length()-1) 

vous obtiendrez une sortie assez raisonnable.

Un élément de tableau sur chaque ligne peut être créé comme ceci:

list.toString().replace("[","").replace("]","").replaceAll(",","\r\n")

J'ai utilisé cette technique pour créer des info-bulles HTML à partir d'une liste dans une petite application, avec quelque chose comme:

list.toString().replace("[","<html>").replace("]","</html>").replaceAll(",","<br>")

Si vous avez un tableau, commencez par Arrays.asList (list) .toString () à la place

Je reconnais tout à fait que ce n'est pas optimal, mais ce n'est pas aussi inefficace qu'on pourrait le penser et c'est assez simple à lire et à comprendre. Cependant, il est assez rigide - en particulier, n'essayez pas de séparer les éléments avec replaceAll si vos données peuvent contenir des virgules, mais utilisez la version de sous-chaîne si vos données sont entre crochets, parfait.

10
Bill K

Les autres réponses sont bien. Cependant, vous pouvez également passer Collectors.toList () en tant que paramètre à Stream.collect () pour renvoyer les éléments sous forme de ArrayList.

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

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

1
Rekha Ghanate
String actual = list.stream().reduce((t, u) -> t + "," + u).get();
1
Joe Almore

Pouvons-nous essayer ceci.

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

    }
0
Kumar Abhishek

Tester les deux approches suggérées dans Shail016 et bpedroso answer ( https://stackoverflow.com/a/24883180/2832140 ), le simple StringBuilder + append(String) dans une boucle for, semble exécuter beaucoup plus rapide que list.stream().map([...].

Exemple: Ce code parcourt un Map<Long, List<Long>> construit une chaîne json, à l'aide de 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());
}

Sur ma machine virtuelle dev, junit prend généralement entre 0,35 et 1,2 seconde pour exécuter le test. En utilisant ce code suivant, cela prend entre 0,15 et 0,33 seconde:

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());
}
0
Lorenzo Cipriani
List<String> list = Arrays.asList("One", "Two", "Three");
    list.stream()
            .reduce("", org.Apache.commons.lang3.StringUtils::join);

Ou 

List<String> list = Arrays.asList("One", "Two", "Three");
        list.stream()
                .reduce("", (s1,s2)->s1+s2);

Cette approche vous permet également de générer un résultat sous forme de chaîne à partir d'une liste d'objets Exemple 

List<Wrapper> list = Arrays.asList(w1, w2, w2);
        list.stream()
                .map(w->w.getStringValue)
                .reduce("", org.Apache.commons.lang3.StringUtils::join);

Ici, la fonction de réduction vous permet d’avoir une valeur initiale à laquelle vous souhaitez ajouter une nouvelle chaîne Exemple:

 List<String> errors = Arrays.asList("er1", "er2", "er3");
            list.stream()
                    .reduce("Found next errors:", (s1,s2)->s1+s2);
0
0vint0