views:

3455

answers:

9

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.

A: 

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

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

skiphoppy
A: 

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.getClass().equals(Integer.TYPE)) {
        handleInt((int)o);
    }
    else if (o.getClass().equals(String.class)) {
        handleString((String)o);
    }
    ...
}
Frank Krueger
actually instead of using o.GetType()==typeof(int)) just say if(o is int);
Mike Brown
And if you happen to be worried about every nanosecond, "as" will save you a few compared to "is" with a cast.
Neil Whitaker
+9  A: 
for (Object object : list) {
    System.out.println(object.getClass().getName());
}
Fabian Steeg
don't forget about null if it is possible in your list. You'll get NullPointerExceptions from this example with nulls.
John Gardner
+6  A: 

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)

faran
+2  A: 

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.

John Gardner
A: 

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.

shoover
+4  A: 

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)) {
    ...
}
Heath Borders
A: 

Thanks very much for helping me out. In response to shoover's answer, I did find a way to do this without having to call getClass each time. The data had to be transferred to Number anyway, so i just put a Sentinel on the catch side of the loop. I laughed at myself when I figured out that the answer was from my intro to programming class from collage. I forgot K.I.S.S..

WolfmanDragon
A: 

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

DJClayworth