很好地打印 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:11:05  来源:igfitidea点击:

Printing Java Collections Nicely (toString Doesn't Return Pretty Output)

javadebuggingpretty-print

提问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:" + stackdoesn'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 ToStringHelperclass 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.debugPrintmethod which will pretty print your map.

Apache Commons 项目提供的 MapUtils 类提供了MapUtils.debugPrint一种可以漂亮地打印地图的方法。

回答by Harneet

Be careful when calling Sop on Collection, it can throw ConcurrentModificationException. Because internally toStringmethod of each Collection internally calls Iteratorover 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 mapwith Object::toStringto create Collection<String>and then use joining collector to join every item in collection with ,as delimiter.

首先我们使用mapwithObject::toString来创建Collection<String>,然后使用加入收集器将集合中的每个项目加入,作为分隔符。