2013-06-14 23 views
8

Tôi đang cố gắng phát triển trình tải bảng chung mà lược đồ được biết khi chạy. Điều này yêu cầu phải có một lớp chứa danh sách các loại phần tử khác nhau và hỗ trợ nhiều phương thức lấy và đặt khác nhau như getInt(int index), asString(int index), asStringList(int index). Các loại yếu tố mà tôi xem xét là Integer, Double, StringList<Integer>, List<Double>List<String>. Loại thực tế của mỗi phần tử được biết đến trong thời gian chạy và tôi sẽ lưu trữ chúng trong Danh sách mô tả lược đồ của nó để xử lý tiếp.Lưu trữ các loại phần tử khác nhau trong Danh sách trong Java

Câu hỏi của tôi là: tôi có nên lưu trữ danh sách các thành phần đó trong List<Object> hoặc List<? extends Object> không? hoặc có cách nào tốt hơn để thực hiện lớp đó?

+0

Khi chạy, 'Danh sách 'trở thành' List', vì vậy không có cơ hội ở đây, bạn 'd phải có hai bộ riêng biệt của các lớp học – fge

+1

Đó là một mùi mã thực sự khó chịu bạn đã có. –

+0

@Brain Roach: Tôi đã bao gồm lý do tại sao tôi cần điều này. – keelar

Trả lời

11

Kể từ khi tổ tiên chung của lớp học của bạn là Object, và vì List<? extends Object> không làm cho mọi việc bất kỳ sạch hơn (sau khi tất cả, mọi thứ đều mở rộng Object) có vẻ như List<Object> sẽ là một sự lựa chọn OK.

Tuy nhiên, danh sách đó sẽ là một túi hỗn hợp: bạn sẽ cần phải kiểm tra loại thời gian chạy của đối tượng bên trong và đưa ra quyết định dựa trên điều đó. Điều này chắc chắn không phải là một điều tốt.

Một giải pháp thay thế tốt hơn là tạo lớp của riêng bạn thực hiện các hoạt động trên các phần tử trong danh sách theo cách thống nhất và tạo một phân lớp cho từng loại phụ thực hiện các thao tác này một cách khác nhau. Điều này sẽ cho phép bạn xử lý danh sách theo cách thống nhất, đẩy sự khác biệt của mỗi đối tượng vào trình bao bọc của bạn.

public interface ItemWrapper { 
    int calculateSomething(); 
} 

public abstract class IntWrapper implements ItemWrapper { 
    private int value; 

    public IntWrapper(int v) { 
     value=v; 
    } 

    public int calculateSomething() { 
     return value; 
    } 
} 

public abstract class DoubleListWrapper implements ItemWrapper { 
    private List<Double> list; 

    public DoubleListWrapper (List<Double> lst) { 
     list = lst; 
    } 

    public int calculateSomething() { 
     int res; 
     for (Double d : list) { 
      res += d; 
     } 

     return res; 
    } 
} 
// ...and so on 

Bây giờ bạn có thể tạo ra một danh sách các ItemWrapper đối tượng, và calculateSomething trên chúng mà không cần kiểm tra loại của họ:

List<ItemWrapper> myList = new ArrayList<ItemWrapper>(); 

for (ItemWrapper w : myList) { 
    System.out.println(
     w.calculateSomething()); 
} 
+0

Tại sao tôi nhận được "Phương pháp trừu tượng không thể có nội dung" trên "int trừu tượng công khai"? – Zon

+0

@Zon Vì đó là lỗi sao chép/dán của tôi :-) Cảm ơn bạn đã chỉ ra. – dasblinkenlight

+0

myList luôn trống và không thể truy cập được. Làm thế nào chúng ta có thể thêm bất kỳ ItemWrapper vào myList trước khi looping, nếu không có ItemWrapper class (chỉ interface)? – Zon

4

Bạn nên sử dụng List<Object> hoặc bất kỳ lớp học nào phù hợp nhất. Tôi đã từng hỏi một câu hỏi tương tự mà tích lũy một vài câu trả lời rất tốt mà có rất nhiều thông tin có liên quan cho bạn. I would check it out. Về cơ bản, tất cả đều xuống đến PECS - Producer Extends, Consumer Super.

+0

Cảm ơn bạn đã chọn con trỏ, tôi đã thử nhưng không tìm thấy bài đăng này. Cảm ơn bạn đã cung cấp thông tin này. – keelar

+0

không sao. đã có một vấn đề tương tự một lần :) – oligofren