正确打印Java集合(toString不返回漂亮的输出)

我希望像Eclipsedebugging器那样打印一个Stack<Integer>对象(即[1,2,3...] ),但用out = "output:" + stack打印并不会返回这个好结果。

为了澄清,我正在谈论Java的内置集合,所以我不能覆盖它的toString()

我怎样才能得到一个不错的打印版本的堆栈?

你可以将它转换为数组,然后用Arrays.toString(Object[])打印出来:

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

(Java 8)

Apache Commons项目提供的MapUtils类提供了一个MapUtils.debugPrint方法,它将很好地打印您的地图。

使用java 8stream和收集器可以轻松完成:

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

首先我们使用Object::toString来创buildCollection<String> ,然后使用连接收集器以分隔符的formsjoin集合中的每个项目。

在类上实现toString()。

我推荐使用Apache Commons ToStringBuilder来简化这个过程。 有了它,你只需要写这种方法:

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

为了得到这样的输出:

人@ 7f54 [名称=斯蒂芬,年龄= 29]

还有一个反思的实现 。

我同意上面关于在你自己的类上重写toString()意见(并尽可能地使这个过程自动化)。

对于你没有定义的类,你可以写一个ToStringHelper类,并为每个你想要处理的类库重载一个方法:

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

编辑:回应xukxpvfzflbbld的评论,这是前面提到的情况下可能的实现。

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

这不是一个完整的实现,而只是一个启动器。

System.out.println(Collection c)已经以可读格式打印任何types的集合。 只有集合包含用户定义的对象时,则需要在用户定义的类中实现toString()以显示内容。

您可以使用JAVA中“Objects”类 (从1.7开始可用)

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

产量:1273,123,876,897

另一种可能是使用Google Guave中“MoreObjects”类 ,它提供了许多有用的帮助函数:

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

输出:NameOfYourObject = [1273,123,876,897]

番石榴文档

番石榴看起来是个不错的select:

Iterables.toString(myIterable)

在Java8中

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

要么

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

Just修改了前面的例子,甚至可以打印包含用户定义对象的集合。

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

如果这是您自己的集合类而不是内置类,则需要重写其toString方法。 Eclipse对于没有硬连线格式的任何对象调用该函数。

在Collection上调用Sop时要小心,它会抛出ConcurrentModification Exception。 因为每个集合的内部toString方法在集合内部调用Iterator

应该为除Map之外的任何集合工作,但也很容易支持。 如果需要,修改代码以传递这3个字符作为参数。

 static <T> String seqToString(Iterable<T> 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(); } 

你可以尝试使用

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

Apache Commons 3 ,你想打电话

 StringUtils.join(myCollection, ",")