Bagaimana cara mengetahui tipe apa setiap objek dalam ArrayList <Object>?

87

Saya memiliki ArrayList yang terdiri dari elemen berbeda yang diimpor dari db, terdiri dari string, angka, ganda, dan int. Adakah cara untuk menggunakan teknik tipe refleksi untuk mengetahui apa yang dimiliki setiap jenis data yang dimiliki setiap elemen?

FYI: Alasan ada begitu banyak jenis data adalah karena ini adalah bagian dari kode java yang ditulis untuk diimplementasikan dengan DB yang berbeda.

WolfmanDragon
sumber

Jawaban:

100

Di C #:
Diperbaiki dengan rekomendasi dari 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);
    }
    ...
}

Di Jawa:

ArrayList<Object> list = ...;
for (Object o : list) {
    if (o instanceof Integer)) {
        handleInt((Integer o).intValue());
    }
    else if (o instanceof String)) {
        handleString((String)o);
    }
    ...
}
Frank Krueger
sumber
3
sebenarnya daripada menggunakan o.GetType () == typeof (int)) katakan saja if (o is int);
Michael Brown
1
Dan jika Anda khawatir tentang setiap nanodetik, "karena" akan menghemat beberapa dibandingkan dengan "ada" dengan pemeran.
Neil
47
Tidak bisakah Anda melakukannya instanceofdalam kasus java?
Razor Storm
2
Untuk kasus Integer, seharusnya juga Integer.class, saya baru saja mencoba Integer.TYPE tidak berfungsi.
alan turing
(int) otidak berfungsi di Java. Ini menghasilkan pesan kesalahan Cannot cast from Object to int. Gunakan (Integer o).intValue()sebagai gantinya.
Maks
54

Anda dapat menggunakan getClass()metode ini, atau Anda dapat menggunakan instanceof. Sebagai contoh

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

atau

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

Perhatikan bahwa instanceof akan cocok dengan subclass. Misalnya, dari Cadalah subkelas dari A, maka yang berikut ini akan benar:

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

Namun, hal berikut ini salah:

C c = new C();
assert !c.getClass().equals(A.class)
faran
sumber
45
for (Object object : list) {
    System.out.println(object.getClass().getName());
}
Fabian Steeg
sumber
7
jangan lupa tentang null jika memungkinkan dalam daftar Anda. Anda akan mendapatkan NullPointerExceptions dari contoh ini dengan nulls.
John Gardner
13

Anda hampir tidak pernah ingin menggunakan sesuatu seperti:

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

karena Anda tidak memperhitungkan kemungkinan subclass. Anda benar-benar ingin menggunakan Class # isAssignableFrom:

Object o = ...
if (Foo.class.isAssignableFrom(o)) {
    ...
}
Heath Borders
sumber
5

Di Java, gunakan saja operator instanceof. Ini juga akan menangani subclass.

ArrayList<Object> listOfObjects = new ArrayList<Object>();
for(Object obj: listOfObjects){
   if(obj instanceof String){
   }else if(obj instanceof Integer){
   }etc...
}
Reid Mac
sumber
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());
            }
        }
    }
}
pembuat pot
sumber
4

Panggil saja .getClass()masing-masing Objectdalam satu lingkaran.

Sayangnya, Java tidak punya map(). :)

cakalang
sumber
3

Instanceof berfungsi jika Anda tidak bergantung pada kelas tertentu, tetapi juga perlu diingat bahwa Anda dapat memiliki null dalam daftar, jadi obj.getClass () akan gagal, tetapi instanceof selalu mengembalikan false pada null.

John Gardner
sumber
3

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

Andrew
sumber
2

daripada menggunakan object.getClass().getName()Anda bisa menggunakan object.getClass().getSimpleName(), karena mengembalikan nama kelas sederhana tanpa nama paket disertakan.

misalnya,

Object[] intArray = { 1 }; 

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

memberi,

java.lang.Integer
Integer
Sufiyan Ghori
sumber
0

Anda mengatakan "ini adalah bagian dari kode java yang sedang ditulis", dari situ saya menyimpulkan bahwa masih ada kemungkinan Anda bisa mendesainnya dengan cara yang berbeda.

Memiliki ArrayList seperti memiliki sekumpulan barang. Daripada memaksa instanceof atau getClass setiap kali Anda mengambil objek dari daftar, mengapa tidak mendesain sistem sehingga Anda mendapatkan tipe objek saat Anda mengambilnya dari DB, dan menyimpannya ke dalam kumpulan tipe yang sesuai. obyek?

Atau, Anda dapat menggunakan salah satu dari banyak pustaka akses data yang ada untuk melakukan ini untuk Anda.

pengusir
sumber
0

Jika Anda mengharapkan data menjadi numerik dalam beberapa bentuk, dan semua yang Anda minati adalah mengubah hasilnya menjadi nilai numerik, saya sarankan:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
DJClayworth
sumber