234 votes

Imprimer les collections Java de manière agréable (toString ne renvoie pas une jolie sortie)

Je souhaite imprimer un Stack<Integer> aussi bien que le fait le débogueur d'Eclipse (c.-à-d. [1,2,3...] ) mais en l'imprimant avec out = "output:" + stack ne renvoie pas ce beau résultat.

Pour clarifier, je parle de la collection intégrée de Java, je ne peux donc pas surcharger sa fonction toString() .

Comment puis-je obtenir une version imprimable de la pile ?

9 votes

Au moins à partir de Java 7, AbstractCollection@toString (et donc String + Stack ) l'imprime déjà comme vous le souhaitez.

0 votes

346voto

Zach Langley Points 3523

Vous pouvez le convertir en un tableau et l'imprimer avec Arrays.toString(Object[]) :

System.out.println(Arrays.toString(stack.toArray()));

12 votes

Je l'aime bien. C'est simple, c'est propre. Pour être honnête, Collections a aussi besoin d'une méthode toString, mais celle-ci fonctionne aussi.

1 votes

@Tovi7 Ce n'est probablement pas le cas parce que la plupart des collections OOTB fournissent déjà des toString()s lisibles, ce qui n'est pas le cas des tableaux.

0 votes

@Boosha il faut aussi O(n) temps pour convertir la pile en une chaîne et O(n) temps pour imprimer la chaîne sur la console.

18voto

tlavarea Points 81

La classe MapUtils proposée par le projet Apache Commons offre une fonction MapUtils.debugPrint qui imprimera joliment votre carte.

1 votes

Pas que je sache. Je ne connais pas très bien la bibliothèque Guava, mais je ne serais pas surpris qu'il y en ait une.

0 votes

Ce n'est pas nécessaire, du moins dans Java 6, car AbstractMap#toString le fait déjà. La seule question qui se pose est celle de la carte : stackoverflow.com/questions/2828252/map-to-string-in-java

13voto

Shekhar Points 71

System.out.println(Collection c) permet déjà d'imprimer n'importe quel type de collection dans un format lisible. Seulement si la collection contient des objets définis par l'utilisateur, vous devez implémenter toString() dans la classe définie par l'utilisateur pour afficher le contenu.

11voto

Chinnery Points 5830

Implémenter la fonction toString() dans la classe.

Je recommande le Apache Commons ToStringBuilder pour faciliter les choses. Avec lui, il suffit d'écrire ce genre de méthode :

public String toString() {
     return new ToStringBuilder(this).
       append("name", name).
       append("age", age).
       toString(); 
}

Pour obtenir ce type de résultat :

Person@7f54[name=Stephen,age=29]

Il existe également un mise en œuvre réfléchie .

0 votes

ToStringBuilder s'applique généralement mieux aux haricots et aux objets qui transportent des informations, mais moins aux structures de données complexes. Si l'objet pile n'imprime pas tous les éléments stockés, cela ne servira à rien.

2 votes

L'utilisation de la réflexion ToStringBuilder, HashCodeBuilder et EqualsBuilder est très inefficace. Bien que le résultat soit correct, ces classes sont loin d'être le pic de performance de la semaine...

2 votes

La question dit explicitement que la classe est une collection intégrée, donc toString() ne peut pas être modifiée.

8voto

joel.neely Points 17059

Je suis d'accord avec les commentaires précédents concernant l'utilisation de l'option "overriding". toString() sur vos propres classes (et d'automatiser ce processus autant que possible).

Pour les cours, vous n'a pas vous pourriez écrire un ToStringHelper avec une méthode surchargée pour chaque classe de la bibliothèque que vous souhaitez gérer à votre guise :

public class ToStringHelper {
    //... instance configuration here (e.g. punctuation, etc.)
    public toString(List m) {
        // presentation of List content to your liking
    }
    public toString(Map m) {
        // presentation of Map content to your liking
    }
    public toString(Set m) {
        // presentation of Set content to your liking
    }
    //... etc.
}

EDIT : En réponse au commentaire de xukxpvfzflbbld, voici une implémentation possible pour les cas mentionnés précédemment.

package com.so.demos;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class ToStringHelper {

    private String separator;
    private String arrow;

    public ToStringHelper(String separator, String arrow) {
        this.separator = separator;
        this.arrow = arrow;
    }

   public String toString(List<?> l) {
        StringBuilder sb = new StringBuilder("(");
        String sep = "";
        for (Object object : l) {
            sb.append(sep).append(object.toString());
            sep = separator;
        }
        return sb.append(")").toString();
    }

    public String toString(Map<?,?> m) {
        StringBuilder sb = new StringBuilder("[");
        String sep = "";
        for (Object object : m.keySet()) {
            sb.append(sep)
              .append(object.toString())
              .append(arrow)
              .append(m.get(object).toString());
            sep = separator;
        }
        return sb.append("]").toString();
    }

    public String toString(Set<?> s) {
        StringBuilder sb = new StringBuilder("{");
        String sep = "";
        for (Object object : s) {
            sb.append(sep).append(object.toString());
            sep = separator;
        }
        return sb.append("}").toString();
    }

}

Il ne s'agit pas d'une mise en œuvre complète, mais seulement d'un point de départ.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X