Home > Back-end >  (Java) How to Overwrite A 2D Array Where I've Already Declared Null Values
(Java) How to Overwrite A 2D Array Where I've Already Declared Null Values

Time:09-09

Hi I'm using a 2d array to simulate a vending machine.

I want to declare an array with a set length and make it oversize so it can accommodate me adding items to it.

Ex:

String[][] itemsT1 = new String[][] {null, null, null, null, null, null, null, null, null};
int itemCount = 0;

// The way I've been adding things in my "addItem' method is:

if ( (items.length > 0) && (itemsCount < items.length) ) {
            items[itemsCount][0] = nameOfItem;
            items[itemsCount][1] = expirationDate;
            itemsCount  ;
            System.out.println("Item added");
        }

// so that the end result of the array should be (with nameOfItem = "Water" and expDate = "15") something like this:

{ {"Water", "15"}, null, null, null, null, null, null, null, null}

// and it's scalable to be hypothetically used again:

{ {"Water", "15"}, {"Chocolate", "20"}, {"Juice", "25"}, null, null, null, null, null, null}

I might be back with more questions so thank you for answering, and let me know if I need to provide more!

CodePudding user response:

Declare your 2D String Array and initialize to the number of items you want to handle within your vending machine, let's say 10 Rows (items) with 3 data Columns in each row:

String[][] items = new String[10][3];

Open stream to accept Keyboard input using the Scanner class:

Scanner userInput = new Scanner(System.in);

Now create a for loop to iterate through each item row within the array so that each can be filled by the User. The following is in its' simplest form with no validation. If you just hit the Enter key when asked for an Item Name then the entry process will end:

for (int i = 0; i < items.length; i  ) {
    System.out.print("Enter a name for item #"   (i   1)   ": -> ");
    String itemName = userInput.nextLine().trim();
    if (itemName.isEmpty()) { 
        break; 
    }
    System.out.print("Enter expiry for item #"   (i   1)   ": -> ");
    String itemExpiry = userInput.nextLine().trim();
    System.out.print("Enter price for item  #"   (i   1)   ": -> ");
    String itemPrice = userInput.nextLine().trim();
    items[i][0] = itemName;
    items[i][1] = itemExpiry;
    items[i][2] = itemPrice;
    System.out.println();
}

Now, display all the entered items contained within the array into the Console Window:

for (String[] diffItems : items) {
    if (diffItems[0] != null) {
        System.out.println(Arrays.toString(diffItems));
    }
}

CodePudding user response:

If you prefer using 2D arrays, at first you'd need to find the first "empty" space in your vending machine -> a null element. (I'll keep it in a method so it's clear and easier to use)

public int getFreeSpaceIndex(final String[][] vendingMachine) {
    for (int index = 0; index < vendingMachine.length; index  )
        if (vendingMachine[index] == null)
            return index;
    // meaning there's no empty space, you should use some static field
    // to describe this situation to avoid magic numbers in your code
    return -1;
}

After you found the element you can insert whatever you want in there

// you've got the itemT1 array that you've created
// and let's say a user inputs the water item down below,
// I simplified it to declaration, cause it's off the topic
final String[] water = new String[] {"Water", "15"};
final int freeSpaceIndex = findFreeSpaceIndex(itemT1);
if (freeSpaceIndex == -1) {
    System.err.printf("There's not enough space for the %s item.", Arrays.toString(water));
} else {
    itemT1[freeSpaceIndex] = item;
}

Ultimately you can wrap the array into your own data structure and simply make an addItem(String[]) method that will search for an empty space and handle the overflow.

class VendingMachineStock {
    private String[][] stock = new String[][] {null, null, null, null, null, null, null, null, null};
    // constructors, api...

    public boolean hasFreeSpace() {
        return getFreeSpaceIndex() != -1;
    }

    public boolean addItem(final String[] item) {
        final int freeSpaceIndex = getFreeSpaceIndex();
        if (freeSpaceIndex == -1) {
            System.err.printf("There's not enough space for the %s item.", Arrays.toString(water));
            return false;
        }
        stock[freeSpaceIndex] = item;
        return true;
    }

    private int getFreeSpaceIndex() {
        for (int index = 0; index < stock.length; index  )
            if (stock[index] == null)
                return index;
        return -1;
    }
}

But there're many flaws in a code like this. Anyone can mess up and add String[] {"15", "Water"} or even new String[] {"15", "30", "I'm Foo Bar :)"}.

The right data structure for your problem would actually be a linked list with Item objects (as @DevilsHnd mentioned) and your own limiting structure over it.

class Item {
    private final String name;
    private int price;
    // default getters, setters, consturctor...
}

class VendingMachineStock {
    private final LinkedList<Item> stock;
    // this will limit your stock list size
    private int maxSlots; 

    // I omit API and constructor intentionally, it's off the
    // topic, but you must write it

    public void addItem(final Item item) {
        // you can either throw exceptions or return boolean
        // flag indicating the result, it's up to you.
        // in this case I prefer a detailed explanation on why
        // the method did not add the item.
        if (stock.size() >= maxSlots) {
            throw new IllegalStateException("Stock overflow, can't add more items");
        }
        stock.add(item);
    }
}
  • Related