Bir ArrayList <Object> nesnesinde her nesnenin ne tür olduğunu nasıl öğrenebilirim?


87

Bir db'den içe aktarılan farklı öğelerden oluşan, dizeler, sayılar, çiftler ve tam sayılardan oluşan bir ArrayList var. Her bir öğenin ne tür veri tuttuğunu bulmak için bir yansıma türü tekniği kullanmanın bir yolu var mı?

Bilginize: Bu kadar çok veri türü olmasının nedeni, bunun farklı DB'lerle uygulanmak üzere yazılan bir java kodu parçası olmasıdır.

Yanıtlar:


100

C #'da: Mike'ın
önerisiyle düzeltildi

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

Java'da:

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

3
aslında o.GetType () == typeof (int)) kullanmak yerine if (o is int);
Michael Brown

1
Ve eğer her nanosaniye için endişeleniyorsanız, "olduğu gibi" sizi bir kadroyla "eşittir" ile karşılaştırıldığında birkaçını kurtaracaktır.
Neil

47
Sadece instanceofjava durumunda yapamaz mısın?
Jilet Fırtına

2
Tamsayı durumunda, aynı zamanda Integer.class olmalıdır, sadece Integer.TYPE çalışmıyor denedim.
alan turing

(int) oJava'da çalışmaz. Hata mesajını üretir Cannot cast from Object to int. (Integer o).intValue()Bunun yerine kullanın .
Maksimum

54

getClass()Yöntemi kullanabilir veya instanceof'u kullanabilirsiniz. Örneğin

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

veya

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

İnstanceof öğesinin alt sınıflarla eşleşeceğini unutmayın. Örneğin, / C, bir alt sınıfıdır A, bu durumda aşağıdakiler doğru olacaktır:

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

Ancak, aşağıdakiler yanlış olacaktır:

C c = new C();
assert !c.getClass().equals(A.class)

45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}

7
Listenizde mümkünse boşluğu unutmayın. Bu örnekten null değerlerle NullPointerExceptions alacaksınız.
John Gardner

13

Neredeyse hiç böyle bir şey kullanmanızı istemezsiniz:

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

çünkü olası alt sınıfları hesaba katmıyorsunuz. Gerçekten Class # isAssignableFrom kullanmak istiyorsunuz:

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

5

Java'da sadece instanceof operatörünü kullanın. Bu aynı zamanda alt sınıflarla da ilgilenecektir.

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

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

4

.getClass()Her birini Objectbir döngüde çağırın .

Maalesef Java'da yok map(). :)


3

Instanceof, belirli sınıflara bağlı değilseniz çalışır, ancak listede null değerlere sahip olabileceğinizi unutmayın, bu nedenle obj.getClass () başarısız olur, ancak instanceof her zaman null değeri false döndürür.


3

Java 8'den beri


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


2

kullanmak yerine object.getClass().getName()kullanabilirsiniz object.getClass().getSimpleName(), çünkü paket adı dahil edilmeden basit bir sınıf adı döndürür.

Örneğin,

Object[] intArray = { 1 }; 

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

verir

java.lang.Integer
Integer

0

"Bu, yazılmakta olan bir java kodu" diyorsunuz, ben de onu farklı bir şekilde tasarlama şansınızın hala var olduğu sonucuna varıyorum.

Bir ArrayList'e sahip olmak, bir şeyler koleksiyonuna sahip olmak gibidir. Listeden her nesne aldığınızda instanceof veya getClass'ı zorlamak yerine, neden sistemi DB'den aldığınızda nesnenin türünü alacak ve uygun türde bir koleksiyonda depolayacak şekilde tasarlamıyorsunuz? nesne?

Veya bunu sizin için yapmak için var olan birçok veri erişim kitaplığından birini kullanabilirsiniz.


0

Verilerin bir biçimde sayısal olmasını bekliyorsanız ve ilgilendiğiniz tek şey sonucu sayısal bir değere dönüştürmekse, şunu öneririm:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.