1

我有一张地图,其定义如下

HashMap<Object, Object> hashMap;

现在我需要遍历每一对并打印键和值。对于像. key.toString()_ 但是在数组上不会给出可读的字符串。value.toString()ArrayListtoString()

我知道Arrays.toString(). 但我不能在我的情况下使用它,因为Arrays.toString()需要一个对象数组,而我所拥有的只是一个对象。所以我写了一个自定义代码,看起来像,

private String convertToHumanReadableFormat(Object value) {
    if (value == null) return "N/A";
    if (value.getClass().isArray()) {
        return convertArrayToReadableFormat(value);
    }
    return value.toString();
}

private String convertArrayToReadableFormat(Object value) {
    String output = "[";
    int arrayLength = Array.getLength(value);
    for (int i = 0; i < arrayLength; i++) {
        Object element = Array.get(value, i);
        if (element != null) {
            if (element.getClass().isArray()) {
                output += convertArrayToReadableFormat(element);
            }
            else {
                output += element.toString();
            }
        }
        if ((i + 1) < arrayLength)
            output += ", ";
    }
    output += "]";
    return output;
}

我实际上是在复制什么Arrays.deepToString()。但我看不到只使用Arrays.toString()or的方法Arrays.deepToString()

这是解决问题的正确方法还是有什么方法可以让这些标准方法为我工作?

任何帮助都会很棒。

4

5 回答 5

1

请将方法修改convertToHumanReadableFormat为以下。我已经对其进行了测试,并且确实有效。

private <T> String convertToHumanReadableFormat(Object value) {
            if (value == null) return "N/A";
            if (value.getClass().isArray()) {
                if( value instanceof int[]||value instanceof long[]){
                    List<T> list = new ArrayList<T>();
                    list.addAll((Collection<? extends T>) Arrays.asList(value));
                    return convertToHumanReadableFormat(list.toArray());

                }else{
                     return Arrays.deepToString((Object[]) value);
                }
            }
            return value.toString();
        }

您可以将其他原始类型添​​加到 if 条件。

于 2012-06-22T06:54:34.620 回答
0

您可以只使用九个 instanceof 语句来调用适当的 toString 或 deepToString 方法。如果您确实使用自己的代码,请记住使用 StringBuilder 并考虑包含对自身或父维度的引用的数组的可能性。目前,您的代码将递归直到堆栈溢出。按照我的建议使用 instanceof 还可以避免代码中固有的原始值的装箱(从而提高性能)。九个语句也不算多吧?

if (val instanceof Object[]) return Arrays.deepToString((Object[]) val);
if (val instanceof byte[]) return Arrays.toString((byte[]) val);
// Repeat for other 7 array types...
于 2012-06-22T08:27:29.157 回答
0

您可以考虑几种方法 -
A. 如果您对格式不严格,并且只想以人类可读的方式打印 HashMap 内容,我建议您使用 JSon 序列化 - 如果非常可读,则输出.
你可以看到我们在Ovirt开源项目中所做的(克隆引擎项目的 git repo) - engine\backend\manager\modules\utils\src\main\java\org\ovirt\engine\core\utils\serialization\ json - 看看那里的 JsonObjectSerializer 类。

B. 如果您对格式有严格要求 - 您应该获取地图的 entrySet,对其进行迭代,然后将对象插入到 ArrayList 中。之后,您可以使用 toArray() 方法返回一个数组,并使用您上面描述的方法。
请记住,我建议您的 ArrayList 将是字符串的 ArrayList,因此您必须获取每个 mapEntry 并将其转换为字符串,考虑 toString() 并查看它生成的格式是否适合您。

于 2012-06-22T06:53:16.860 回答
0

如果您的用例是以人类可读的形式呈现数组和其他对象图,您可以使用模板解决方案(如 freemarker 的速度)或将它们转换为 JSON(或 XML)并重新启动它 - 我会推荐 GSON / XStream 来完成这项任务.

如果您希望将其用于调试目的,那么只需坚持使用日志系统并使用那里可用的标准转换器(例如在 log4j 中)

于 2012-06-22T06:53:31.433 回答
0

如果您将数组转换为列表然后使用 toString -

Arrays.asList(array)

您将需要以这种方式编写您的辅助方法 -

private String convertToHumanReadableFormat(Object value) {
    if (value == null) return "N/A";
    if (value.getClass().isArray()) {
       value = Arrays.asList((Object[])value);     
    }     
    return value.toString(); 
} 

要处理原语,您需要首先手动将数组转换为列表 -

private String convertToHumanReadableFormat(Object value) {
    if (value == null) return "N/A";
    if (value.getClass().isArray()) {

       //convert array to list 
       int count = Array.getLength(value);
       ArrayList<Object> list = new ArrayList<Object>();
       for(int i=0; i<count; i++){
          list.add(Array.get(value, i));
       } 
       return list.toString(); //or value=list;  
    }     
    return value.toString(); 
}
于 2012-06-22T06:42:04.240 回答