【问题标题】:Print arrays in Java在 Java 中打印数组
【发布时间】:2012-01-18 19:15:27
【问题描述】:

我正在编写一个方法来打印它通过的每个对象。通过为对象调用Object.toString() 方法可以正常工作,但不适用于数组。我可以用Object.getClass().isArray()方法判断它是否是一个Array,但我不知道如何转换它。

int[] a;
Integer[] b;

Object aObject = a;
Object bObject = b;

// this wouldn't work
System.out.println(Arrays.toString(aObject));
System.out.println(Arrays.toString(bObject));

【问题讨论】:

    标签: java arrays casting tostring


    【解决方案1】:

    如果您不知道类型,您可以将对象转换为Object[] 并像这样打印(在确保它确实是一个数组并且可以转换为Object[] 之后)。如果不是Object[] 的实例,则先使用反射创建Object[],然后打印:

    private void printAnyArray(Object aObject) {
        if (aObject.getClass().isArray()) {
            if (aObject instanceof Object[]) // can we cast to Object[]
                System.out.println(Arrays.toString((Object[]) aObject));
            else {  // we can't cast to Object[] - case of primitive arrays
                int length = Array.getLength(aObject);
                Object[] objArr = new Object[length];
                for (int i=0; i<length; i++)
                    objArr[i] =  Array.get(aObject, i);
                System.out.println(Arrays.toString(objArr));
            }
        }
    }
    

    测试:

    printAnyArray(new int[]{1, 4, 9, 16, 25});
    printAnyArray(new String[]{"foo", "bar", "baz"});
    

    输出:

    [1, 4, 9, 16, 25]
    [foo, bar, baz]
    

    【讨论】:

    • 我怎样才能知道它是否是一个原始数组?我还需要知道数组的原始类型。
    • 请检查更新后的代码,它会现在打印任何数组对象,而无需您在if/elseif/else的丑陋链中强制转换为每个原始类型
    • 有趣的更新,虽然反射和自动装箱的额外费用值得一提。
    • @PaulBellora 我已经阅读了大量警告不要使用所谓的“昂贵”反射的文章,但也看到几乎所有现代框架都在充分利用它。阅读此内容,例如:buzdin.blogspot.com/2011/01/is-java-reflection-really-slow.html 我的 2 美分:确保您有一个很好的用例来使用反射,恕我直言,这个问题非常适合。
    • 太棒了,正是我需要的。
    【解决方案2】:

    如果您要问如何在任何数组上以编程方式调用此方法,那么原始数组将无法实现。查看Arrays 类的文档,您会发现每个原始数组类型都有toString() 的重载。

    这是因为 int[] 例如扩展了 Object 而不是 Object[]

    编辑:这是一个包含原始数组的令人遗憾的冗长解决方案:

    public static void printObject(Object obj) {
    
        String output;
    
        if (obj == null) {
            output = "null";
        }
        else if (obj.getClass().isArray()) {
    
            if (obj instanceof Object[]) {
                output = Arrays.toString((Object[])obj); //Object[] overload
            }
            else if (obj instanceof int[]) {
                output = Arrays.toString((int[])obj);    //int[] overload
            }
            //and so on for every primitive type
        }
        else {
            output = obj.toString();
        }
    
        System.out.println(output);
    }
    

    我希望其他人可以提供更优雅的解决方案,但基于原始数组的限制,这可能是你能做的最好的。

    【讨论】:

      【解决方案3】:

      为什么不让method overloading 解决您的问题?只需编写两个(或更多)名称相同但签名不同的方法,然后让编译器决定程序执行时将调用哪个方法:

      void print(Object object) {
         System.out.println("Object: " + object);
      }
      
      void print(Object[] array) {
          System.out.println("Object[]: " Arrays.toString(array)); 
      }
      
      void print(int[] array) {
          System.out.println("int[]: " Arrays.toString(array)); 
      }
      

      代码中其他地方的示例用法:

      String first = "test";
      print(first);   // prints "Object: test";
      
      String[] second = {"A", "B"};    
      print(second);   // prints "Object[]: [A, B]" 
      
      int[] third = {1, 2};
      print(third);    // prints "int[]: [1, 2]"
      

      【讨论】:

        【解决方案4】:

        如果您不想依赖对象的类本身来重载 Object 的 toString 方法(以获得比打印类名和哈希码更有用的东西... .)

        我的建议是使用一个使用反射的库来获得更深的结构,例如 GSON:http://code.google.com/p/google-gson/

        public static String print(Object object) {
            return new Gson().toJson(object);
        }
        
        public static void test() {
            System.out.println(print(new int[][] {new  int[] {1, 2, 3} }));
            // outputs: [[1,2,3]]
            System.out.println(print(new String[] { "aa", "bb", "cc" }));
            // outputs: ["aa","bb","cc"]
        }
        

        这可以轻松打印数组,包括多维数组和原始数组。

        但真正的好处是它以统一的方式打印任何类的对象,无论该类是否以任何有用的方式覆盖了 toString。

        【讨论】:

          【解决方案5】:

          如果您只想将其打印为字符串,为什么要转换它?只需将其视为一个 Objects 数组,遍历该数组,并在每个 Object 上调用 toString() 方法即可。

          【讨论】:

          • 但是如果它包含原始类型,我不能将它转换为 Object 数组。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-29
          相关资源
          最近更新 更多