简体   繁体   English

如何在Java中扩展列表以存储其他元数据并强制其仅接受一种类型的对象?

[英]How to extend a list in java to store additional metadata and force it to accept only one type of objects?

In addition to the included items, I have to store the name and the id of the List inside itself. 除了包含的项目外,我还必须在内部存储列表的名称和ID。 Thus i extended an ArrayList as follows: 因此,我扩展了ArrayList ,如下所示:

class MyList<E> extends ArrayList<E>{
    private int id;
    private String name;

    MyList(int id, String name){
        this.id = id;
        this.name = name;
    }
    id getId(){       return id;   }
    String getName(){ return name; }
}

Now I realized, that this extension will only hold one specific type of objects. 现在我意识到,此扩展将仅包含一种特定类型的对象。 So how can I remove the generic character of my list? 那么,如何删除列表的通用字符?

class MyList<MyObject> extends ArrayList<E>
class MyList<MyObject> extends ArrayList<MyObject>

...and so on fails. ...等等失败。 I want to instantiate my list by 我想实例化我的清单

MyList mylist = new MyList();

...and it should automatically accept only MyObject s... ...并且它应该仅自动接受MyObject s ...

(Would it be better to create a wrapper which holds an ArrayList in addition to the meta? But because it is still a list, why remove all list-typical capabilities...) (最好创建一个包装,该包装除了包含meta之外还包含一个ArrayList ?但是由于它仍然是一个列表,因此为什么要删除所有列表类型的功能...)

You'll need 你需要

class MyList extends ArrayList<MyObject>

When you declare a type parameter for your class declaration like so 当您为类声明声明类型参数时,就像这样

class MyList<MyObject> ...

the type MyObject> is not your type, it is a type variable that also has the name MyObject . 类型MyObject>不是您的类型,它是一个类型变量,也具有名称MyObject

What you want, is to use your MyObject type as a type argument for the ArrayList type parameter as shown above. 您想要的是使用MyObject类型作为ArrayList类型参数的类型参数,如上所示。


But, as others have suggested, composition is probably a better way to do this, ie the wrapper you suggested in your question. 但是,正如其他人所建议的那样,合成可能是一种更好的方法,例如,您在问题中建议的包装器。

As has been answered already, the correct declaration would be 正如已经回答的那样,正确的声明是

class MyList extends ArrayList<MyObject>

Even though you have no interest in overriding any ArrayList methods, you should consider composition over inheritance for this type of scenarios. 即使您对覆盖任何ArrayList方法都不感兴趣,对于这种类型的方案,也应考虑在继承上进行组合。

Example: 例:

class MyList implements Iterable<MyObject> {
    private final int id;
    private final String name;
    private final List<MyObject> list;

    MyList(int id, String name){
        this.id = id;
        this.name = name;
        this.list = new ArrayList<>();
    }

    int getId()                     { return id; }

    String getName()                { return name; }

    MyObject get(int i)             { return list.get(i); }

    void add(MyObject o)            { list.add(o); }

    void remove(MyObject o)         { list.remove(o); }

    void remove(int i)              { list.remove(i); }

    void set(int i, MyObject o)     { list.set(i, o); }

    boolean contains(MyObject o)    { return list.contains(o); }

    int size()                      { return list.size(); }

    @Override
    Iterator<MyObject> iterator()   { return list.iterator(); }
}

With this: 有了这个:

  • You can easily switch the ArrayList for a LinkedList , or any other list; 您可以轻松地将ArrayList切换为LinkedList或任何其他列表。
  • You control the methods this class offers; 您可以控制此类提供的方法。
  • If you like the chaining style, you may change those void for MyList ; 如果您喜欢链接样式,则可以更改MyList那些void
  • etc .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM