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

时间:2014-02-13 23:38:24

标签: java arrays multidimensional-array type-conversion

我尝试编写以下方法:

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

我得到这个编译错误:

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

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

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

无论如何 - 使用它 - 它可以满足您的需求。

/**
 * 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);
  }
}

我可能错了。

像这样使用:

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

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

答案 2 :(得分:0)

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

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

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

希望它有所帮助!快乐的编码!

答案 3 :(得分:0)

这是一个对我有用的解决方案:

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

输出是:

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

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