Làm cách nào để tìm ra loại từng đối tượng trong ArrayList <Đối tượng>?


87

Tôi có một ArrayList được tạo thành từ các phần tử khác nhau được nhập từ một db, được tạo thành từ các chuỗi, số, số đôi và số nguyên. Có cách nào sử dụng kỹ thuật kiểu phản chiếu để tìm ra từng loại dữ liệu mà mỗi phần tử nắm giữ không?

FYI: Lý do mà có quá nhiều loại dữ liệu là đây là một đoạn mã java được viết để thực thi với các DB khác nhau.

Câu trả lời:


100

Trong C #: Đã sửa
với đề xuất từ 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);
    }
    ...
}

Trong Java:

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

3
thực ra thay vì sử dụng o.GetType () == typeof (int)) chỉ cần nói if (o là int);
Michael Brown

Và nếu bạn tình cờ lo lắng về từng nano giây, thì "as" sẽ giúp bạn tiết kiệm một ít so với "is" với một diễn viên.
Neil

47
Bạn không thể làm instanceoftrong trường hợp java?
Razor Storm

2
Đối với trường hợp Integer, nó cũng phải là Integer.class, tôi vừa thử Integer.TYPE không hoạt động.
alan turing

(int) okhông hoạt động trong Java. Nó tạo ra thông báo lỗi Cannot cast from Object to int. Sử dụng (Integer o).intValue()thay thế.
Tối đa

54

Bạn có thể sử dụng getClass()phương pháp hoặc bạn có thể sử dụng instanceof. Ví dụ

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

hoặc là

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

Lưu ý rằng instanceof sẽ khớp với các lớp con. Ví dụ, of Clà một lớp con của A, thì điều sau sẽ đúng:

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

Tuy nhiên, điều sau sẽ là sai:

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

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

7
đừng quên null nếu nó có thể trong danh sách của bạn. Bạn sẽ nhận được NullPointerExceptions từ ví dụ này với null.
John Gardner 20-08

13

Bạn hầu như không bao giờ muốn bạn sử dụng một cái gì đó như:

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

bởi vì bạn không tính đến các lớp con có thể có. Bạn thực sự muốn sử dụng Class # isAssignableFrom:

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

5

Trong Java chỉ cần sử dụng toán tử instanceof. Điều này cũng sẽ quan tâm đến các lớp con.

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

Chỉ cần gọi .getClass()từng người Objecttrong một vòng lặp.

Thật không may, Java không có map(). :)


3

Instanceof hoạt động nếu bạn không phụ thuộc vào các lớp cụ thể, nhưng cũng lưu ý rằng bạn có thể có null trong danh sách, vì vậy obj.getClass () sẽ không thành công, nhưng instanceof luôn trả về false trên null.


3

Kể từ 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
            }
        });


2

thay vì sử dụng, object.getClass().getName()bạn có thể sử dụng object.getClass().getSimpleName(), vì nó trả về một tên lớp đơn giản mà không bao gồm tên gói.

ví dụ,

Object[] intArray = { 1 }; 

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

cho,

java.lang.Integer
Integer

0

Bạn nói "đây là một đoạn mã java đang được viết", từ đó tôi suy ra rằng vẫn có khả năng bạn có thể thiết kế nó theo một cách khác.

Có ArrayList giống như có một bộ sưu tập nội dung. Thay vì ép buộc instanceof hoặc getClass mỗi khi bạn lấy một đối tượng từ danh sách, tại sao không thiết kế hệ thống để bạn nhận được loại đối tượng khi bạn truy xuất nó từ DB và lưu trữ nó vào một bộ sưu tập với kiểu thích hợp vật?

Hoặc, bạn có thể sử dụng một trong nhiều thư viện truy cập dữ liệu tồn tại để thực hiện việc này cho bạn.


0

Nếu bạn mong đợi dữ liệu ở dạng số ở một số dạng và tất cả những gì bạn muốn làm là chuyển đổi kết quả thành giá trị số, tôi sẽ đề xuất:

for (Object o:list) {
  Double.parseDouble(o.toString);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.