3

Here's the code for the separate class Product which the ArrayList is based on. The chapter has us learning ArrayList, Loops, and Iterator so anything more advanced than that has not been covered and is not meant to be used to complete the exercise.

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);
    }

How the project is set up is I create a StockManager object and a few Product objects (Entering parameters for ProductID and ProductName) when the object is created. I then can call the default addProduct method to add those newly created Product objects to the ArrayList. What I am tasked with is modifying the addProduct method so that a new product won't be added to the list if a product with the same ID was already entered into the list.

At first, I thought I was maybe supposed to use the "for each" loop and do something like the following:

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

But this fails to add anything to the list. If I add a product object to the list with this method and then call a method to print/find the product it just returns null and shows nothing was entered.

I then thought maybe I'm supposed to do something like

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

But this doesn't work either. My Professor hinted that I should be using the null value, but I messed around with null and it never works, because getID is an integer, and even if I got it working I feel like I'm not setting the problem up right.

6 Answers6

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

This doesn't work because stock is a list of Products and so can't contain an ID (an integer).

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

This was closer to the solution but this doesn't work because if you have no stock then you have nothing to iterate over and thus will never add anything. Also, attempting to modify a list that you're iterating over will throw an exception anyway.

I would implement this like so, with a boolean flag that is set:

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);
}

For the first product, alreadyPresent will remain false and so the product will be added. For each subsequent item, the item will only be added after the for-each loop has finished iterating and so no exception will be thrown.

Michael
  • 41,989
  • 11
  • 82
  • 128
  • Thank you for your help! I ran into an error using the code you posted because it would not add any additional items to the list after the first was added. I changed it around slightly and it now works as intended. I appreciate the help and am going to study what you posted so I can figure out why I did it wrong and what I need to learn. –  Apr 10 '18 at 18:20
  • @ZacharyW Just needed to change != to ==. I've edited my answer. – Michael Apr 11 '18 at 08:59
0

basically you need to have a unique collection which satisfies the condition of SET data structure. Set contains the unique collection of well defined objects. Use SET data structure here, it best suits the requirement here.

You can keep a list as well but then you will have to iterate over it to see if the value already exists or not.

Here is the basic tutorial of using sets in java

As far as your query is concerned.

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

For every iteration if check is false, it will add the item. You may add a Boolean check to see if list contains it or not.

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

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

Or maybe have a list of ids and use list.contains to see if the id already exists or not.

Danyal Sandeelo
  • 12,196
  • 10
  • 47
  • 78
  • the point is for him to learn ArrayList, as he pointed out -> not an option, even though you're right about it – HBo Apr 10 '18 at 08:48
  • I would guess OP hasn’t covered Sets yet judging by the question, however it is probably the easiest approach. – achAmháin Apr 10 '18 at 08:49
0

Your foreach statement is wrong. try :

public void addProduct(Product item)
{
  boolean exists;
  for(Product product : stock){
      if(product.getID()==item.getID()){
        exists = true;
        break;
      }      
   }
   if(!exists)
    stock.add(item);
}
Dogukan Zengin
  • 545
  • 3
  • 11
0

Thank all of you for your help, especially Michael who's code led me to where I needed to be. Using the code below the method now works as intended. I can add items to the list using it, but if an item is added with the same ID as another it is disregarded. Similarly, calls to the getID and PrintDetails methods return all the items and correctly do not return duplicate items that were not added.

I'm going to do some careful studying so I understand how this code works and try to learn where I went wrong.

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);                                
    }
0

If you want to allow only unique products then you need to override equals method in Product class (which will compare items by their id) and just check duplicate product by contains method of arraylist..

Code:

//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);
    }

}

OR

you can also use HashSet instead of ArrayList, In that case you need to override hashcode and equals method. refer code as below

Code

//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);

}
Zealous System
  • 2,080
  • 11
  • 22
-2

A possible solution is to use a set (misread the question)

Override the equals (and hashcode look it up)

Use a HashSet! Google: sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element.

    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());
}

}
Mohamed Omar
  • 158
  • 1
  • 7