【问题标题】:Java - remove() function for ArrayList<class> (I need help) [duplicate]Java - ArrayList<class> 的 remove() 函数(我需要帮助)[重复]
【发布时间】:2019-08-15 01:30:18
【问题描述】:

如何删除我之前在 ArrayList 中添加的元素 我这样创建它:

public static ArrayList<Product> P = new ArraList<Product>(); 

我使用的方法:

public void removeProduct(Product p) {
    P.remove(p); // this way, did not solve the problem 
} 

//我做了(添加方法),它工作正常,一切都很好,我希望有人能帮助得到答案,谢谢:)

public void deleteProduct(String ID) {
    System.out.println("Enter product id to delete: ");
    ID = input.next();
    for(Product m : s.P) {
        if(ID.equals(m.getID())) {
            s.P.remove(ID);
        }
        else {
            System.out.println("ID is not exist");
        }
    }
}

//和

public void removeProductToCart(Product p) {
    viewShoppingCart();
    System.out.println("Enter product id to remove it: ");
    String ID = input.next();
    for(Product r : s.P) {
        if(ID.equals(r.getID())) {
            s.P.remove(p);
        }
        else {
            System.out.println("ID is not exist");
        }
    }
}

【问题讨论】:

  • 具体问题是什么。 “我需要帮助”并没有告诉我们您所面临的问题。你在做什么,你期望发生什么,反而会发生什么?准确。
  • 你写I did the (added the method) and it works and everything is fine。如果是all fine,你需要什么?
  • 可能抛出异常。如果是这样,了解它会有所帮助(消息,在哪里,...)

标签: java


【解决方案1】:

你需要使用迭代器,否则你会得到java.util.ConcurrentModificationException。抛出异常,因为您在列表上执行 2 个操作:iterationremoval

所以,你需要这样的东西:

for (Iterator<Book> it = s.P.listIterator(); it.hasNext(); ) {
    Product r = it.next();
    if(ID.equals(r.getID())) {
        it.remove(r);
    }
}

因为根本原因是执行 2 次操作,所以还有另一种方法 - 只需在迭代的每一步创建列表的副本:

for(Product m : new ArrayList<>(s.P)) {
    if(ID.equals(m.getID())) {
        s.P.remove(m);
    }
}

注意:出于性能考虑(每一步的二次内存使用和线性删除),我不推荐最后一种方法。我给出这个例子只是为了强调抛出 java.util.ConcurrentModificationException 的根本原因。

【讨论】:

    【解决方案2】:

    2 个问题:

    1. s.P 是产品列表,而不是字符串,因此调用 remove(String) 不起作用。
    2. 删除 for-each 循环中的元素将引发 ConcurrentModificationException

    可能的解决方案:

    public void removeProductToCart(Product p) {
        viewShoppingCart();
        System.out.println("Enter product id to remove it: ");
        String ID = input.next();
        Product toRemove = null;
        for(Product r : s.P) {
            if(ID.equals(r.getID())) {
                toRemove = r;
                break;
            }
        }
        if(toRemove == null) {
            System.out.println("ID is not exist");
        }
        else {
            s.P.remove(toRemove);
        }
    }
    


    如果传递的参数是需要删除的产品,这可以简化。

    相同的逻辑可以应用于第一个函数:

    public void deleteProduct(String ID) {
        System.out.println("Enter product id to delete: ");
        ID = input.next();
        Product toRemove = null;
        for(Product r : s.P) {
            if(ID.equals(r.getID())) {
                toRemove = r;
                break;
            }
        }
        if(toRemove == null) {
            System.out.println("ID is not exist");
        }
        else {
            s.P.remove(toRemove);
        }
    }
    

    注意:方法参数目前没有任何作用。为什么不使用它们而不是循环查找产品?

    【讨论】:

    • 非常感谢,你救了我,但还有一个东西购物车从来没有删除过那里,但谢谢我能理解你的方式
    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 2015-12-10
    • 1970-01-01
    • 2015-08-29
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    相关资源
    最近更新 更多