【问题标题】:Print Different Object Data From ArrayList in Java从 Java 中的 ArrayList 打印不同的对象数据
【发布时间】:2019-01-04 07:58:21
【问题描述】:

有没有办法从包含不同对象的ArrayList 打印不同的数据? 例如,我创建了两个基本类:

import java.util.*;

class Furniture{
    String name;
    int weight;

    Furniture(String name, int weight){
        this.name = name;
        this.weight = weight;
    }

    String getName(){
        return name;
    }
    int getWeight(){
        return weight;
    }
    }
}
class Resident{
    String name;

    Resident(String name){
        this.name = name;
    }

    String getName(){
        return name;
    }
}

然后我将它们存储在ArrayList<Object> 中并想打印名称,方法是使用下面声明的printArrayList 方法:

public class Main{

public static <E> void printArrayList(ArrayList<E> arrayToPrint){
    for(E element : arrayToPrint){
        try{
            System.out.println(element.getName());
        }
        catch(Exception e){
            System.out.println("Exception e: " + e);
        }
    }
}

 public static void main(String []args){
    Furniture sofa = new Furniture("Sofa", 5);
    Resident mike = new Resident("Mike");

    ArrayList<Object> arrayList = new ArrayList<>();

    arrayList.add(sofa);
    arrayList.add(mike);
    printArrayList(arrayList);
}

现在,我知道并非所有对象都可以有变量名或声明的 get 方法,因此我尝试通过 try/catch 排除这些情况。 我也尝试通过使用 fe 来排除它:

if(elements.getName() == null)

还是一样的结果。

【问题讨论】:

  • 在访问它的方法之前,你应该强制转换你的对象。
  • 您可以使用instanceOf 方法检查对象是否属于特定类(如element instanceOf Furniture)或使用Reflection API 检查类/变量/方法是否存在
  • 我想知道首先在 List 中包含完全不相关的对象是否是个好主意。居民和家具似乎没有任何理由在同一个列表中。如果他们有,他们至少应该共享一个公共接口(@98​​7654331@?),你应该有一个List&lt;Named&gt;。
  • 你的第一个问题是ArrayList&lt;Object&gt;

标签: java list generics arraylist


【解决方案1】:

您不需要使用参数化类型。而是引入一个特定的接口(例如NameAware),该接口公开您的类实现的getName() 方法。通过这种方式,您可以依赖一个通用类型。

public interface NameAware{
   String getName();
}

public class Resident implements NameAware{
     ...
     public String getName(){
        return name;
    }
}

public class Furniture implements NameAware{
     ...
     public String getName(){
        return name;
    }
}

并将您的方法定义为:

public static void printArrayList(ArrayList<NameAware> arrayToPrint) {
    for (NameAware element : arrayToPrint) {
        try {
            System.out.println(element.getName());
        } catch (Exception e) {
            System.out.println("Exception e: " + e);
        }
    }
}

请注意,您应该从以下位置更改您的实际代码:

ArrayList<Object> arrayList = new ArrayList<>();

到

ArrayList<NameAware> arrayList = new ArrayList<>();

【讨论】:

  • 最好将参数声明为ArrayList&lt;? extends NameAware&gt;
  • 甚至更好 List&lt;? extends NameAware&gt; 或 Iterable&lt;? extends NameAware&gt;
  • @Lino 你是对的。但是对于实际需求来说,这不是阅读开销和不必要的东西吗? List&lt;? extends NameAware&gt; 意味着我们想要设置一些限制(如不在列表中添加元素)并打开泛型列表的可能性。但这会使代码阅读起来更复杂,实际上并不是必需的。
  • @Mick Mnemonic 我完全同意在实际代码中用List 替换所有声明的类型ArrayList,但对于Iterable,它看起来像是过早的代码泛化。为什么我们应该在实际上只使用 List 的方法中使 List 更加抽象?目前没有什么需要它,引入它会产生相反的感觉。
  • @davidxxx,是的,使用Iterable 不会有任何伤害,但也没有真正的帮助。该方法基本上是关于迭代的,所以从这个意义上说它是有道理的。
【解决方案2】:

最佳实践是使用getName 方法声明一个接口,并让Furniture 和Resident 实现它。

public interface Namable {
    public String getName();
}

然后,使用List&lt;Namable&gt; 而不是List&lt;Object&gt;:

Furniture sofa = new Furniture("Sofa", 5);
Resident mike = new Resident("Mike");

List<Namable> arrayList = new ArrayList<>();

arrayList.add(sofa);
arrayList.add(mike);

for (Namable n : arrayList) {
    System.out.println(n.getName());
}

【讨论】:

  • 如果他写道:“现在,我知道并非所有对象都可以具有变量名或声明的 get 方法,因此我试图通过 try/catch 排除这些情况。我还尝试使用 fe 排除它:"
猜你喜欢
  • 1970-01-01
  • 2018-05-03
  • 2020-08-09
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
相关资源
最近更新 更多