Question

I have a ArrayList made up of different elements imported from a db, made up of strings, numbers, doubles and ints. Is there a way to use a reflection type technique to find out what each type of data each element holds?

FYI: The reason that there is so many types of data is that this is a piece of java code being written to be implemented with different DB's.

Was it helpful?

Solution

In C#:
Fixed with recommendation from Mike

ArrayList list = ...;
// List<object> list = ...;
foreach (object o in list) {
    if (o is int) {
        HandleInt((int)o);
    }
    else if (o is string) {
        HandleString((string)o);
    }
    ...
}

In Java:

ArrayList<Object> list = ...;
for (Object o : list) {
    if (o instanceof Integer)) {
        handleInt((Integer o).intValue());
    }
    else if (o instanceof String)) {
        handleString((String)o);
    }
    ...
}

OTHER TIPS

You can use the getClass() method, or you can use instanceof. For example

for (Object obj : list) {
  if (obj instanceof String) {
   ...
  }
}

or

for (Object obj : list) {
 if (obj.getClass().equals(String.class)) {
   ...
 }
}

Note that instanceof will match subclasses. For instance, of C is a subclass of A, then the following will be true:

C c = new C();
assert c instanceof A;

However, the following will be false:

C c = new C();
assert !c.getClass().equals(A.class)
for (Object object : list) {
    System.out.println(object.getClass().getName());
}

You almost never want you use something like:

Object o = ...
if (o.getClass().equals(Foo.class)) {
    ...
}

because you aren't accounting for possible subclasses. You really want to use Class#isAssignableFrom:

Object o = ...
if (Foo.class.isAssignableFrom(o)) {
    ...
}

In Java just use the instanceof operator. This will also take care of subclasses.

ArrayList<Object> listOfObjects = new ArrayList<Object>();
for(Object obj: listOfObjects){
   if(obj instanceof String){
   }else if(obj instanceof Integer){
   }etc...
}
import java.util.ArrayList;

/**
 * @author potter
 *
 */
public class storeAny {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ArrayList<Object> anyTy=new ArrayList<Object>();
        anyTy.add(new Integer(1));
        anyTy.add(new String("Jesus"));
        anyTy.add(new Double(12.88));
        anyTy.add(new Double(12.89));
        anyTy.add(new Double(12.84));
        anyTy.add(new Double(12.82));

        for (Object o : anyTy) {
            if(o instanceof String){
                System.out.println(o.toString());
            } else if(o instanceof Integer) {
                System.out.println(o.toString());   
            } else if(o instanceof Double) {
                System.out.println(o.toString());
            }
        }
    }
}

Just call .getClass() on each Object in a loop.

Unfortunately, Java doesn't have map(). :)

Instanceof works if you don't depend on specific classes, but also keep in mind that you can have nulls in the list, so obj.getClass() will fail, but instanceof always returns false on null.

Since Java 8


        mixedArrayList.forEach((o) -> {
            String type = o.getClass().getSimpleName();
            switch (type) {
                case "String":
                    // treat as a String
                    break;
                case "Integer":
                    // treat as an int
                    break;
                case "Double":
                    // treat as a double
                    break;
                ...
                default:
                    // whatever
            }
        });

instead of using object.getClass().getName() you can use object.getClass().getSimpleName(), because it returns a simple class name without a package name included.

for instance,

Object[] intArray = { 1 }; 

for (Object object : intArray) { 
    System.out.println(object.getClass().getName());
    System.out.println(object.getClass().getSimpleName());
}

gives,

java.lang.Integer
Integer

You say "this is a piece of java code being written", from which I infer that there is still a chance that you could design it a different way.

Having an ArrayList is like having a collection of stuff. Rather than force the instanceof or getClass every time you take an object from the list, why not design the system so that you get the type of the object when you retrieve it from the DB, and store it into a collection of the appropriate type of object?

Or, you could use one of the many data access libraries that exist to do this for you.

If you expect the data to be numeric in some form, and all you are interested in doing is converting the result to a numeric value, I would suggest:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top