简体   繁体   English

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

[英]How to print an object which points to an array in Java

I have a map which is defined like 我有一张地图,其定义如下

HashMap<Object, Object> hashMap;

Now I need to iterate over each pair and print the key and value. 现在,我需要遍历每对并打印键和值。 Doing key.toString() and value.toString() works well for types like ArrayList . 对于诸如ArrayList类的类型,执行key.toString()value.toString()效果很好。 But toString() on an array won't give a readable string. 但是数组上的toString()不会给出可读的字符串。

I am aware about Arrays.toString() . 我知道Arrays.toString() But I can't use it in my case because Arrays.toString() expects an object array and all I have is an object. 但是我不能使用它,因为Arrays.toString()需要一个对象数组,而我所拥有的只是一个对象。 So I wrote a custom code which looks like, 所以我写了一个自定义代码,看起来像

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

I am actually duplicating what Arrays.deepToString() does. 我实际上是在复制Arrays.deepToString()功能。 But I can't see a way to just use Arrays.toString() or Arrays.deepToString() . 但是我看不到一种仅使用Arrays.toString()Arrays.deepToString()

Is this the correct approach to the problem or is there any way to get those standard methods working for me? 这是解决问题的正确方法,还是有什么方法可以使这些标准方法对我有用?

Any help would be great. 任何帮助都会很棒。

Please modify the method convertToHumanReadableFormat to the following. 请将方法convertToHumanReadableFormat修改为以下内容。 I have tested it and it indeed worked. 我已经对其进行了测试,并且确实有效。

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

You can add other primitive types to the if condition. 您可以将其他基本类型添加到if条件。

what if you convert array to list and then use toString - 如果将数组转换为列表然后使用toString怎么办?

Arrays.asList(array)

you will need to write your helper method this way - 您将需要以这种方式编写辅助方法-

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

to handle primitives you will need to first manually convert array to list - 要处理原语,您需要首先手动将数组转换为列表-

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

There are several approaches you can consider - 您可以考虑几种方法-
A. If you're not to strict on the format, and just want to print the HashMap contents in a human readable way, I would suggest you to use JSon serializing - the output if quite human readable. 答:如果您对格式不严格,只想以人类可读的方式打印HashMap内容,我建议您使用JSon序列化-如果人类可读,则输出。
You can see what we did at Ovirt open source project (clone the git repo of the engine project) - engine\\backend\\manager\\modules\\utils\\src\\main\\java\\org\\ovirt\\engine\\core\\utils\\serialization\\json - look at the JsonObjectSerializer class there. 您可以看到我们在Ovirt开源项目中所做的工作(克隆引擎项目的git repo) -engine \\ backend \\ manager \\ modules \\ utils \\ src \\ main \\ java \\ org \\ ovirt \\ engine \\ core \\ utils \\ serialization \\ json-查看那里的JsonObjectSerializer类。

B. If you are strict on the format - You should get the entrySet of your map, iterate over it, and insert the objects into an ArrayList . B.如果您对格式有严格要求-您应该获取地图的entrySet,对其进行迭代,然后将对象插入ArrayList中。 After that you can use the toArray() method to return an array, and use the method you described above. 之后,您可以使用toArray()方法返回一个数组,并使用上述方法。
Bare in mind that I suggest that your ArrayList will be an ArrayList of Strings, so you must take each mapEntry and translate it string, consider the toString() and see if the format it produces is good enough for you. 切记,我建议您的ArrayList将是一个字符串的ArrayList,因此您必须获取每个mapEntry并将其转换为字符串,考虑使用toString()并查看其生成的格式是否足够适合您。

If you use case is rendering arrays and other object graphs in human readable form you may go for templating solution (like velocity of freemarker) or convert them to JSON (or XML) and rpetty pring it - I would recommend GSON / XStream for this task. 如果用例是以人类可读的形式渲染数组和其他对象图,则可以使用模板解决方案(例如freemarker的速度)或将它们转换为JSON(或XML)并对其进行伪造-对于此任务,我建议使用GSON / XStream 。

If you like to have it for debug purposes, then just stick with logging system and use standart converters available there ( for example in log4j) 如果您希望将其用于调试目的,则只需坚持使用日志记录系统并使用那里可用的标准转换器(例如,在log4j中)

You could just use nine instanceof statements to call the appropriate toString or deepToString method. 您可以只使用九个instanceof语句来调用适当的toString或deepToString方法。 If you do use your own code, remember to use a StringBuilder and to take into account the possibility of an array containing a reference to itself or a parent dimension. 如果确实使用自己的代码,请记住使用StringBuilder并考虑到数组包含对自身或父维度的引用的可能性。 Currently your code would recurse until stack overflow. 当前,您的代码将递归直到堆栈溢出。 Using instanceof as I suggest would also avoid the boxing of primitive values that is inherent in your code (and thus improve performance). 我建议使用instanceof还可以避免将代码固有的原始值装箱(从而提高性能)。 Nine statements isn't too many, is it? 九个陈述不是很多,是吗?

if (val instanceof Object[]) return Arrays.deepToString((Object[]) val);
if (val instanceof byte[]) return Arrays.toString((byte[]) val);
// Repeat for other 7 array types...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM