【问题标题】:Storing a reference to the object in ArrayList在 ArrayList 中存储对对象的引用
【发布时间】:2014-02-16 18:36:05
【问题描述】:

大家好,我正在尝试将当前引用存储到数组列表“pl”。 例如pl.add(this); 出于某种原因,我只得到对最后一项的引用,而没有得到以前的引用。循环确实会遍历所有三个项目。

下面是我得到的代码和输出。谁能告诉我我做错了什么谢谢你提前的帮助。

       // variables
private String productType;
private String hyperLinkParam;
private ArrayList <ProductList> pl = new ArrayList<ProductList> ();

public ProductList() {

    try {

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();

       InputStream url = null;
        url = getClass().getResourceAsStream("inventory.xml");


        Document doc = db.parse(url);
        doc.getDocumentElement().normalize();

        // loop through each item
        NodeList items = doc.getElementsByTagName("item"); //Returns a list of elements with the given tag name item
        for (int i = 0; i < items.getLength(); i++)
        {

                Element e = (Element) items.item(i);
                setHyperLinkParam(e.getAttribute("name").toString());
                setProductType(getTextValue(e,"productType"));
                System.out.print(e.getAttribute("name").toString());
                System.out.println(getTextValue(e,"productType"));

                pl.add(this);


         }

          for(int j=0; j < pl.size(); j++){
            System.out.print("getHyperLinkParam: " + pl.get(j).getHyperLinkParam());
            System.out.println("getProductType: " + pl.get(j).getProductType());
          }

Manufacture.java

    @WebMethod(operationName = "getProductList")
public ProductList getProductList() {
    try {
        ProductList productlist = new ProductList();
        if(productlist == null){
            return null;
        }else{
            return productlist;
        }
    } catch(Exception e){
        System.out.println("error: " + e.getMessage());
        return null;
    }
}

index.jsp

    <%
try {
org.soen487.supplychain.manufacturer.Manufacture_Service service = new org.soen487.supplychain.manufacturer.Manufacture_Service();
org.soen487.supplychain.manufacturer.Manufacture port = service.getManufacturePort();
// TODO process result here
org.soen487.supplychain.manufacturer.ProductList result = port.getProductList();
out.println("Result = "+result);

} catch (Exception ex) {
// TODO handle custom exceptions here
}
%>

【问题讨论】:

    标签: java arrays jsp arraylist


    【解决方案1】:

    这就是问题所在:

    pl.add(this);
    

    您一次又一次地添加相同的参考 (this)。 this 的值 只是对“当前”对象的引用 - 而您正在循环中修改该对象的内容。

    在循环的每次迭代中,您应该创建一个新的、单独的对象,设置 那个 对象的属性,然后将对该对象的引用添加到列表中。

    老实说,您将this 添加到列表中有点奇怪 - 通常这样的方法会在某个知道如何解析 XML 的类中,而不是数据项的实例本身。不清楚pl 是在哪里声明的,但您应该真正考虑一下程序的结构。

    【讨论】:

    • 我明白,但问题是我如何在上面的代码中创建一个新对象?我修改了我的代码以显示我声明变量的位置。我想每次都创建一个新的 pl 对象吗?感谢您的帮助
    • @KSM:你调用了构造函数。 pl 不是一个对象,它是一个变量——它的值是对列表的引用,而不是您要存储在其中的对象。我希望看到(在循环内)类似Foo foo = new Foo(); foo.setFirstValue(...); foo.setSecondValue(...); pl.add(foo);
    【解决方案2】:

    您不断将相同的对象 (this) 添加到列表中。尽管您更改了成员,但列表中的所有引用仍然引用同一个对象。

    您应该创建一个新对象并添加它。

    查看我的其他帖子

    【讨论】:

      【解决方案3】:

      我试图从这里发布的内容中猜测 ProductList 和 Product 的整体结构。问题是列表元素的列表和字段似乎位于单个类的上下文中,即 ProductList。这不行 - 需要两个类。

      // stores the data coming from a single Element ("item") of the document
      class Product {
          private String productType;
          private String hyperLinkParam;
          public setHyperLinkParam( String hlp ){
              hyperLinkParam = hlp;
          }
          public setProductType( String pt ){
              productType = pt;
          }
      }
      
      // Container for a list of products from an inventory
      class ProductList {
          private ArrayList <Product> pl = new ArrayList<Product> ();
          public ProductList() {
              DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
              DocumentBuilder db = dbf.newDocumentBuilder();
              InputStream url = getClass().getResourceAsStream("inventory.xml");
              Document doc = db.parse(url);
              doc.getDocumentElement().normalize();
      
              // loop through each item
              NodeList items = doc.getElementsByTagName("item"); 
              for (int i = 0; i < items.getLength(); i++){
                  Element e = (Element) items.item(i);
                  // create the single product from the current item
                  Product prod = new Product();
                  prod.setHyperLinkParam( e.getAttribute("name").toString() );
                  prod.setProductType( getTextValue( e, "productType") );
                  // add it to the list
                  pl.add( prod );
              }
          }
      
          void showList(){
              for( Product prod: pl ){
              System.out.print("getHyperLinkParam: " + prod.getHyperLinkParam());
                  System.out.println("getProductType: " + prod.getProductType());
              }
          }
      }
      

      注意:如果 ProductList 和 Product 的构造位于具有工厂方法 makeProductList 和 makeProduct 的工厂类中,那么一切都会变得更加清晰和清晰。 ProductList 应该有一个方法 addProduct 将 add 委托给它的 pl 成员。并且关于如何从 XML 中获取产品列表的知识应该在构造函数中 therenot,并且类似地,获取 Product 的字段值的方式来自“item”元素的不属于 Product 或 ProductList 的代码。

      【讨论】:

      • 上面的代码确实显示了不同的项目,在 Productlist 类中,但我无法访问 JSP 中的代码,我假设我不能返回正确的对象,我在上面的两个新小节中命名为代码 Manufacture.java 和 index.jsp。你能帮我更正吗
      • 我应该能够以 productlist.product.getMethod() 的形式访问它吗?
      • @KSM 我不熟悉 JSP,但是如果您需要获取 ProductList 的内容作为结果(如果这就是 "out.println("Result = "+result)"应该实现)那么您必须向 ProductList 添加一个 toString() 方法:使用 StringBuilder 并附加 pl 的所有元素。
      【解决方案4】:

      试试

      ProductList obj=new ProductList();
      // some work on this object and then store it in List
      pl.add(obj);
      

      它应该可以工作,因为它会给你新鲜的对象

      【讨论】:

      • 我添加了上面提到的新编码,但它似乎不起作用我在 org.soen487.supplychain.manufacturer.ProductList.(ProductList.java:47) 和行47 是我创建新 obj 对象的地方
      • org.soen487.supplychain.manufacturer.ProductList.(ProductList.java:47) 第 47 行是我创建新 obj 对象的位置
      • 使用 obj.setHyperLinkParam(e.getAttribute("name").toString()); obj.setProductType(getTextValue(e,"productType"));
      • 如果你在上面看新的编码,这就是我所做的,但它似乎不起作用
      • 检查 obj 引用的变量中存储了哪些值,我认为,这一次值出错了。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      • 2014-01-17
      • 1970-01-01
      相关资源
      最近更新 更多