2

I'm having a slight problem implementing pass-by-value in a project. In case of buyOption, fillOption and takeOption.

I don't know how to make changed value apply to whole program and not only to methods. Any tips/solution/feedback would be highly appreciated.

public class CoffeeMachine {

    static int water = 400;
    static int milk = 540;
    static int beans = 120;
    static int cups = 9;
    static int money = 550;
    static boolean exit = false;

    public static void main(String[] args) {
        do {
            printMenu(water, milk, beans, cups, money);
        } while (!exit);
    }

    private static void printMenu(int water, int milk, int beans, int cups, int money) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Write action (buy, fill, take, remaining, exit): ");
        String input = scanner.nextLine();

        switch (input) {
            case "buy":
                buyOption(water, milk, beans, cups, money);
                break;

            case "fill":
                fillOption(water, milk, beans, cups, money);
                break;

            case "take":
                takeOption(water, milk, beans, cups, money);
                break;

            case "remaining":
                contentOption(water, milk, beans, cups, money);
                break;

            case "exit":
                exit = true;
                System.exit(0);
                break;

            default:
                System.out.println("Wrong option!");
                break;
        }
    }

    private static void contentOption(int water, int milk, int beans, int cups, int money) {
        System.out.println("The coffee machine has: ");
        System.out.println(water + " of water");
        System.out.println(milk + " of milk");
        System.out.println(beans + " of coffee beans");
        System.out.println(cups + " of disposable cups");
        System.out.println(money + " of money");
    }

    private static void buyOption(int water, int milk, int beans, int cups, int money) {
        Scanner scanner = new Scanner(System.in);

        String temp = null;

        System.out.println("What do you want to buy? 1 - espresso, 2 - latte, 3 - cappuccino: ");

        String input = scanner.nextLine();

        switch (input) {
            case "1":
                if (water >= 250 && beans >= 16 && cups >= 1) {
                    water -= 250;
                    beans -= 16;
                    cups -= 1;
                    money += 4;
                    System.out.println("I have enough resources, making you a coffee!");
                } else {
                    if (water < 250) {
                        temp = "water";
                    } else if (beans < 16) {
                        temp = "beans";
                    } else if (cups < 1) {
                        temp = "cups";
                    }
                    System.out.println("Sorry, not enough " + temp + "!");
                }
                break;

            case "2":
                if (water >= 350 && milk >= 75 && beans >= 20 && cups >= 1) {
                    water -= 350;
                    milk -= 75;
                    beans -= 20;
                    cups -= 1;
                    money += 7;
                    System.out.println("I have enough resources, making you a coffee!");
                } else {
                    if (water < 350) {
                        temp = "water";
                    } else if (milk < 75) {
                        temp = "milk";
                    } else if (beans < 20) {
                        temp = "beans";
                    } else if (cups < 1) {
                        temp = "cups";
                    }
                    System.out.println("Sorry, not enough " + temp + "!");
                }
                break;

            case "3":
                if (water >= 200 && milk >= 100 && beans >= 12 && cups >= 1) {
                    water -= 200;
                    milk -= 100;
                    beans -= 12;
                    cups -= 1;
                    money += 6;
                    System.out.println("I have enough resources, making you a coffee!");
                } else {
                    if (water < 200) {
                        temp = "water";
                    } else if (milk < 100) {
                        temp = "milk";
                    } else if (beans < 12) {
                        temp = "beans";
                    } else if (cups < 1) {
                        temp = "cups";
                    }
                    System.out.println("Sorry, not enough " + temp + "!");
                }
                break;

            case "back":
                break;

            default:
                System.out.println("Wrong option!");
        }
    }

    private static void fillOption(int water, int milk, int beans, int cups, int money) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Write how many ml of water do you want to add: ");
        water = water + scanner.nextInt();
        System.out.println("Write how many ml of milk do you want to add: ");
        milk = milk + scanner.nextInt();
        System.out.println("Write how many grams of coffee beans do you want to add: ");
        beans = beans + scanner.nextInt();
        System.out.println("Write how many disposable cups of coffee do you want to add: ");
        cups = cups + scanner.nextInt();
    }

    private static void takeOption(int water, int milk, int beans, int cups, int money) {
        System.out.println("I gave you " + money);
        money = 0;
    }
}
amasterm
  • 21
  • 3
  • Does this answer your question? [Is Java "pass-by-reference" or "pass-by-value"?](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – Abra Oct 02 '20 at 12:58

2 Answers2

3

Java is always pass-by-value. The problem here is that you are working with local variables (the parameters declared in every method) which are hiding your static members. You can simply omit all the parameters in method declaration: this way you will "use" the static members you declared at the beginning.

EDIT

private static void takeOption(int water, int milk, int beans, int cups, int money) {
   //sample code
   milk = milk+1;
}

In this scenario, every operation you make using, let's say, "milk" will only exist inside this method. Your parameter is named milk, but it has nothing to share with "milk" declared on top of your class. It is just a coincidence that they are named the same. You cann refer to your static milk using this.milk (or CoffeeMachine.milk, since it is a static field), but as your code is written at the moment, I can see no use without editing your methods furthermore.

private static void takeOption() {
   //code here
}

Editing your method signature like this will make you use your static variables.

Siberio
  • 105
  • 9
  • 2
    As a side note those fields likely shouldn't be `static` : you're representing the stock of your own CoffeeMachine, not a magical stock shared by every CoffeeMachine in the wold. (That said that would require instanciating your CoffeeMachine at some point which you currently do not do, and as long as you're only manipulating a single CoffeeMachine using static fields and methods might make it simpler for a beginner) – Aaron Oct 02 '20 at 13:00
  • 1
    There are many things that could be improved, but I guess OP is just starting in Java. One step at a time :) – Siberio Oct 02 '20 at 13:03
1

In order to affect the static variables you have set for your CoffeeMachine.

You have to reference the static variable directly inside your method:

So instead of just using

water -= 250;

Which affects only the parameter (local scope)

You will have to use:

CoffeeMachine.water -= 250;

As it has been pointed out, the fields shouldn't be static, but I'm assuming you are learning java at this moment.

NOTE: For your purposes probably you don't need parameters in your method as you are affecting the initial static variables, but in case you actually needed parameters:

You could change the names of your parameters:

private static void buyOption(int water, int milk, int beans, int cups, int money)

Could have easily just become:

private static void buyOption(int localWater, int localMilk, int localBeans, int localCups, int localMoney)

With the new names you could just use the variable water to represent your static variable while using localWater to represent your parameter

Then this would work:

if (localWater >= 250 && localBeans >= 16 && localCups >= 1) {
                water -= 250;
                beans -= 16;
                cups -= 1;
                money += 4;
                System.out.println("I have enough resources, making you a coffee!");
            }
gtgaxiola
  • 9,241
  • 5
  • 42
  • 64