如何在Java中打印指向数组的对象

时间:2012-06-22 06:37:49

标签: java arrays multidimensional-array

我有一张定义为

的地图
HashMap<Object, Object> hashMap;

现在我需要遍历每一对并打印键和值。执行key.toString()value.toString()适用于ArrayList等类型。但是数组上的toString()不会给出可读字符串。

我知道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()Arrays.deepToString()的方法。

这是解决问题的正确方法,还是有办法让这些标准方法适合我?

任何帮助都会很棒。

5 个答案:

答案 0 :(得分: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条件中。

答案 1 :(得分:0)

如果将数组转换为list然后使用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(); 
}

答案 2 :(得分:0)

您可以考虑几种方法 -
答:如果你不是严格的格式,只想以人类可读的方式打印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()并查看它产生的格式是否足够好。

答案 3 :(得分:0)

如果你使用case是以人类可读的形式呈现数组和其他对象图,你可以去模板解决方案(比如freemarker的速度)或者将它们转换为JSON(或XML)并且rpetty pring it - 我会推荐GSON / XStream为了这个任务。

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

答案 4 :(得分:0)

您可以使用9个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...