【问题标题】:how to return arraylist of multiple class in Java?如何在Java中返回多个类的arraylist?
【发布时间】:2015-09-15 04:53:03
【问题描述】:

我要做一个返回多个Object的ArrayList的方法,像这样:

public ArrayList<Object> getData(Object similar) {

    //I suppose that I have 2 ArrayList that already contain data here
    ArrayList<Human> humans = new ArrayList<Human>();
    ArrayList<Animal> animals = new ArrayList<Animal>();

    if (similar.getClass().equals(Human.class)) {
        return humans;
    }

    if (similar.getClass().equals(Animal.class)) {
        return animals;
    }

    return null;
}

我的想法是检查 Object 参数的类型,如果是 Human 类,则返回 Human 的 ArrayList。但是由于类型不兼容,我不能那样返回。
问题是返回对象不具体。
我如何解决它?谢谢!

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    我不知道你为什么会这样,工厂模式听起来是个更好的主意,但可能类似于...

    public <T> ArrayList<T> getData(T similar) {
        if (similar.getClass().equals(Human.class)) {
            return (ArrayList<T>) new ArrayList<Human>();
        }
    
        if (similar.getClass().equals(Animal.class)) {
            return (ArrayList<T>) new ArrayList<Animal>();
        }
    
        return null;
    }
    

    然后你应该能够使用类似的东西

    ArrayList<Human> humans = getData(new Human());
    ArrayList<Animal> animals = getData(new Animal());
    

    叫它

    根据您想要的严格程度,您还可以使用类似...

    if (Human.class.isInstance(similar)) {
    

    这将允许您捕获Human 的子类

    然而,对我来说,这没有任何意义。你的方法应该清楚地定义它愿意做什么。也许,与其尝试使用单个方法为多个类返回数据,不如考虑使用工厂模式,例如...

    public abstract class AbstractFactory<T> {
        public abstract List<T> getData();
    }
    
    public class HumanFactory extends AbstractFactory<Human>{
    
        @Override
        public List<Human> getData() {
            return new ArrayList<>(); // Or what ever data you need it filled with
        }
    
    }
    
    public class AnimalFactory extends AbstractFactory<Animal>{
    
        @Override
        public List<Animal> getData() {
            return new ArrayList<>(); // Or what ever data you need it filled with
        }
    
    }
    

    【讨论】:

    • ArrayList 人类 = getData(new Human());很傻;如果他知道他想要 ArrayList,他可以使用 ArrayList human = new ArrayList()
    • @DarkSquirtings Duh,我只是遵循允许 OP 开始的内容,正如我所说,如果我真的那么担心,我会简单地使用工厂模式
    【解决方案2】:

    我不确定这是否是您要查找的内容,但如果我了解您正在尝试正确执行的操作,则应该可以。

    你可以通过使用泛型来简化你正在做的事情

    public ArrayList<T> getData(T similar) {
        return new ArrayList<T>();
    }
    

    这将返回您传递给函数的任何类型的 ArrayList。

    【讨论】:

    • 与仅调用 new ArrayList() 相比,这有何改进?他也不能在不知道类的情况下调用方法。
    【解决方案3】:

    这里是你使用 generic 方法的地方!您应该将代码更改为:

    public <T> ArrayList<T> getData (T similar) {
        return new ArrayList<T> ();
    }
    

    但这真的没有意义。因为你为什么想要一种方法来创建ArrayList?你可以像这样创建任何你喜欢的类型:

    ArrayList<WhateverTypeYouLike> = new ArrayList<> ();
    

    但如果你真的想要这样做,这里有一些关于泛型方法的更多信息:

    https://docs.oracle.com/javase/tutorial/extra/generics/methods.html

    【讨论】:

    • 我知道如何创建这样的 ArrayList,但这不是我想要的。我的方法获取参数的类型,取决于它,我知道我应该返回什么。我编辑了我的问题,我希望它更清楚!
    • 但是你为什么要这个?如果可以将对象传递给方法,则必须知道它的类型。这意味着您可以使用对象的类型创建一个数组列表。无需编写方法。这是作业还是什么? @NgoKimHuynh
    • 我知道我可以创建 2 个返回 ArrayList 和 ArrayList 的方法。但如果我的想法可行,我不需要写2次。
    • 看来你误会了。但无论如何。
    【解决方案4】:

    问题出在:如果您的方法定义表明您正在返回一个ArrayList&lt;Object&gt;,那么调用者期望收到一个ArrayList&lt;Object&gt;ArrayList&lt;Human&gt; 在可以放入其中的内容方面受到更多限制,因此无法履行类定义中规定的合同。

    此外,如果您在编译时不知道要传递给创建 ArrayList 的方法的对象是什么类,那么您也不知道您收到的是哪种 ArrayList,所以即使您的方法确实有效,但对您没有任何好处。

    我不确定你想做什么,但第一步可能是确保你不只是想设计一种更复杂的方式来使用ArrayList&lt;Human&gt; myList = new ArrayList&lt;Human&gt;();

    【讨论】:

      【解决方案5】:

      您的代码无法编译,因为ArrayList&lt;Human&gt; 不是 ArrayList&lt;Object&gt; 的子类型。对于数组,情况就不同了。 Human[]Object[] 的子类型。这样做的原因是通过使用类型系统来防止运行时错误。如果您的代码将编译调用者可能会执行以下操作:

      ArrayList<Object> aList = getData(new Human());
      list.add("some String");
      

      毕竟,aList 应该包含任意的Objects,因此可以编译。如果你用数组做到这一点。添加String 时,您会得到一个ArrayStoreException

      对此可以做些什么?这取决于您的要求。但是@Sweeeper 和@FrozenHawk 提供的代码可能适合你:

      public <T> ArrayList<T> getData (T similar) {
        return new ArrayList<T> ();
      }
      

      如果这不是您的意图,请在 cmets 中询问。有更多的模式。

      【讨论】:

        猜你喜欢
        • 2018-10-20
        • 2023-03-10
        • 2014-11-28
        • 2020-07-27
        • 1970-01-01
        • 2016-02-22
        • 2021-06-10
        • 2012-05-27
        • 1970-01-01
        相关资源
        最近更新 更多