很好地打印 Java 集合(toString 不返回漂亮的输出)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/395401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing Java Collections Nicely (toString Doesn't Return Pretty Output)
提问by Elazar Leibovich
I wish to print a Stack<Integer>
object as nicely as the Eclipse debugger does (i.e. [1,2,3...]
) but printing it with out = "output:" + stack
doesn't return this nice result.
我希望Stack<Integer>
像 Eclipse 调试器那样打印一个对象(即[1,2,3...]
),但是打印它out = "output:" + stack
不会返回这个好的结果。
Just to clarify, I'm talking about Java's built-in collection so I can't override its toString()
.
澄清一下,我说的是 Java 的内置集合,所以我不能覆盖它的toString()
.
How can I get a nice printable version of the stack?
我怎样才能得到一个漂亮的可打印版本的堆栈?
采纳答案by Zach Langley
You could convert it to an array and then print that out with Arrays.toString(Object[])
:
您可以将其转换为数组,然后使用Arrays.toString(Object[])
以下命令将其打印出来:
System.out.println(Arrays.toString(stack.toArray()));
回答by Uri
If this is your own collection class rather than a built in one, you need to override its toString method. Eclipse calls that function for any objects for which it does not have a hard-wired formatting.
如果这是您自己的集合类而不是内置类,则需要覆盖其 toString 方法。Eclipse 为它没有硬连线格式的任何对象调用该函数。
回答by Chinnery
Implement toString() on the class.
在类上实现 toString()。
I recommend the Apache Commons ToStringBuilderto make this easier. With it, you just have to write this sort of method:
我推荐Apache Commons ToStringBuilder使这更容易。有了它,你只需要编写这样的方法:
public String toString() {
return new ToStringBuilder(this).
append("name", name).
append("age", age).
toString();
}
In order to get this sort of output:
为了获得这种输出:
Person@7f54[name=Stephen,age=29]
Person@7f54[name=Stephen,age=29]
There is also a reflective implementation.
还有一个反射实现。
回答by joel.neely
I agree with the above comments about overriding toString()
on your own classes (and about automating that process as much as possible).
我同意上述关于覆盖toString()
您自己的类(以及尽可能自动化该过程)的评论。
For classes you didn'tdefine, you could write a ToStringHelper
class with an overloaded method for each library class you want to have handled to your own tastes:
对于您没有定义的ToStringHelper
类,您可以为每个要根据自己喜好处理的库类编写一个带有重载方法的类:
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: Responding to the comment by xukxpvfzflbbld, here's a possible implementation for the cases mentioned previously.
编辑:回应 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();
}
}
This isn't a full-blown implementation, but just a starter.
这不是一个完整的实现,而只是一个开始。
回答by Shekhar
System.out.println(Collection c) already print any type of collection in readable format. Only if collection contains user defined objects , then you need to implement toString() in user defined class to display content.
System.out.println(Collection c) 已经以可读格式打印任何类型的集合。仅当集合包含用户定义的对象时,才需要在用户定义的类中实现 toString() 来显示内容。
回答by Shekhar
Just Modified the previous example to print even collection containing user defined objects.
刚刚修改了前面的示例以打印包含用户定义对象的偶数集合。
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));
}
}
回答by tlavarea
The MapUtils class offered by the Apache Commons project offers a MapUtils.debugPrint
method which will pretty print your map.
Apache Commons 项目提供的 MapUtils 类提供了MapUtils.debugPrint
一种可以漂亮地打印地图的方法。
回答by Harneet
Be careful when calling Sop on Collection, it can throw ConcurrentModification
Exception. Because internally toString
method of each Collection internally calls Iterator
over the Collection.
在 Collection 上调用 Sop 时要小心,它可能会抛出ConcurrentModification
异常。因为toString
每个 Collection 的内部方法在内部调用Iterator
了 Collection。
回答by Display Name
Should work for anycollection except Map
, but it's easy to support, too.
Modify code to pass these 3 chars as arguments if needed.
应该适用于除 之外的任何集合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();
}
回答by bsmk
With java 8 streams and collectors it can be done easily:
使用 java 8 流和收集器可以轻松完成:
String format(Collection<?> c) {
String s = c.stream().map(Object::toString).collect(Collectors.joining(","));
return String.format("[%s]", s);
}
first we use map
with Object::toString
to create Collection<String>
and then use joining collector to join every item in collection with ,
as delimiter.
首先我们使用map
withObject::toString
来创建Collection<String>
,然后使用加入收集器将集合中的每个项目加入,
作为分隔符。