【问题标题】:Storing Objects of multiple classes in an Array List, then accessing their attributes将多个类的对象存储在一个数组列表中,然后访问它们的属性
【发布时间】:2022-01-21 11:45:52
【问题描述】:

我有一类(子)对象

public class SubObjects {
    
    int depth;
    
    public SubObjects(int d) {
        this.depth = d;
    }
}

还有一类对象

public class Objects {
    
    private int height;
    private int width;
    ArrayList<SubObjects> liste;
    
    public Objects(int h, int w) {
        this.height = h;
        this.width = w;
        this.liste = new ArrayList<>();
    }
}

对象包含值高度和宽度以及子对象的 ArrayList。这可以按预期工作,但是我确实想在这些 ArrayList 中存储来自不同类的多种类型的子对象。

经过一番谷歌搜索后,我将 Objects 类更改为

public class Objects {
    
    private int height;
    private int width;
    ArrayList<Object> liste;
    
    public Objects(int h, int w) {
        this.height = h;
        this.width = w;
        this.liste = new ArrayList<Object>();
    }
}

这允许我按照我的意图将来自第二类 SubObjects2 的对象存储在 ArrayList 中

public class SubObjects2 {
    
    int weight;
    
    public SubObjects2(int weight) {
        this.weight = weight;
    }
}

这太棒了,我以为我已经解决了它,但后来我运行了主类,而我用早期的实现可以从 ArrayList 中的对象中返回带有 getter 的值

... liste.get(i).depth (in a for loop)

同样的查询现在返回以下错误

Unresolved compilation problem: 
    depth cannot be resolved or is not a field

我现在如何访问存储在 ArrayList 中的子对象内的值?

【问题讨论】:

  • public int depth代替int depth
  • 对象和子对象有什么区别?为什么他们有s?它们是东西的集合吗?还是一件事? SubObject 与 Object 有关系吗?也许你的意思是让 SubObject 扩展 Object?对象是由其他对象还是子对象组成的?

标签: java object arraylist


【解决方案1】:

您的问题是 Object 类没有名称为 depth 的字段,只有 SubObject 具有此属性

如果你的所有类型都有你想要获取的公共属性,你可以创建一个接口,并且所有类型都应该实现它

interface SubObject {
    int value();
}

public class SubObjects implements SubObject {

    ...

    @Override
    public int value() {
        return depth;
    }
}

public class SubObjects2 implements SubObject {

    ...

    @Override
    public int value() {
        return weight;
    }
}
       

现在您将创建一个子对象列表,在循环中,它将是

for (int i = 0; i < lists.size() ; i++) {
    int value = lists.get(i).value();
}

另一种解决方案是在获取值之前检查类型并进行转换

List<Object> lists = new ArrayList<>();
for (int i = 0 ; i < lists.size(); i++) {
    Object object = lists.get(i);
    if (object.getClass() == SubObjects.class) {
        SubObjects subObject = (SubObjects) object;
        int depth = subObject.depth;
    }
    
    else if if (object.getClass() == SubObjects2.class) {
        SubObjects2 subObject2 = (SubObjects2) object;
        int weight = subObject2.weight;
    }
}

【讨论】:

  • 对于子对象不实现公共接口的情况,另一种解决方案是使用访问者模式,它稍微复杂一些,但避免了 Object.getClass() 所需的反射。例如,参见stackoverflow.com/questions/6762256/…
  • 我假设只是将 SubObjects2 中的字段重命名为“深度”也不会削减它?
  • 如果没有通用接口,需要判断是SubObjects还是SubObjects2然后进行转换获取深度,可以将接口方法命名为depthgetDepth并使用
  • 第一行会将对象从Object 类型转换为SubObjects 类型,现在您可以像使用任何其他子对象一样使用它并从中获取深度
  • 知道了,谢谢!
【解决方案2】:

如果两个类之间没有关系,除了它们都继承了所有对象都扩展的 Object 类,并且您希望将这两个类的对象存储在同一个列表中,您可以将它们存储在对象列表中。

在您可以访问对象的属性之前,您需要将其转换为您想要使用的类型。这就是泛型之前的做法。

        List list = new ArrayList(List.of(Integer.valueOf(1), "hello"));
        
        for(Object o: list){
            if (o instanceof Integer){
                System.out.println("o is an integer.");
                Integer i = (Integer) o;
                System.out.println(i.intValue());
            } else if (o instanceof String){
                System.out.println("o is a string.");
                String s = (String) o;
                System.out.println(s.length());
        }
    }

【讨论】:

    猜你喜欢
    • 2016-07-13
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 2013-03-01
    • 2010-12-11
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    相关资源
    最近更新 更多