【问题标题】:Extending ArrayList and Creating new methods扩展 ArrayList 并创建新方法
【发布时间】:2011-09-25 08:47:14
【问题描述】:

我在掌握某些东西时遇到了一点问题 - 我可能完全错了。

我正在尝试创建一个扩展 ArrayList 的类,但有几个方法可以增加功能(至少对于我正在开发的程序而言。)

其中一种方法是 findById(int id),它在每个 ArrayList 对象中搜索特定的 id 匹配项。到目前为止它正在工作,但它不会让我这样做for (Item i : this) { i.getId(); }

我不明白为什么?

完整代码:

public class CustomArrayList<Item> extends ArrayList<Item> {

    // declare singleton instance
    protected static CustomArrayList instance;

    // private constructor
    private CustomArrayList(){
        // do nothing
    }

    // get instance of class - singleton
    public static CustomArrayList getInstance(){
        if (instance == null){
            instance = new CustomArrayList();
        }
        return instance;
    }

    public Item findById(int id){
        Item item = null;
        for (Item i : this) {
            if (i.getId() == id) {
                      // something
         }
        }
        return item;
    }
    public void printList(){
        String print = "";
        for (Item i : this) {
            print += i.toString() + "\n";
        }
        System.out.println(print);
    }
}

【问题讨论】:

    标签: java arraylist extend


    【解决方案1】:

    getId() 是什么?大概是some类中的一个方法,但我们不知道是哪个类。

    如果您实际上有一个名为Item 的类和一个getId() 方法,这是一个列表,您只需要阻止您的类是通用的。所以不要这样:

    public class CustomArrayList<Item> extends ArrayList<Item> {
    

    你想要的:

    public class CustomArrayList extends ArrayList<Item> {
    

    当前在您的类中,Item 不引用名为 Item 的类,它引用名为 Item类型参数

    现在个人:

    • 除非你真的必须这样做,否则我不会避免创建单例
    • 如果你必须这样做,我会避免以你的方式创建它们(这不是线程安全的)
    • 我不会扩展 ArrayList&lt;&gt;,除非我真的必须这样做,我更喜欢组合而不是继承

    【讨论】:

    • 我正在创建一个单例,因为我只能拥有一个。我知道我创建它的方式不是线程安全的——我需要一个“锁定方法”,对吗? aioobe 发布的内容解决了我的问题,但我仍然对创建线程安全的单例感兴趣。
    • 在 Java 1.5+ 中创建单例的首选方法是使用枚举。例如看这个问题:stackoverflow.com/questions/70689/…
    【解决方案2】:

    改变

    public class CustomArrayList<Item> extends ArrayList<Item> {
    

    public class CustomArrayList extends ArrayList<Item> {
    

    我怀疑Item 是您要存储在列表中的类的名称。通过在CustomArrayList 之后添加&lt;Item&gt;,您将引入一个隐藏此类的类型参数


    &lt;Item&gt;参数,你的代码等于

    public class CustomArrayList<T> extends ArrayList<T> {
        // ...
            for (T i : this) { i.getId(); }
        // ...
    }
    

    这显然不会总是有效,因为T 可以指代任何类型。

    【讨论】:

    • 太棒了。这只是正确的语法,还是我试图做其他事情?太感谢了!快速回复。
    • 这可能是您的场景的正确语法。更新了答案以解释原因。
    • 谢谢!这解释得很好。
    • 补充一点,如果你想支持各种元素类型,常用超类型Item,使用public class ItemArrayList&lt;T extends Item&gt; extends ArrayList&lt;T&gt; { ... }
    猜你喜欢
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 2011-06-26
    相关资源
    最近更新 更多