2012-10-11 49 views
2

我想要做的是用多种对象记录一个复杂的HashMap<String, Object>,我事先不知道结构。只有具有Map's own的toString method is that when it runs in to arrays and their own toString`方法问题的输出小于信息:阵列的打印地图

{array=[Ljava.lang.Object;@6c22c95b} 

什么是我可以实现的方式来记录Map的最佳方式?

示例代码片段:

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); 
} 

输出:

{array=[Ljava.lang.Object;@6c22c95b} 

回答

0

需要迭代和打印数组的内容就像

java.util.Arrays.toString(array); 
2

你有两种可能性。

首先将您的地图更改为包含集合而不是数组。 toString()方法AbstractCollection使用元素本身的toString创建收集元素的好看法,因此如果元素的toString足够好,则总视图也可以读取。

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

+0

与你的第一个建议的问题是,我不能改变的对象,它就是这样。我需要记录它并将其传递给它。 – user1737468

+0

我正在使用slf4j。您能否更具体地使用日志格式化程序? – user1737468

0

这实际上是Java的黑暗角落之一。

您可以使用外部库Apache Commons Lang,比如它提供了ReflectionToStringBuilder

+0

嗯,这真的有效。仅仅通过打印ReflectionToSTringBuilder.toString(map)就会产生[email protected] [threshold = 12,loadFactor = 0.75] – user1737468

0

那么你可以定义你自己的地图,扩大正常的地图和阴影.toString() 然后依次检查对象是否是instanceof数组和处理打印的方式不同。

0

除非值Object正确地覆盖了它的toString方法,否则只能通过打印Object来打印有意义的日志。但是有可能使用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 
} 

如果字段是私有字段,如果你确信,对于那些getter方法,那么你可以使用反射调用这些并打印。

0

你正在解决错误的问题。使用Guava Multimap而不是数组的地图,一切都会更好,包括字符串表示。如果您不想使用外部库,请使用Map<String, List<Object>>。所有标准列表实现都提供了适当的toString()方法。

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

0

这里有一些简单的实用方法,可能工作。

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(); 
} 

这些都是改编自cobbzilla-utils,我个人的方便的工具库: