【问题标题】:Creating instance list of different objects创建不同对象的实例列表
【发布时间】:2012-06-19 20:57:37
【问题描述】:

我正在尝试创建一个包含不同类实例的数组列表。如何在不定义类类型的情况下创建列表? (<Employee>)

List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee());
Employee employee = employees.get(0);

【问题讨论】:

    标签: java arrays class object arraylist


    【解决方案1】:

    您可以创建一个对象列表,例如List&lt;Object&gt; list = new ArrayList&lt;Object&gt;()。由于所有类的实现都从java.lang.Object 类隐式或显式扩展,因此此列表可以包含任何对象,包括EmployeeIntegerString 等的实例。

    当您从此列表中检索元素时,您将检索到 Object 而不再是 Employee,这意味着您需要在这种情况下执行显式转换,如下所示:

    List<Object> list = new ArrayList<Object>();
    list.add("String");
    list.add(Integer.valueOf(1));
    list.add(new Employee());
    
    Object retrievedObject = list.get(2);
    Employee employee = (Employee)list.get(2); // explicit cast
    

    【讨论】:

    • 列表 example=new ArrayList(); example.get(0).myFunction(); AND 列表 示例=新 ArrayList(); example.get(0).myFunction();我使用了这些代码,但错误:找不到符号符号:方法 myFunction();
    • 当你得到像example.get(0) 这样的对象时,它应该是List&lt;Object example = new ArrayList&lt;Object&gt;();,你需要进行显式转换。哪个类实现了方法 myFunction()?如果Employee 实现myFunction() 你应该做类似((Employee)(example.get(0))).myFunction(); 的事情,这样你就表明从位置0 检索到的对象可以作为雇员处理。当然如果不是就会抛出异常。
    • 类苹果{ int price; public void myFunction(int iPrice) { price=iPrice; } } 类橙色{ 整数价格; public void myFunction(int iPrice) { price=iPrice; } } public class main { public static void main(String[] args) { List list= new ArrayList(); //创建 3 个苹果对象到列表 list.add(new apple()); list.add(新苹果()); list.add( 新橙色() );列表.get(0)。 /* “得到(0)。”这没有使用苹果对象和我的函数 */ } }
    • 代替list.get(0).myFunction(..)试试((apple)(list.get(0))).myFunction(1);
    • 检查我在此处粘贴的代码:heypasteit.com/clip/0DGC 以查看这是否是您要执行的操作...
    【解决方案2】:
    List<Object> objects = new ArrayList<Object>();
    

    objects 列表将接受任何Object

    你可以这样设计

    public class BaseEmployee{/* stuffs */}
    
    public class RegularEmployee extends BaseEmployee{/* stuffs */}
    
    public class Contractors extends BaseEmployee{/* stuffs */}
    

    在列表中

    List<? extends BaseEmployee> employeeList = new ArrayList<? extends BaseEmployee>();
    

    【讨论】:

    • 不鼓励使用原始类型。 Java 语言规范甚至指出,Java 编程语言的未来版本可能会禁止使用原始类型。此外,正如问题所暗示的那样,使用 extends 会阻止向列表中添加元素。
    • ListArrayListraw types,不是吗? JLS 第 4.8 节说:“仅允许使用原始类型作为对遗留代码兼容性的让步。在将泛型引入 Java 编程语言之后编写的代码中使用原始类型是强烈不鼓励. Java 编程语言的未来版本可能会禁止使用原始类型"
    • @Edwin,更新了答案,但我仍然建议 OP 在这种情况下使用 ? extends Base 模式
    • 如果你在泛型类型中使用? extends Base,你可以从结构中取出东西,但不能把东西放进去。您对employeeList 的引用永远不允许添加新的Employee ,因为它使用的是通配符引用。但是,它可以安全地读取它已经包含的任何内容作为BaseEmployee。恕我直言,没有办法按照问题建议使用通配符。
    【解决方案3】:

    如果您的实例不能比Object 更具体,请使用:

    List<Object> employees = new ArrayList<Object>();
    

    否则尽可能具体:

    List<? extends SpecificType> employees = new ArrayList<? extends SpecificType>();
    

    【讨论】:

      【解决方案4】:

      List anyObject = new ArrayList();

      or

      List&lt;Object&gt; anyObject = new ArrayList&lt;Object&gt;();

      现在anyObject 可以容纳objects of any type

      使用instanceof了解what kind of object it is

      【讨论】:

        【解决方案5】:

        我相信你最好的办法是将列表声明为对象列表:

        List<Object> anything = new ArrayList<Object>();
        

        然后你可以放任何你想要的东西,比如:

        anything.add(new Employee(..))
        

        显然,如果没有正确的转换,您将无法从列表中读取任何内容:

        Employee mike = (Employee) anything.get(0);
        

        我不鼓励使用以下原始类型:

        List anything = new ArrayList()
        

        由于泛型的全部目的正是为了避免它们,在未来 Java 可能不再支持原始类型,原始类型被认为是遗留的,一旦你使用了原始类型,你就不能再使用泛型了。给出参考。例如,看看另一个问题:Combining Raw Types and Generic Methods

        【讨论】:

          【解决方案6】:

          如何在不定义类类型的情况下创建列表? (&lt;Employee&gt;)

          如果我没看错,您只是想避免指定类型,对吗?

          在 Java 7 中,你可以这样做

          List<Employee> list = new ArrayList<>();
          

          但是正在讨论的任何其他替代方案都只会牺牲类型安全。

          【讨论】:

            【解决方案7】:

            我看到所有答案都建议使用一个包含 Object 类的列表,然后显式转换所需的类,我个人不喜欢这种方法。

            对我来说更好的方法是创建一个接口,其中包含用于从我想放入列表中的某些类中检索或存储数据的方法。让这些类实现该新接口,将接口中的方法添加到它们中,然后您可以用接口对象填充列表 - List&lt;NewInterface&gt; newInterfaceList = new ArrayList&lt;&gt;() 因此能够从列表中的对象中提取所需的数据而无需显式施放任何东西。

            如果需要对列表进行排序,也可以在界面中放一个比较器。

            【讨论】:

              【解决方案8】:

              我知道这是一个老问题,但有一种很好且简单的方法可以做到这一点(它适用于最新版本的 ElasticSearch Rest API)。

              搜索对象如下:

               SearchResponse<JsonData> search = client.search(s -> s
                .index(index)
                .query(query),
                JsonData.class);
              

              然后我像这样迭代响应:

               for (Hit<JsonData> hit: search.hits().hits()) {
                String stringSource = hit.source().toString();
                MySavedRegister mySavedRegister = mapper.readValue(stringSource, mySavedRegister .class);
                mylist.add(esGenericEvent);
               }
              

              其中 mySavedRegister 代表具有匹配源参数的类。

              【讨论】:

              • 抱歉,您的回答与问题无关。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-07-16
              • 1970-01-01
              • 1970-01-01
              • 2010-12-24
              • 1970-01-01
              • 1970-01-01
              • 2021-07-22
              相关资源
              最近更新 更多