我希望打印一个Stack<Integer>对象,就像Eclipse调试器做的那样(即[1,2,3…]),但打印它与out = "output:" + Stack不会返回这个好结果。
澄清一下,我说的是Java的内置集合,所以我不能重写它的toString()。
我怎样才能得到一个漂亮的可打印版本的堆栈?
我希望打印一个Stack<Integer>对象,就像Eclipse调试器做的那样(即[1,2,3…]),但打印它与out = "output:" + Stack不会返回这个好结果。
澄清一下,我说的是Java的内置集合,所以我不能重写它的toString()。
我怎样才能得到一个漂亮的可打印版本的堆栈?
当前回答
JSON
另一种解决方案是将您的集合转换为JSON格式并打印JSON - string。其优点是格式良好且可读的Object-String,而不需要实现toString()。
使用谷歌的Gson的示例:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
...
printJsonString(stack);
...
public static void printJsonString(Object o) {
GsonBuilder gsonBuilder = new GsonBuilder();
/*
* Some options for GsonBuilder like setting dateformat or pretty printing
*/
Gson gson = gsonBuilder.create();
String json= gson.toJson(o);
System.out.println(json);
}
其他回答
番石榴看起来是个不错的选择:
Iterables.toString (myIterable)
你可以把它转换成一个数组,然后用Arrays.toString(Object[])打印出来:
System.out.println(Arrays.toString(stack.toArray()));
system . out。println(集合c)已经以可读格式打印任何类型的集合。只有当集合包含用户定义的对象时,才需要在用户定义的类中实现toString()来显示内容。
现在在java (Java7/8)中,大多数集合都有一个有用的toString()。 所以不需要做流操作来连接你需要的东西,只需要在集合中重写你的值类的toString,你就可以得到你需要的东西。
AbstractMap和AbstractCollection都通过对每个元素调用toString来实现toString()。
下面是一个显示行为的测试类。
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> 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<Integer, Foo> 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 }}
}
}
更新Java 14(2020年3月)
记录现在是一个预览功能,如果类只保存数据,则不需要重写toString()。记录实现了一个数据契约,为您的方便提供了对字段的公共只读访问,并实现了默认函数,如比较,toString和hashcode。
所以一旦可以实现Foo的行为如下:
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
public class ToString {
static record Foo(int i) { }
public static void main(String[] args) {
Foo f = new Foo(10);
System.out.println(f.toString());
// prints: Foo[i=10]
List<Foo> 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: [Foo[i=10], Foo[i=12], Foo[i=13], Foo[i=14]]
Map<Integer, Foo> 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=Foo[i=10], 12=Foo[i=12], 13=Foo[i=13], 14=Foo[i=14]}
}
}
使用java 8流和收集器可以轻松完成:
String format(Collection<?> c) {
String s = c.stream().map(Object::toString).collect(Collectors.joining(","));
return String.format("[%s]", s);
}
首先,我们使用map和Object::toString来创建Collection<String>,然后使用join collector来连接Collection中的每个项,作为分隔符。