How to identify an instance of multidimensional object in java?

364 Views Asked by At

Is there any alternative way to identify instance of multidimensional object without hardcode on it?

//source
import java.util.LinkedList;
import java.util.List;

public class Test {

    public static <T> boolean isPrimitiveWrapper(T p_obj) throws Exception {
        if (Number.class.isInstance(p_obj) || Number[].class.isInstance(p_obj)) {
            return true;
        } else if (Boolean.class.isInstance(p_obj) || Boolean[].class.isInstance(p_obj)) {
            return true;
        } else if (Character.class.isInstance(p_obj) || Character[].class.isInstance(p_obj)) {
            return true;
        }

        return false;
    }

    public static void main(String[] args) throws Exception {
        Integer[][][] a = {{{0}}, {{1}}, {{0}}};

        println(isPrimitiveWrapper(a));
        println(isPrimitiveWrapper(a[0]));
        println(isPrimitiveWrapper(a[0][0]));
        println(isPrimitiveWrapper(a[0][0][0]));
    }

    public static <T> void println(T p_t) {
        System.out.println(p_t);
    }

}

//Actual Result
false
false
true
true

//Expected Result
true
true
true
true

Based on the example above, we have no problem to deal with non-array & single dimension array object, but it is fail to identify multidimensional array object.

It is too ugly to hardcode the number of dimension.

3

There are 3 best solutions below

0
On BEST ANSWER
public class Test {

    public static <T> boolean isPrimitiveWrapper(T p_obj) throws Exception {
        return isPrimitiveWrapper(p_obj.getClass());
    }

    public static boolean isPrimitiveWrapper(Class p_obj) throws Exception {
        if (Number.class.isAssignableFrom(p_obj)) {
            return true;
        } else if (Boolean.class.isAssignableFrom(p_obj)) {
            return true;
        } else if (Character.class.isAssignableFrom(p_obj)) {
            return true;
        } else if (p_obj.isArray()) {

            //To handle multi dimension array
            while (p_obj.isArray()) {
                p_obj = p_obj.getComponentType();
            }

            return isPrimitiveWrapper(p_obj);
        }

        return false;
    }

    public static boolean isPrimitiveWrapper(boolean p_obj) {
        return false;
    }

    public static boolean isPrimitiveWrapper(byte p_obj) {
        return false;
    }

    public static boolean isPrimitiveWrapper(short p_obj) {
        return false;
    }

    public static boolean isPrimitiveWrapper(float p_obj) {
        return false;
    }

    public static boolean isPrimitiveWrapper(int p_obj) {
        return false;
    }

    public static boolean isPrimitiveWrapper(long p_obj) {
        return false;
    }

    public static boolean isPrimitiveWrapper(char p_obj) {
        return false;
    }

    public static boolean isPrimitiveWrapper(double p_obj) {
        return false;
    }

    public static void main(String[] args) throws Exception {
        Integer[][][] a = {{{0}}, {{1}}, {{0}}};
        int[][][] b = {{{0}}, {{1}}, {{0}}};

        println(isPrimitiveWrapper(a));
        println(isPrimitiveWrapper(a[0]));
        println(isPrimitiveWrapper(a[0][0]));
        println(isPrimitiveWrapper(a[0][0][0]));

        println(isPrimitiveWrapper(b));
        println(isPrimitiveWrapper(b[0]));
        println(isPrimitiveWrapper(b[0][0]));
        println(isPrimitiveWrapper(b[0][0][0]));
    }

    public static <T> void println(T p_t) {
        System.out.println(p_t);
    }

}
6
On

Try this approach. I guess that's what you want.
But this code looks like some sort of a hack anyway
(which is not necessarily bad).

private static boolean isPrimitiveWrapper(Object obj){
    if (obj == null) {
        return false;
    } else {
        String cls = obj.getClass().getCanonicalName();
        return "java.lang.Integer".equals(cls) || 
               cls.startsWith("java.lang.Integer[]");
    }
}

Here is another hack. Both codes should work OK though.

private static boolean isPrimitiveWrapper(Object obj){
    if (obj == null) {
        return false;
    } else {
        String cls = obj.getClass().getName();
        cls = cls.replaceAll(";", "");
        return cls.matches("\\[*L?java\\.lang\\.Integer");
    }
}
0
On

There's no standard way to determine, if the class itself is wrapper for primitive type or not, so, you can do something like this:

private static final Set <Class <?>> primitiveWrappers;

static {
    Set <Class <?>> tmp = new HashSet<>();
    tmp.add (Integer.class);
    tmp.add (Boolean.class);
    tmp.add (Character.class);
    tmp.add (Long.class);
    tmp.add (Double.class);
    tmp.add (Float.class);
    // ... have I forgotten smth?
    primitiveWrappers = Collections.unmodifiableSet(tmp);
}

private static boolean isPrimitiveWrapperOrArrayOf(Object o) {
    if (o.getClass().isArray())
        return isPrimitiveWrapperOrArrayOf(o.getClass().getComponentType());
    else
        return primitiveWrappers.contains(o.getClass());
}

When you run isPrimitiveWrapperOrArrayOf, the class is being checked if it's array, if it is, we'll check it's component type (for example, that would be Integer[] for Integer[][]) in the same function isPrimitiveWrapperOrArrayOf, so this way we'll come to just SomeClass, which will be checked if it's contained inside hardcoded primitiveWrappers

By the way, you may take a look at Commons Lang, ClassUtils.wrapperToPrimitive may solve your problem.