2012-10-11 122 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,我個人的方便的工具庫: