正确打印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, ",")