【问题标题】:Creating an ArrayList and adding items创建 ArrayList 并添加项目
【发布时间】:2011-02-17 20:01:24
【问题描述】:

我正在学习 Java,但遇到了 ArrayList 的问题。

首先,我有一个名为 Item 的类,我用它创建各种项目对象。 然后我有一个类目录,它是一个数组列表,应该包含我创建的项目对象的列表。 目前,我可以通过在 Catalog 对象上调用 addItem 方法并手动输入要添加的项目对象的名称(item1 item2 item3 等)手动将项目添加到目录中 但是我想知道是否有一种方法可以在每次创建项目对象时自动将项目添加到 ArrayList 中?

我应该提一下,我的列表需要包含无限数量的项目,所以我没有在我的代码中指定大小。 任何帮助将不胜感激 :) 谢谢

import java.util.ArrayList;

public class Catalogue
{
   private ArrayList<Item> catalogue;

    public Catalogue ()
    { 
      catalogue = new ArrayList<Item>();
    }


    public void addAnItem(Item item)
    {
      catalogue.add(item);
    }
}

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    Catalogue 用作Item 工厂:

    public class Catalogue
    {
      ...
    
      public Item createItem()
      {
        Item item = new Item();
        catalogue.add(item);
        return item;
      }
    
      ...
    }
    

    另一种方法:将Catalogue设为单例并让项目自行添加。

    【讨论】:

    • 这样就完成了工作,如果我当天没有缺票的话会得到 +1。但是,值得注意的是,这将您限制在一个目录中。单例通常被认为是一种反模式。
    • @glowcoder -- 使用单个目录,您的意思是实现单例模式,是吗?使用工厂模式允许多个目录(以及多个目录中的项目),因此这是我的第一个想法 :)
    • 为了清楚起见:这是目录中的一种方法。如果不调用目录的 createItem(),您应该无法创建项目。可能通过使 Item 构造函数包受保护或将 Item 定义为接口并让 createItem 实例化 Item 的匿名内部类实现。如果这太快了(对于现阶段的 Will),请不要打扰 :)
    • 非常好,外挂。为了清楚起见,我编辑了我的帖子......如果多个开发人员正在处理项目,使用受保护的构造函数并不能防止包内的滥用,因此接口+匿名实现是最安全的方式。具有私有构造函数的内部类是另一种方式。
    • @Matten 我添加了一个我自己的答案,此时无耻地窃取了两个领先的答案:)
    【解决方案2】:

    您可以这样做的一种方法是,如果您将 Catalog 传递给 Item 类的构造函数,并且一旦设置了项目,就在此时将项目添加到目录中。

    它可能看起来像这样

    public Item(Catalogue catalogue) {
       // set up item here
    
       // finally add item to the catalogue
       catalogue.addAnItem(this);
    }
    

    【讨论】:

    • 也是一个非常好的结构。如果所有项目都相同(同一个类别),那么可以说比 Matten 的工厂模式更好(如果有不同种类的项目会更好)。
    【解决方案3】:

    我在 Matten 和 Codemwnci 的回答中放了一些 cmets,下面是对它们的解释。

    Codemwnci 建议您不应该在不设置目录的情况下构建项目。

    public class Item {
     public Item(Catalog catalog) {
       // set up item here
    
       // finally add item to the catalog
       catalog.addAnItem(this);
     }
    }
    

    此显式构造函数删除了隐式默认(无参数)构造函数,如果没有有效的非空目录,您将无法构造项目。

    如果您有各种类型的物品,具有(略微)不同的行为,那么 Matten 的回答可能会更好地为您服务(尽管此处略有更改)。

    作为一个例子,我正在使用一本书(这是你的项目)。我的书有标题、作者、textAtTheBack 和权重。

    interface Book {
      String getTitle();
      String getAuthor();
      String getTextAtTheBack();
      Long getWeight(); // in grams, can be very heavy!
    }
    
    public class Catalog {
      private ArrayList<Book> catalogue;
      public Book createPaperback(final String title, final String author, 
                                  final String tatb, final Long weight) {
        Book b = new Book() {
          String getTitle() { return title; }
          String getAuthor() {return author; }
          String getTextAtTheBack() {return tatb;}
          Long getWeight() {return weight;}
        }
        catalogue.add(b);
        return b;
      }
    
      public Book createEBook(final String title, final String author, 
                                  final String tatb) {
        Book b = new Book() {
          String getTitle() { return title; }
          String getAuthor() {return author; }
          String getTextAtTheBack() {return tatb;}
          Long getWeight() {return 0;} // Yep - no weight!
        }
        catalogue.add(b);
        return b;
      }
    }
    

    或者,您可以有不同的目录:

    public abstract class Catalogue {
        private final List<Book> books = new ArrayList<Book>;
    
        public abstract Book (final String title, final String author, 
                                  final String tatb, final Long weight);
    
        /** Find the book with the given title (not null) in the current catalogue.
         * @return the book, or null if not found.
         */
        public void findBook(String title) {
            for (Book b : books) {
               if (b.getTitle().equalsIgnoreCase(title)) {
                   return b;
               }
            }
            return null;
        }
    
        protected void addBookToCatalogue(Book b) {
            books.add(b);
        }
    }
    
    public class EbookCatalogue extends Catalogue {
        public Book (final String title, final String author, 
                                  final String tatb, final Long weight) {
          Book b = new Book() {
            String getTitle() { return title; }
            String getAuthor() {return author; }
            String getTextAtTheBack() {return tatb;}
            Long getWeight() {return 0;} // ignore weight
          }
          addBookToCatalogue(b);
          return b;
        }
    }
    

    在程序的其余部分中,您可以有多个目录,每个目录的图书类型略有不同,但程序不需要知道这一点。

    我认为在这种情况下,codemwnci 的简单构造函数是最好的,但如果您的情况需要更灵活的解决方案,还有其他解决方案。

    【讨论】:

    • 你这个小偷:) +1 这个扩展的例子,但是......你不应该从EbookCatalgoue 中删除abstract 关键字吗?为什么不从电子书的位和字节在帐户中? ;)
    • @matten 哎呀。 abstract 关键字确实不应该存在。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 2014-01-27
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多