0

User can make a order of a certain quantity of bottles of the same wine. Class Shop holds a list of different wines that it has. How can I make an order method that, instead of remove the object by the wines list in Shop class, remove the "quantity"? I was thinking about creating a new class (Inventory for example) that has Wine and quantity and managing the decrement from there. Hope you can help me! Thanks

public class Shop {
    private ArrayList<Wine> wines;
    private ArrayList<User> users;
    private ArrayList<Employee> employees;
    private ArrayList<Order> orders;

    public Shop(ArrayList<Wine> wines, ArrayList<User> users, ArrayList<Employee> employees, ArrayList<Order> orders) {
        this.wines = wines;
        this.users = users;
        this.employees = employees;
        this.orders = orders;
    }
}

public class Wine {
    private String name;
    private String productor;
    private Integer year;
    private String notes;
    private String vine;

    public Wine(String name, String productor, Integer year, String notes, String vine) {
        this.name = name;
        this.productor = productor;
        this.year = year;
        this.notes = notes;
        this.vine = vine;
    }
}

public class Order {
    private User user;
    private Wine wine;
    private int quantity;

    public Order(User user, Wine wine, int quantity) {
        this.user = user;
        this.wine = wine;
        this.quantity = quantity;
    }
}

I tried to use Hashmap<Wine, Integer> instead of ArrayList<Wine> in Shop class and I've created this orderWine method.

public void orderWine(Shop s, Wine w, Integer q){

    if(this.login(s)){        //authenticated access
        HashMap<Wine, Integer> wines = new HashMap<>(s.getWines());
        ArrayList<Order> orders = new ArrayList<>(s.getOrders());
        orders.add(new Order(this, w, q));
        s.setOrders(orders);
        if(s.getWines().containsKey(w)){
            if(s.getWines().get(w) > q){
                int upQuant = wines.get(w) - q;
                wines.put(w,upQuant);
            }
        }
    }
}
Abra
  • 19,142
  • 7
  • 29
  • 41
Leos
  • 3
  • 2
  • Or you could simply decrement, perhaps by adding a method to the Order class. – Robert Harvey Nov 13 '20 at 16:20
  • I'm not confident in Map, but i thought that too. In case i should just put Map wine, quantity in shop class and do that from there.. could be a solution – Leos Nov 13 '20 at 16:27

1 Answers1

1

I think separating out the quantity of each wine is a good idea. You could either do that with an Inventory class, or simply use a map (Map<String, Integer>), that is one where the key is the name of the wine (which does have to be unique) and the value is the quantity.

You can add this as a member of your Shop class:

    public class Shop {
        private ArrayList<Wine> wines;
        private ArrayList<User> users;
        private ArrayList<Employee> employees;
        private ArrayList<Order> orders;
        private Map<String, Integer> inventory;

   public Shop(ArrayList<Wine> wines, ArrayList<User> users,    
       ArrayList<Employee> employees, ArrayList<Order> orders) {
            this.wines = wines;
            this.users = users;
            this.employees = employees;
            this.orders = orders;

            this.inventory = new HashMap<String, Integer>();
            for (Wine w : wines) {
                name = w.getName()  
                if (this.inventory.containsKey(name)){
                    // wine already there. Throw exception
                }
                this.inventory.put(name, 1);
                
   }

(You do need to add a getter getName() in the Wine class to access the name of the wine)

And then later when you receive an order, you could have a method in Shop to update the inventory as follows:

public void updateInventory(String name) {

        if (!this.inventory.containsKey(name)) {
            // The inventory does not contain the wine
            // specified. Handle this (eg by writing out
            // an error message to the user, and/or
            // raising an exception)
        }

        int quantity = this.inventory.get(name);

        if (quantity < 1) {
            // There is no more wine.
            // Handle this.
        }
            
        this.inventory.put(name, quantity--);
        
}
H3007
  • 46
  • 5
  • Your basic idea is good, however won’t work as is. `this.inventory.get(name)--` should be `inventory.put(name, inventory.get(name) - 1)`. An even better approach would be to use `AtomicInteger` as the value type, then you could `inventory.get(name).decrementAndGet()` – Bohemian Nov 13 '20 at 16:55
  • Good points. I've updated the method assuming a standard Integer type and auto-boxing. You are right about `AtomicInteger`, but perhaps more advanced than what the requester needs? – H3007 Nov 13 '20 at 17:26
  • Thanks for your comment. First of all i'm trying to use an Hashmap just to see if i can do it without creating a new parameter, let me see what you think about it – Leos Nov 13 '20 at 18:07
  • Yes, Using `Wine` as the key is even better, but you need to ensure that the `Wine.equals()` and `Wine.hashCode()` methods are correctly overridden. See eg https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java . So a little bit more complicated, which is why I didn't mention that in my original answer! – H3007 Nov 13 '20 at 18:36