2014-02-13 3 views
0

Я попытался написать следующий метод:Как я могу определить, является ли элемент в массиве массивом?

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) 

Как еще, если не так, я могу сказать, если элемент является массивом?

+3

Как бы это был массив? 'original' является' double [] '. –

+0

@SotiriosDelimanolis Это еще одна часть проблемы ...:/ – Supuhstar

+0

@Supuhstar: Как это написано, элементы не могут быть массивом. –

ответ

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

1

Если изменить тип параметра для Object... original, используйте Class#isArray(), как это:

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

'original [i]' имеет тип 'double'. –

0

Использование переменного оператора аргумента (...) сам создает массив локальный для метод (в этом случае дублируется «оригинал»), поэтому все, что вы передадите ему, станет массивом. Итак, планируете ли вы передать как многомерные, так и одномерные массивы этому методу, а затем метод различает типы? Если вы не объявляете какие-либо многомерные массивы в своем классе, то проверка их будет совершенно ненужной. Если у вас есть синглы и multis, которые вы хотите напечатать, я бы предложил методы перегрузки и сами аргументы метода разделили. Так что-то вроде:

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

Это скомпилирован для меня увидеть, если он делает для вас, а также проверить, чтобы убедиться, что он делает то, что вы хотите. Но аргументы метода будут сортировать, какие массивы являются одиночными и которые являются многомерными.

Надеюсь, это поможет! Счастливое кодирование!

+0

> «Планируете ли вы передать эти многомерные и одномерные массивы этому методу, а затем метод различает типы?» Да, я, но я надеялся, что это может быть более общим: разрешить кому бы то ни было вызов методу передачи массива 'n' и получить его обратно как другой тип – Supuhstar

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, но является теперь массив удваивается , что является моей конечной целью

Смежные вопросы