Impresión de colecciones de Java muy bien (toString no devuelve bastante salida)

Deseo imprimir un objeto Stack tan bien como lo hace el depurador Eclipse (es decir [1,2,3...] ) pero imprimirlo con out = "output:" + stack no devuelve este buen resultado.

Solo para aclarar, estoy hablando de la colección integrada de Java, así que no puedo anular su toString() .

¿Cómo puedo obtener una buena versión imprimible de la stack?

Puede convertirlo en una matriz y luego imprimirlo con Arrays.toString(Object[]) :

 System.out.println(Arrays.toString(stack.toArray())); 
 String.join(",", yourIterable); 

(Java 8)

La clase MapUtils que ofrece el proyecto Apache Commons ofrece un método MapUtils.debugPrint que imprimirá su mapa bastante.

Con java 8 streams y coleccionistas se puede hacer fácilmente:

 String format(Collection c) { String s = c.stream().map(Object::toString).collect(Collectors.joining(",")); return String.format("[%s]", s); } 

primero usamos el map con Object::toString para crear Collection y luego usamos join collector para unir cada elemento en la colección con , como delimitador.

Implementar toString () en la clase.

Recomiendo Apache Commons ToStringBuilder para hacer esto más fácil. Con eso, solo tienes que escribir este tipo de método:

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

Para obtener este tipo de resultados:

Persona @ 7f54 [nombre = Stephen, edad = 29]

También hay una implementación reflexiva .

System.out.println (Collection c) ya imprime cualquier tipo de colección en formato legible. Solo si la colección contiene objetos definidos por el usuario, entonces debe implementar toString () en una clase definida por el usuario para mostrar el contenido.

Estoy de acuerdo con los comentarios anteriores sobre anular toString() en sus propias clases (y sobre automatizar ese proceso tanto como sea posible).

Para las clases que no definió, podría escribir una clase ToStringHelper con un método sobrecargado para cada clase de biblioteca que desee que haya manejado según sus propios gustos:

 public class ToStringHelper { //... instance configuration here (eg 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. } 

EDITAR: Respondiendo al comentario de xukxpvfzflbbld, aquí hay una posible implementación para los casos mencionados anteriormente.

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

Esta no es una implementación completa, sino solo un comienzo.

Guava parece una buena opción:

Iterables.toString(myIterable)

Puede usar la clase “Objetos” de JAVA (que está disponible desde 1.7)

 Collection myCollection = Arrays.asList("1273","123","876","897"); Objects.toString(myCollection); 

Salida: 1273, 123, 876, 897

Otra posibilidad es usar la clase “MoreObjects” de Google Guave , que proporciona muchas de las útiles funciones de ayuda:

 MoreObjects.toStringHelper(this).add("NameOfYourObject", myCollection).toString()); 

Salida: NameOfYourObject = [1273, 123, 876, 897]

Guava documenta

En Java8

 //will prints each element line by line stack.forEach(System.out::println); 

o

 //to print with commas stack.forEach( (ele)->{ System.out.print(ele+","); } ); 

Con Apache Commons 3 , quieres llamar

 StringUtils.join(myCollection, ",") 

Just Modificado el ejemplo anterior para imprimir incluso la colección que contiene objetos definidos por el usuario.

 public class ToStringHelper { private static String separator = "\n"; public ToStringHelper(String seperator) { super(); ToStringHelper.separator = seperator; } public static String toString(List l) { StringBuilder sb = new StringBuilder(); String sep = ""; for (Object object : l) { String v = ToStringBuilder.reflectionToString(object); int start = v.indexOf("["); int end = v.indexOf("]"); String st = v.substring(start,end+1); sb.append(sep).append(st); sep = separator; } return sb.toString(); } public static String toString(Map m) { StringBuilder sb = new StringBuilder(); String sep = ""; for (Object object : m.keySet()) { String v = ToStringBuilder.reflectionToString(m.get(object)); int start = v.indexOf("["); int end = v.indexOf("]"); String st = v.substring(start,end+1); sb.append(sep).append(st); sep = separator; } return sb.toString(); } public static String toString(Set s) { StringBuilder sb = new StringBuilder(); String sep = ""; for (Object object : s) { String v = ToStringBuilder.reflectionToString(object); int start = v.indexOf("["); int end = v.indexOf("]"); String st = v.substring(start,end+1); sb.append(sep).append(st); sep = separator; } return sb.toString(); } public static void print(List l) { System.out.println(toString(l)); } public static void print(Map m) { System.out.println(toString(m)); } public static void print(Set s) { System.out.println(toString(s)); } } 

Si esta es su propia clase de colección en lugar de una integrada, debe anular su método toString. Eclipse llama a esa función para cualquier objeto para el que no tenga un formato de conexión por cable.

Tenga cuidado al llamar a Sop on Collection, puede lanzar Excepción de ConcurrentModification . Dado que internamente el método toString de cada colección internamente llama a Iterator sobre la colección.

Debería funcionar para cualquier colección, excepto Map , pero también es fácil de mantener. Modifique el código para pasar estos 3 caracteres como argumentos si es necesario.

 static  String seqToString(Iterable items) { StringBuilder sb = new StringBuilder(); sb.append('['); boolean needSeparator = false; for (T x : items) { if (needSeparator) sb.append(' '); sb.append(x.toString()); needSeparator = true; } sb.append(']'); return sb.toString(); } 

Puedes intentar usar

 org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString(yourCollection); 

la mayoría de las colecciones tienen un útil toString() en java en estos días (Java7 / 8). Por lo tanto, no es necesario realizar operaciones de transmisión para concatenar lo que necesita, simplemente anule la toString de su clase de valor en la colección y obtendrá lo que necesita.

tanto AbstractMap como AbstractCollection implementan toString () llamando a String por elemento.

a continuación hay una clase de prueba para mostrar el comportamiento.

 import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; public class ToString { static class Foo { int i; public Foo(int i) { this.i=i; } @Override public String toString() { return "{ i: " + i + " }"; } } public static void main(String[] args) { List foo = new ArrayList<>(); foo.add(new Foo(10)); foo.add(new Foo(12)); foo.add(new Foo(13)); foo.add(new Foo(14)); System.out.println(foo.toString()); // prints: [{ i: 10 }, { i: 12 }, { i: 13 }, { i: 14 }] Map foo2 = new HashMap<>(); foo2.put(10, new Foo(10)); foo2.put(12, new Foo(12)); foo2.put(13, new Foo(13)); foo2.put(14, new Foo(14)); System.out.println(foo2.toString()); // prints: {10={ i: 10 }, 12={ i: 12 }, 13={ i: 13 }, 14={ i: 14 }} } } 
Intereting Posts