如何判断数组中的项是否也是数组?

时间:2023-01-01 21:27:37

I tried to write the following method:

我试着写下面的方法:

public static long[] deepDoubleToLong(double... original)
{
    long[] ret = new long[original.length];
    for(int i = 0; i < ret.length; i++)
        if (original[i] instanceof double[])
            ret[i] = deepDoubleToLong((double[])original[i]);
        else
            ret[i] = (long)original[i];
    return ret;
}

bit I get this compile error:

我得到这个编译错误:

Uncompilable source code - unexpected type
  required: reference
  found:    double
    at ArrayConversion.deepDoubleToLong(ArrayConversion.java:5)

How else, if not this way, can I tell if an item is an array?

如果不是这样,我怎么知道一个项目是否是一个数组?

4 个解决方案

#1


1  

If you change the parameter type to Object... original, use Class#isArray(), like this:

如果将参数类型更改为Object ... original,请使用Class#isArray(),如下所示:

if (original[i].getClass().isArray())

#2


0  

I suspect you are looking for my Rebox class.

我怀疑你正在寻找我的Rebox课程。

The problem (as the comment at the start describes) comes when you call a varargs method with an array as a parameter. This causes the array to be wrapped up and appears as an array of primitives in the first parameter - or something like that.

当您使用数组作为参数调用varargs方法时,会出现问题(如开头所述的注释所述)。这会导致数组被包裹起来并在第一个参数中显示为基元数组 - 或类似的内容。

Anyway - use this - it does what you need.

无论如何 - 使用它 - 它做你需要的。

/**
 * Can rebox a boxed primitive array into its Object form.
 * 
 * Generally I HATE using instanceof because using it is usually 
 * an indication that your hierarchy is completely wrong.
 * 
 * Reboxing - however - is an area I am ok using it.
 *
 * Generally, if a primitive array is passed to a varargs it
 * is wrapped up as the first and only component of an Object[].
 *
 * E.g.
 *
 * public void f(T... t) {};
 * f(new int[]{1,2});
 *
 * actually ends up calling f with t an Object[1] and t[0] the int[].
 *
 * This unwraps it and returns the correct reboxed version.
 *
 * In the above example it will return an Integer[].
 *
 * Any other array types will be returned unchanged.
 *
 * @author OldCurmudgeon
 */
public class Rebox {
  public static <T> T[] rebox(T[] it) {
    // Default to return it unchanged.
    T[] result = it;
    // Special case length 1 and it[0] is primitive array.
    if (it.length == 1 && it[0].getClass().isArray()) {
      // Which primitive array is it?
      if (it[0] instanceof int[]) {
        result = rebox((int[]) it[0]);
      } else if (it[0] instanceof long[]) {
        result = rebox((long[]) it[0]);
      } else if (it[0] instanceof float[]) {
        result = rebox((float[]) it[0]);
      } else if (it[0] instanceof double[]) {
        result = rebox((double[]) it[0]);
      } else if (it[0] instanceof char[]) {
        result = rebox((char[]) it[0]);
      } else if (it[0] instanceof byte[]) {
        result = rebox((byte[]) it[0]);
      } else if (it[0] instanceof short[]) {
        result = rebox((short[]) it[0]);
      } else if (it[0] instanceof boolean[]) {
        result = rebox((boolean[]) it[0]);
      }
    }
    return result;
  }

  // Rebox each one separately.
  private static <T> T[] rebox(int[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Integer.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(long[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Long.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(float[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Float.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(double[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Double.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(char[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Character.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(byte[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Byte.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(short[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Short.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(boolean[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Boolean.valueOf(it[i]);
    }
    return boxed;
  }

  // Trick to make a T[] of any length.
  // Do not pass any parameter for `dummy`.
  // public because this is potentially re-useable.
  public static <T> T[] makeTArray(int length, T... dummy) {
    return Arrays.copyOf(dummy, length);
  }
}

I may be wrong though.

我可能错了。

Use it like this:

像这样用它:

public StringBuilder add(StringBuilder s, T... values) {
  // Remember to rebox it in case it's a primitive array.
  for (T v : Rebox.rebox(values)) {
    add(s, v);
  }
  return s.append(fin());
}

In answer to your question title How can I tell if an item in an array is also an array? - use it[i].getClass().isArray()

回答你的问题标题如何判断数组中的项是否也是一个数组? - 使用它[i] .getClass()。isArray()

#3


0  

The use of the variable argument operator (...) itself is creating an array local to your method (in this case dubbed "original"), so anything you pass to it will become an array. So are you planning on passing both multi and single dimensional arrays to this method, and then have the method distinguish between the types? If you are not declaring any multi dimensional arrays in your class, then checking for them would be entirely unnecessary. If you do have singles and multis that you want to type cast I might suggest overloading methods, and have the method arguments themselves do the separating. So something like:

变量参数运算符(...)本身的使用是为您的方法创建一个本地数组(在本例中称为“原始”),因此传递给它的任何内容都将成为一个数组。那么你打算将多维和单维数组传递给这个方法,然后让方法区分这些类型吗?如果您没有在类中声明任何多维数组,那么检查它们将完全没有必要。如果你确实有想要输入的单数和多数,我可能建议重载方法,并让方法参数自己进行分离。所以类似于:

public static long[] doubleToLong(double[][] original, int index){
//your conversion logic here that will type cast your second dimension array
long[] ret = new long[original.length];    
for(int i = 0; i < ret.length; i++)
     ret[i] = (long)original[index][i];
return ret;
}

public static long[] doubleToLong(double[] original){
//your conversion logic here that type casts a single dimension array
long[] ret = new long[original.length];    
for(int i = 0; i < ret.length; i++)
     ret[i] = (long)original[i];
return ret;
}

That compiled for me, see if it does for you, and also test it to make sure it does what you want. But the method arguments will sort through which arrays are single, and which are multidimensional.

这为我编译,看看它是否适合你,并测试它,以确保它做你想要的。但是方法参数将排序哪些数组是单个的,哪些是多维的。

Hope it helps! Happy coding!

希望能帮助到你!快乐的编码!

#4


0  

Here's a solution that worked for me:

这是一个适合我的解决方案:

import java.util.Arrays;

public class ArrayConversion
{
    public static Object[] deepToDouble(Object[] original)
    {
        Object[] ret = new Object[original.length];
        for(int i = 0; i < ret.length; i++)
            if (original[i] instanceof Object[])
                ret[i] = deepToDouble((Object[])original[i]);
            else
                ret[i] =
                (
                    original[i] instanceof Number
                        ? ((Number)original[i]).doubleValue()
                        : Double.NaN
                );
        return ret;
    }

    public static void main(String... args)
    {
        Object[] test = new Object[]{1, new Object[]{1, 2, 3}, 3};
        System.out.println(Arrays.deepToString(test));
        System.out.println(Arrays.deepToString(deepToDouble(new Object[]{1, new Object[]{1, 2, 3}, 3})));
    }
}

And the output is:

输出是:

[1, [1, 2, 3], 3]
[1.0, [1.0, 2.0, 3.0], 3.0]

I know it's still loosely typed as Object, but it is now an array of doubles, which is my end goal

我知道它仍然松散地输入为Object,但它现在是一系列双打,这是我的最终目标

#1


1  

If you change the parameter type to Object... original, use Class#isArray(), like this:

如果将参数类型更改为Object ... original,请使用Class#isArray(),如下所示:

if (original[i].getClass().isArray())

#2


0  

I suspect you are looking for my Rebox class.

我怀疑你正在寻找我的Rebox课程。

The problem (as the comment at the start describes) comes when you call a varargs method with an array as a parameter. This causes the array to be wrapped up and appears as an array of primitives in the first parameter - or something like that.

当您使用数组作为参数调用varargs方法时,会出现问题(如开头所述的注释所述)。这会导致数组被包裹起来并在第一个参数中显示为基元数组 - 或类似的内容。

Anyway - use this - it does what you need.

无论如何 - 使用它 - 它做你需要的。

/**
 * Can rebox a boxed primitive array into its Object form.
 * 
 * Generally I HATE using instanceof because using it is usually 
 * an indication that your hierarchy is completely wrong.
 * 
 * Reboxing - however - is an area I am ok using it.
 *
 * Generally, if a primitive array is passed to a varargs it
 * is wrapped up as the first and only component of an Object[].
 *
 * E.g.
 *
 * public void f(T... t) {};
 * f(new int[]{1,2});
 *
 * actually ends up calling f with t an Object[1] and t[0] the int[].
 *
 * This unwraps it and returns the correct reboxed version.
 *
 * In the above example it will return an Integer[].
 *
 * Any other array types will be returned unchanged.
 *
 * @author OldCurmudgeon
 */
public class Rebox {
  public static <T> T[] rebox(T[] it) {
    // Default to return it unchanged.
    T[] result = it;
    // Special case length 1 and it[0] is primitive array.
    if (it.length == 1 && it[0].getClass().isArray()) {
      // Which primitive array is it?
      if (it[0] instanceof int[]) {
        result = rebox((int[]) it[0]);
      } else if (it[0] instanceof long[]) {
        result = rebox((long[]) it[0]);
      } else if (it[0] instanceof float[]) {
        result = rebox((float[]) it[0]);
      } else if (it[0] instanceof double[]) {
        result = rebox((double[]) it[0]);
      } else if (it[0] instanceof char[]) {
        result = rebox((char[]) it[0]);
      } else if (it[0] instanceof byte[]) {
        result = rebox((byte[]) it[0]);
      } else if (it[0] instanceof short[]) {
        result = rebox((short[]) it[0]);
      } else if (it[0] instanceof boolean[]) {
        result = rebox((boolean[]) it[0]);
      }
    }
    return result;
  }

  // Rebox each one separately.
  private static <T> T[] rebox(int[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Integer.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(long[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Long.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(float[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Float.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(double[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Double.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(char[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Character.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(byte[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Byte.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(short[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Short.valueOf(it[i]);
    }
    return boxed;
  }

  private static <T> T[] rebox(boolean[] it) {
    T[] boxed = makeTArray(it.length);
    for (int i = 0; i < it.length; i++) {
      boxed[i] = (T) Boolean.valueOf(it[i]);
    }
    return boxed;
  }

  // Trick to make a T[] of any length.
  // Do not pass any parameter for `dummy`.
  // public because this is potentially re-useable.
  public static <T> T[] makeTArray(int length, T... dummy) {
    return Arrays.copyOf(dummy, length);
  }
}

I may be wrong though.

我可能错了。

Use it like this:

像这样用它:

public StringBuilder add(StringBuilder s, T... values) {
  // Remember to rebox it in case it's a primitive array.
  for (T v : Rebox.rebox(values)) {
    add(s, v);
  }
  return s.append(fin());
}

In answer to your question title How can I tell if an item in an array is also an array? - use it[i].getClass().isArray()

回答你的问题标题如何判断数组中的项是否也是一个数组? - 使用它[i] .getClass()。isArray()

#3


0  

The use of the variable argument operator (...) itself is creating an array local to your method (in this case dubbed "original"), so anything you pass to it will become an array. So are you planning on passing both multi and single dimensional arrays to this method, and then have the method distinguish between the types? If you are not declaring any multi dimensional arrays in your class, then checking for them would be entirely unnecessary. If you do have singles and multis that you want to type cast I might suggest overloading methods, and have the method arguments themselves do the separating. So something like:

变量参数运算符(...)本身的使用是为您的方法创建一个本地数组(在本例中称为“原始”),因此传递给它的任何内容都将成为一个数组。那么你打算将多维和单维数组传递给这个方法,然后让方法区分这些类型吗?如果您没有在类中声明任何多维数组,那么检查它们将完全没有必要。如果你确实有想要输入的单数和多数,我可能建议重载方法,并让方法参数自己进行分离。所以类似于:

public static long[] doubleToLong(double[][] original, int index){
//your conversion logic here that will type cast your second dimension array
long[] ret = new long[original.length];    
for(int i = 0; i < ret.length; i++)
     ret[i] = (long)original[index][i];
return ret;
}

public static long[] doubleToLong(double[] original){
//your conversion logic here that type casts a single dimension array
long[] ret = new long[original.length];    
for(int i = 0; i < ret.length; i++)
     ret[i] = (long)original[i];
return ret;
}

That compiled for me, see if it does for you, and also test it to make sure it does what you want. But the method arguments will sort through which arrays are single, and which are multidimensional.

这为我编译,看看它是否适合你,并测试它,以确保它做你想要的。但是方法参数将排序哪些数组是单个的,哪些是多维的。

Hope it helps! Happy coding!

希望能帮助到你!快乐的编码!

#4


0  

Here's a solution that worked for me:

这是一个适合我的解决方案:

import java.util.Arrays;

public class ArrayConversion
{
    public static Object[] deepToDouble(Object[] original)
    {
        Object[] ret = new Object[original.length];
        for(int i = 0; i < ret.length; i++)
            if (original[i] instanceof Object[])
                ret[i] = deepToDouble((Object[])original[i]);
            else
                ret[i] =
                (
                    original[i] instanceof Number
                        ? ((Number)original[i]).doubleValue()
                        : Double.NaN
                );
        return ret;
    }

    public static void main(String... args)
    {
        Object[] test = new Object[]{1, new Object[]{1, 2, 3}, 3};
        System.out.println(Arrays.deepToString(test));
        System.out.println(Arrays.deepToString(deepToDouble(new Object[]{1, new Object[]{1, 2, 3}, 3})));
    }
}

And the output is:

输出是:

[1, [1, 2, 3], 3]
[1.0, [1.0, 2.0, 3.0], 3.0]

I know it's still loosely typed as Object, but it is now an array of doubles, which is my end goal

我知道它仍然松散地输入为Object,但它现在是一系列双打,这是我的最终目标