仅当列表中不存在类似项目时才将项目添加到ArrayList

时间:2018-04-10 08:43:59

标签: java loops arraylist bluej

这是ArrayList所基于的单独类Product的代码。本章让我们学习了ArrayList,Loops和Iterator,所以任何比这更高级的东西都没有被覆盖,并不打算用来完成练习。

public class Product
{
    // An identifying number for this product.
    private int id;
    // The name of this product.
    private String name;
    // The quantity of this product in stock.
    private int quantity;

    /**
     * Constructor for objects of class Product.
     * The initial stock quantity is zero.
     * @param id The product's identifying number.
     * @param name The product's name.
     */
    public Product(int id, String name)
    {
        this.id = id;
        this.name = name;
        quantity = 0;
    }

    /**
     * @return The product's id.
     */
    public int getID()
    {
        return id;
    }

    /**
     * @return The product's name.
     */
    public String getName()
    {
        return name;
    }

    /**
     * @return The quantity in stock.
     */
    public int getQuantity()
    {
        return quantity;
    }

    /**
     * @return The id, name and quantity in stock.
     */
    public String toString()
    {
        return id + ": " +
               name +
               " stock level: " + quantity;
    }


public class StockManager
{
    // A list of the products.
    private ArrayList<Product> stock;

    /**
     * Initialise the stock manager.
     */
    public StockManager()
    {
        stock = new ArrayList<>();
    }

    /**
     * Add a product to the list.
     * @param item The item to be added.
     */
    public void addProduct(Product item)
    {
        stock.add(item);
    }

如何设置项目是在创建对象时创建StockManager对象和一些Product对象(输入ProductID和ProductName的参数)。然后我可以调用默认的addProduct方法将新创建的Product对象添加到ArrayList。我的任务是修改addProduct方法,这样如果已经在列表中输入了具有相同ID的产品,则不会将新产品添加到列表中。

起初,我以为我可能应该使用“for each”循环并执行以下操作:

public void addProduct(Product item)
{
  for(Product product : stock){
      if(product.getID()!=item.getID())
      stock.add(item);
      }

但是这无法在列表中添加任何内容。如果我使用此方法将产品对象添加到列表中,然后调用方法来打印/查找产品,则只返回null并显示没有输入任何内容。

然后我想也许我应该做像

这样的事情
public void addProduct(Product item)
{
  if(!stock.contains(item.getID()))
   stock.add(item);

但这也不起作用。我的教授暗示我应该使用null值,但我搞乱了null并且它永远不会起作用,因为getID是一个整数,即使我让它工作,我觉得我没有正确设置问题。 / p>

6 个答案:

答案 0 :(得分:3)

public void addProduct(Product item)
{
  if(!stock.contains(item.getID()))
   stock.add(item);
}

这不起作用,因为stock是产品列表,因此不能包含ID(整数)。

public void addProduct(Product item)
{
  for(Product product : stock){
      if(product.getID() != item.getID())
          stock.add(item);
  }
}

这更接近解决方案,但这不起作用,因为如果你没有股票,那么你没有任何东西可以迭代,因此永远不会添加任何东西。此外,尝试修改您正在迭代的列表无论如何都会抛出异常。

我会像这样实现它,并设置一个布尔标志:

public void addProduct(Product item)
{
  boolean alreadyPresent = false;
  for(Product product : stock){
      if(product.getID() == item.getID()) {
          alreadyPresent = true;
          break; //an optimisation but not strictly necessary
      }
  }
  if (!alreadyPresent) stock.add(item);
}

对于第一个产品,alreadyPresent将保持为假,因此将添加该产品。对于每个后续项目,只有在for-each循环完成迭代后才会添加该项目,因此不会抛出任何异常。

答案 1 :(得分:0)

基本上你需要有一个满足SET数据结构条件的唯一集合。 Set包含明确定义的对象的唯一集合。在这里使用SET数据结构,最适合此处的要求。

您也可以保留一个列表,但是您必须迭代它以查看该值是否已存在。

Here is the basic tutorial of using sets in java

就您的查询而言。

for(Product product : stock){
     if(product.getID()!=item.getID())
    stock.add(item);
}

对于每次迭代,如果check为false,它将添加该项。您可以添加布尔检查以查看列表是否包含它。

boolean exists = false;
for(Product product : stock){
     if(product.getID() =item.getID())
      exists  = true;
}

if(!exists){
  stock.add(item); 
}

或者可能有一个ID列表并使用list.contains来查看该ID是否已存在。

答案 2 :(得分:0)

你的foreach陈述是错误的。试试:

public void addProduct(Product item)
{
  boolean exists;
  for(Product product : stock){
      if(product.getID()==item.getID()){
        exists = true;
        break;
      }      
   }
   if(!exists)
    stock.add(item);
}

答案 3 :(得分:0)

感谢大家的帮助,尤其是迈克尔,他的代码将我带到了我需要的地方。使用下面的代码现在可以按预期工作。我可以使用它将项目添加到列表中,但如果添加的项目具有与另一项目相同的ID,则会忽略它。同样,对getID和PrintDetails方法的调用会返回所有项目,并且不会返回未添加的重复项目。

我要做一些仔细的学习,所以我理解这段代码是如何工作的,并试着去了解我哪里出错了。

public void addProduct(Product item)
    {
        boolean alreadyPresent = false;
        for(Product product : stock){
            if(product.getID() == item.getID()){
                alreadyPresent = true;
                break;
            }
        }
        if(!alreadyPresent) 
        stock.add(item);                                
    }

答案 4 :(得分:0)

如果您只想允许唯一的产品,那么您需要覆盖Product类中的equals方法(它将通过它们的id比较项目),并通过包含arraylist的方法检查重复的产品..

代码:

//code in Product Class
@Override
public boolean equals(Object obj) {

    if (obj instanceof Product) {
        return this.getID() == ((Product) obj).getID();
    } else {
        return false;
    }
}

//code in StockManager Class
public void addProduct(Product item)
{
    if(!stock.contains(item)){
        stock.add(item);
    }

}

您也可以使用HashSet而不是ArrayList, 在这种情况下,您需要覆盖hashcode和equals方法。请参考以下代码

代码

//code in Product Class
@Override
public boolean equals(Object obj) {

    if (obj instanceof Product) {
        return this.getID() == ((Product) obj).getID();
    } else {
        return false;
    }
}
@Override
public int hashCode() {
    return this.getID();
}

//code in StockManager Class
public void addProduct(Product item)
{
    stock.add(item);

}

答案 5 :(得分:-2)

一种可能的解决方案是使用一组(误读问题)

覆盖equals(和hashcode查找)

使用哈希设置! Google:集合不包含元素e1和e2,例如e1.equals(e2),最多只有一个null元素。

    public class Product
{
    // An identifying number for this product.
    private int id;
    // The name of this product.
    private String name;
    // The quantity of this product in stock.
    private int quantity;

@Override
public boolean equals(Object e){
if(e == null) return false;
return ((Product)e).getId().equals(this.getId());
}

}