Java 列阵图的打印

Java 列阵图的打印,java,arrays,string,map,Java,Arrays,String,Map,我要做的是记录一个复杂的HashMap,其中包含多种对象,但我事先不知道其结构。Map自己的toString方法的唯一问题是,当它运行到数组及其自己的toString`方法中时,输出的信息不足: {array=[Ljava.lang.Object;@6c22c95b} 我能实现记录地图的最佳方法是什么 示例代码段: public static void main(String[] args) { final Map<String, Object> map = new Has

我要做的是记录一个复杂的
HashMap
,其中包含多种对象,但我事先不知道其结构。
Map自己的
toString
方法的唯一问题是,当它运行到数组及其自己的
toString`方法中时,输出的信息不足:

{array=[Ljava.lang.Object;@6c22c95b}
我能实现记录
地图的最佳方法是什么

示例代码段:

public static void main(String[] args) {
    final Map<String, Object> map = new HashMap<String, Object>();
    final Object[] array = new Object[] {"hep", 1, true};
    map.put("array", array);
    System.out.println(map);
}

您需要迭代并打印数组的内容,如

 java.util.Arrays.toString(array);

你有两种可能

首先将地图更改为包含集合而不是数组
toString()
AbstractCollection
的方法使用元素本身的
toString
创建集合元素的良好视图,因此如果元素的
toString
足够好,那么整个视图也将是可读的


另一种可能是迭代映射条目,并使用
Arrays.toString(arr)
创建数组的字符串表示形式。通常,记录器足够灵活,可以很容易地进行开箱即用的操作,例如使用log4j的格式化程序

这确实是Java的黑暗角落之一


您可以使用提供的外部库。

您可以定义自己的映射,扩展法线映射并覆盖.toString()
然后依次检查对象是否是数组的实例,并以不同的方式处理打印。

除非值对象正确覆盖其
toString
方法,否则仅通过打印对象无法打印有意义的日志。但也有可能使用Java反射。使用
java.lang.reflect
必须获取字段(仅用于公共字段)及其值。如果字段中提到的对象没有覆盖
toString
方法,则需要再次使用反射

Object object = map.get(key);
Class<?> klass = object.getClass(); // but it supports only public fields
Fields[] fields = klaa.getFields();

for (Field field: fields) {
 // get the values from the field . Check with the API
}
objectobject=map.get(键);
类klass=object.getClass();//但它只支持公共字段
Fields[]Fields=klaa.getFields();
用于(字段:字段){
//从字段中获取值。使用API进行检查
}

如果字段是私有字段,并且如果您确定getter方法可用于这些字段,则可以使用反射调用这些字段并打印它们

你解决了错误的问题。使用数组映射而不是数组映射,一切都会更好,包括字符串表示。如果不想使用外部库,请使用
Map
。所有标准列表实现都提供适当的
toString()
方法


顺便说一句,混合数组通常是一种代码味道。您应该尝试创建数组内容的对象表示形式。

这里有两个简单的实用方法可能会起作用

public static String toString(Object[] array) {
    if (array == null) return "null";
    final StringBuilder b = new StringBuilder("[");
    for (Object o : array) {
        if (b.length() > 0) b.append(", ");
        if (o == null) {
            b.append("null");
        } else if (o instanceof Map) {
            b.append(toString((Map) o));
        } else if (o.getClass().isArray()) {
            b.append(toString((Object[]) o));
        } else {
            b.append(o.toString());
        }
    }
    return b.append("]").toString();
}

public static String toString(Map map) {
    if (map == null) return "null";
    final StringBuilder b = new StringBuilder("{");
    for (Object key : map.keySet()) {
        final Object value = map.get(key);
        b.append(key).append("=");
        if (value == null) {
            b.append("null");
        } else {
            if (value.getClass().isArray()) {
                b.append(toString((Object[]) value, ", "));
            } else if (value instanceof Map) {
                b.append(toString((Map) value));
            } else {
                b.append(value);
            }
        }
    }
    return b.append("}").toString();
}
这些内容改编自我的个人便捷实用程序库:


您的第一个建议的问题是,我无法更改对象,它就是这样。我需要记录并转发。我正在使用slf4j。你能更具体一点使用日志格式化程序吗?嗯,这到底是怎么回事。只需打印ReflectionStringBuilder.toString(映射)就可以生成java.util。HashMap@68ab95e6[阈值=12,负载系数=0.75]
public static String toString(Object[] array) {
    if (array == null) return "null";
    final StringBuilder b = new StringBuilder("[");
    for (Object o : array) {
        if (b.length() > 0) b.append(", ");
        if (o == null) {
            b.append("null");
        } else if (o instanceof Map) {
            b.append(toString((Map) o));
        } else if (o.getClass().isArray()) {
            b.append(toString((Object[]) o));
        } else {
            b.append(o.toString());
        }
    }
    return b.append("]").toString();
}

public static String toString(Map map) {
    if (map == null) return "null";
    final StringBuilder b = new StringBuilder("{");
    for (Object key : map.keySet()) {
        final Object value = map.get(key);
        b.append(key).append("=");
        if (value == null) {
            b.append("null");
        } else {
            if (value.getClass().isArray()) {
                b.append(toString((Object[]) value, ", "));
            } else if (value instanceof Map) {
                b.append(toString((Map) value));
            } else {
                b.append(value);
            }
        }
    }
    return b.append("}").toString();
}