Program is not saving to the next space available - java

The problem I have encountered is as follows: I have created two arrays representing docking spaces for ships. The first array the ship object (shipName and size - usually Super-Container) can be saved in the array and if there is no space then it will be added to a waiting list array.
I can only add one ship to the waiting list and it says it is full.
Can you help? Here's my dock class, problem in waitingList():
import java.util.*;
public class Main {
static Scanner scan = new Scanner(System.in);
private static Ship[] dock1 = new Ship[10];
private static Ship[] waitingList = new Ship[10];
public static void main(String[] args) {
menu();
}
public static void menu() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("Choose an option: 1-3");
System.out.println("1. Dock");
System.out.println("2. Undock");
System.out.println("3. Status");
int menu = scan.nextInt();
switch (menu) {
case 1:
System.out.println("1. Dock");
dock();
break;
case 2:
System.out.println("2. Undock");
undock();
break;
case 3:
System.out.println("3. Status");
printDock();
printWaitingList();
break;
case 4:
System.out.println("4. Exit");
System.exit(0);
default:
System.out.println("No such option");
break;
}
}
}
public static void dock() {
System.out.println("Enter ship's name: ");
String name = scan.nextLine();
System.out.println("Enter ship's size: ");
String size = scan.nextLine();
System.out.println("Enter the ships dock:");
//Check if the dock number is valid
int i = Integer.valueOf(scan.nextLine());
if (i >= 0 && i < 10 && dock1[i] == null) {
int c = 0;
int co = 0;
int sco = 0;
for (int j = 0; j < dock1.length; j++) {
if (dock1[j] != null && dock1[j].getShipSize().equals("Cargo")) {
c++;
}
if (dock1[j] != null && dock1[j].getShipSize().equals("Container")) {
co++;
}
if (dock1[j] != null && dock1[j].getShipSize().equals("Super-Container")) {
sco++;
}
}
if (c < 10 && co < 5 && sco < 2) {
//Add ship to the dock
dock1[i] = new Ship(name, size);
System.out.println("Enough space you can dock");
System.out.println("Ship has been docked");
} else {
System.out.println("You cannot dock");
waitingList(name,size);
}
} else {
System.out.println("Couldn't dock");
waitingList(name, size);
}
}
public static void undock() {
System.out.println("Status of ships: ");
printDock();
System.out.println("Enter ship's name to undock: ");
String name = scan.nextLine();
//System.out.println("Enter ship's size to undock: ");
// String size = scan.nextLine();
for (int i = 0; i < dock1.length; i++) {
if (dock1[i] != null && dock1[i].getShipName().equals(name)) {
dock1[i] = null;
System.out.println("Ship removed");
/// HERE CHECK IF SHIP IN DOCK
for (int j = 0; j < waitingList.length; j++) {
if (dock1[i] == null) {
// Add ship to the dock
dock1[i] = new Ship(waitingList[j].getShipName(), waitingList[j].getShipSize());
System.out.println("Move ship from waiting list to dock 1");
waitingList[j] = null;
break;
} else {
System.out.println("No space in dock1");
return;
}
}
} else {
System.out.println("Ship not docked here");
break;
}
}
}
public static void waitingList(String name, String size){
System.out.println("Dock 1 is full, ship will try to be added to Waiting List");
for (int i = 0; i < waitingList.length; i++) {
if (waitingList[i] == null) { //CHANGE TO ALLOW MORE THAN ONE SHIP
//Add ship to the dock
waitingList[i] = new Ship(name, size);
System.out.println("Enough space added to waiting list");
break;
} else {
System.out.println("No space on waiting list, ship turned away");
return;
}
}
}
public static void printDock() {
System.out.println("Docks:");
for (int i = 0; i < dock1.length; i++) {
if (dock1[i] == null) {
System.out.println("Dock " + i + " is empty");
} else {
System.out.println("Dock " + i + ": " + dock1[i].getShipName() + " " + dock1[i].getShipSize());
}
}
}
private static void printWaitingList() {
System.out.println("Waiting List:");
for (int i = 0; i < waitingList.length; i++) {
if (waitingList[i] == null) {
System.out.println("Dock " + i + " is empty");
} else {
System.out.println("Dock " + i + ": " + waitingList[i].getShipName() + " " + waitingList[i].getShipSize());
}
}
}
}

Try this:
public static void waitingList(String name, String size){
System.out.println("Dock 1 is full, ship will try to be added to Waiting List");
for (int i = 0; i < waitingList.length; i++) {
if (waitingList[i] == null) {
//Add ship to the dock
waitingList[i] = new Ship(name, size);
System.out.println("Enough space. Added to waiting list.");
return;
} else {
System.out.println("No space on waiting list at number "+ i +", checking next space."); //Optional
}
}
// Only when no spaces available
System.out.println("No space on waiting list, ship turned away.");
}
if you add a ship to the waitingList array, it will not be null never again, so that check (if waitingList[0] == null) will result into executing the else part, where it is a return, so the loop will not continue and will never try to check if waitingList[1] == null.
So, the solution is to exit the method when the ship is added to the list, not when we see the first used space. So changeing the return will help.

Related

Two problems. Not adding to next index in array and not removing from array

The problem I have encountered is as follows: I have created two array representing docking spaces for ships. The first array the ship object (shipName and size - usually Super-Container) be saved in the array and if there is no space then it will be added to a waiting list array. If the space in the first array becomes vacant then the ship from the waiting list will join the first array.
But when I go to undock (remove a ship from the first array) it only finds the ship in index 0 of the first array and not index 1, 2 etc.
Also, I can only add one ship to the waiting list and it says it is full.
Can you help? Here's my dock class, problem in undock() and waitingList():
import java.util.*;
public class Main {
static Scanner scan = new Scanner(System.in);
private static Ship[] dock1 = new Ship[10];
private static Ship[] waitingList = new Ship[10];
public static void main(String[] args) {
menu();
}
public static void menu() {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.println("Choose an option: 1-3");
System.out.println("1. Dock");
System.out.println("2. Undock");
System.out.println("3. Status");
int menu = scan.nextInt();
switch (menu) {
case 1:
System.out.println("1. Dock");
dock();
break;
case 2:
System.out.println("2. Undock");
undock();
break;
case 3:
System.out.println("3. Status");
printDock();
printWaitingList();
break;
case 4:
System.out.println("4. Exit");
System.exit(0);
default:
System.out.println("No such option");
break;
}
}
}
public static void dock() {
System.out.println("Enter ship's name: ");
String name = scan.nextLine();
System.out.println("Enter ship's size: ");
String size = scan.nextLine();
System.out.println("Enter the ships dock:");
//Check if the dock number is valid
int i = Integer.valueOf(scan.nextLine());
if (i >= 0 && i < 10 && dock1[i] == null) {
int c = 0;
int co = 0;
int sco = 0;
for (int j = 0; j < dock1.length; j++) {
if (dock1[j] != null && dock1[j].getShipSize().equals("Cargo")) {
c++;
}
if (dock1[j] != null && dock1[j].getShipSize().equals("Container")) {
co++;
}
if (dock1[j] != null && dock1[j].getShipSize().equals("Super-Container")) {
sco++;
}
}
if (c < 10 && co < 5 && sco < 2) {
//Add ship to the dock
dock1[i] = new Ship(name, size);
System.out.println("Enough space you can dock");
System.out.println("Ship has been docked");
} else {
System.out.println("You cannot dock");
waitingList(name,size);
}
} else {
System.out.println("Couldn't dock");
waitingList(name, size);
}
}
public static void undock() {
System.out.println("Status of ships: ");
printDock();
System.out.println("Enter ship's name to undock: ");
String name = scan.nextLine();
//System.out.println("Enter ship's size to undock: ");
// String size = scan.nextLine();
for (int i = 0; i < dock1.length; i++) {
if (dock1[i] != null && dock1[i].getShipName().equals(name)) {
dock1[i] = null;
System.out.println("Ship removed");
/// HERE CHECK IF SHIP IN DOCK
for (int j = 0; j < waitingList.length; j++) {
if (dock1[i] == null) {
// Add ship to the dock
dock1[i] = new Ship(waitingList[j].getShipName(), waitingList[j].getShipSize());
System.out.println("Move ship from waiting list to dock 1");
waitingList[j] = null;
break;
} else {
System.out.println("No space in dock1");
return;
}
}
} else {
System.out.println("Ship not docked here");
break;
}
}
}
public static void waitingList(String name, String size){
System.out.println("Dock 1 is full, ship will try to be added to Waiting List");
for (int i = 0; i < waitingList.length; i++) {
if (waitingList[i] == null) { //CHANGE TO ALLOW MORE THAN ONE SHIP
//Add ship to the dock
waitingList[i] = new Ship(name, size);
System.out.println("Enough space added to waiting list");
break;
} else {
System.out.println("No space on waiting list, ship turned away");
return;
}
}
}
public static void printDock() {
System.out.println("Docks:");
for (int i = 0; i < dock1.length; i++) {
if (dock1[i] == null) {
System.out.println("Dock " + i + " is empty");
} else {
System.out.println("Dock " + i + ": " + dock1[i].getShipName() + " " + dock1[i].getShipSize());
}
}
}
private static void printWaitingList() {
System.out.println("Waiting List:");
for (int i = 0; i < waitingList.length; i++) {
if (waitingList[i] == null) {
System.out.println("Dock " + i + " is empty");
} else {
System.out.println("Dock " + i + ": " + waitingList[i].getShipName() + " " + waitingList[i].getShipSize());
}
}
}
}
Your loops are only working with first element of the array, becouse when check failed (for example if (waitingList[i] == null) in waitingList) you print error, and then return, thus breaking loop. What you need to do is make boolean dockSuccessful = false, then if condition is met (there is space in dock) you set it to true and then break the loop (so you woudn't dock ship multiple times). After the loop you insert
if(!dockSuccessful) {
System.out.println("Some error message here");
}
So, if loop finds at least one empty dock, dockSuccessful would be true, and error would not be printed. But if it checked all the docks, it will not update dockSuccessful, it would still be false, and error will be printed.

No more than a number of the same string name in the same array?

The problem I have encountered is as follows: I have created 10 row outputs representing docking spaces for ships.
But the dock can accommodate two sizes of ship; cargo and container. The rows are made up of 5 small and 5 medium. A cargo ship (small) can berth in any available space. A container ship (medium) can berth in the medium space, but not in small spaces.
So if I enter shipName and Container for example it searches the array making sure there is less than 5 Container's so it can dock i.e. save in the array. Can you help?
Here's my dock method:
import java.util.*;
public class Main {
static Scanner scan = new Scanner(System.in);
private static Ship[] dock1 = new Ship[10];
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(true) {
System.out.println("Choose an option: 1-3");
System.out.println("1. Dock");
System.out.println("2. Undock");
System.out.println("3. Status");
int menu = scan.nextInt();
switch (menu) {
case 1:
System.out.println("1. Dock");
dock();
break;
case 2:
System.out.println("2. Undock");
undock();
break;
case 3:
System.out.println("3. Status");
printArray();
break;
case 4:
System.out.println("4. Exit");
System.exit(0);
default:
System.out.println("No such option");
break;
}
}
}
public static void dock() {
int dockCapacity = 0;
System.out.println("Enter ship's name: ");
String name = scan.nextLine();
System.out.println("Enter ship's size: ");
String size = scan.nextLine();
System.out.println("Enter the ships dock:");
//search for 5 small 3 med 2 large
// if what they entered equals shipSize more than 5 than cannot dock.
for(int i = 1; i < dock1.length; i++) {
if (dock1[i].getShipSize().equals(size)) {
System.out.print(dock1[i].getShipSize());
}
else {
System.out.println("Couldn't dock");
}
}
//Check if the dock number is valid
int i = Integer.valueOf(scan.nextLine());
if (i >= 0 && i < 10 && dock1[i] == null){
//Add ship to the dock
dock1[i] = new Ship(name, size);
System.out.println("Ship has been docked");
}
else{
System.out.println("Couldn't dock");
}
// printArray();
}
public static void undock(){
System.out.println("Status of ships: ");
printArray();
System.out.println("Enter ship's name to undock: ");
String name = scan.nextLine();
for(int i = 1; i < dock1.length; i++){
if(dock1[i] != null && dock1[i].getShipName().equals(name)){
dock1[i] = null;
System.out.println("Ship removed");
break;
}
else{
System.out.println("Ship not docked here");
}
}
}
public static void printArray() {
System.out.println("Docks:");
for(int i = 0; i < dock1.length; i++)
{
if(dock1[i] == null)
{
System.out.println("Dock " + i + " is empty");
}
else
{
System.out.println("Dock " + i + ": " + dock1[i].getShipName() + " " + dock1[i].getShipSize());
}
}
}
}
Ship class
public class Ship {
private String shipName;
private String shipSize;
public String getShipName() {
return shipName;
}
public void setShipName(String shipName) {
this.shipName = shipName;
}
public String getShipSize() {
return shipSize;
}
public void setShipSize(String shipSize) {
this.shipSize = shipSize;
}
public Ship(String shipName, String shipSize) {
this.shipName = shipName;
this.shipSize = shipSize;
}
}
I would recommend you to change the Ship class like this. It adds a ShipSize enum and makes it much easier to parse the ship size from string and compare ship sizes. Also, I added a isCargo and isContainer method.
import java.util.Arrays;
public class Ship {
private String shipName;
private ShipSize shipSize;
public Ship(String shipName, ShipSize shipSize) {
this.shipName = shipName;
this.shipSize = shipSize;
}
public String getShipName() {
return shipName;
}
public void setShipName(String shipName) {
this.shipName = shipName;
}
public ShipSize getShipSize() {
return shipSize;
}
public void setShipSize(ShipSize shipSize) {
this.shipSize = shipSize;
}
public boolean isCargo() {
return shipSize == ShipSize.CARGO;
}
public boolean isContainer() {
return shipSize == ShipSize.CONTAINER;
}
public enum ShipSize {
CARGO,
CONTAINER;
public static ShipSize of(String size) {
return Arrays.stream(ShipSize.values()).filter(enumSize -> enumSize.name().equalsIgnoreCase(size)).findAny().orElse(null);
}
}
}
I also modified your main class so it does what you want. I added some parsing and checks for the numbers, added an initialize method for the docks.
import java.util.*;
public class Main {
static Scanner scan = new Scanner(System.in);
private static Dock[] dock1 = new Dock[10];
public static void main(String[] args) {
initializeDock();
Scanner scan = new Scanner(System.in);
while(true) {
System.out.println("Choose an option: 1-3");
System.out.println("1. Dock");
System.out.println("2. Undock");
System.out.println("3. Status");
int menu = scan.nextInt();
switch (menu) {
case 1:
System.out.println("1. Dock");
dock();
break;
case 2:
System.out.println("2. Undock");
undock();
break;
case 3:
System.out.println("3. Status");
printArray();
break;
case 4:
System.out.println("4. Exit");
System.exit(0);
default:
System.out.println("No such option");
break;
}
}
}
private static void initializeDock() {
for (int i = 0; i < 5; i++) {
dock1[i] = new Dock(Ship.ShipSize.CARGO);
}
for (int i = 5; i < 10; i++) {
dock1[i] = new Dock(Ship.ShipSize.CONTAINER);
}
}
public static void dock() {
int dockCapacity = 0;
System.out.println("Enter ship's name: ");
String name = scan.nextLine();
Ship.ShipSize size = null;
while(size == null) {
System.out.println("Enter ship's size: ");
String stringSize = scan.nextLine();
size = Ship.ShipSize.of(stringSize);
if (size == null) {
System.out.println("Could not read ship size. Only cargo and container are allowed.");
}
}
// check that ship fits into any dock
if (size == Ship.ShipSize.CONTAINER) {
long numberOfContainerShips = Arrays.stream(dock1).map(Dock::getDockedShip).filter(Objects::nonNull).filter(Ship::isContainer).count();
if (numberOfContainerShips >= 5) {
System.out.println("No place for a ship that large. Aborting.");
return;
}
}
System.out.println("Enter the ships dock:");
Integer dockNumber = null;
while(dockNumber == null) {
dockNumber = scan.nextInt();
if (dockNumber < 0 || dockNumber > dock1.length - 1) {
System.out.println("Illegal dock number. Only numbers between 0 and " + dock1.length + " are allowed.");
dockNumber = null;
}
}
Dock dock = dock1[dockNumber];
if (dock.getDockedShip() != null) {
System.out.println("Dock reserved - couldn't dock");
return;
}
if (dock.getSupportedSize() == Ship.ShipSize.CARGO && size == Ship.ShipSize.CONTAINER) {
System.out.println("Dock too small - couldn't dock");
return;
}
dock.setDockedShip(new Ship(name, size));
}
public static void undock(){
System.out.println("Status of ships: ");
printArray();
System.out.println("Enter ship's name to undock: ");
String name = scan.nextLine();
for(int i = 1; i < dock1.length; i++){
if(dock1[i].getDockedShip() != null && dock1[i].getDockedShip().getShipName().equals(name)){
dock1[i] = null;
System.out.println("Ship removed");
break;
}
else{
System.out.println("Ship not docked here");
}
}
}
public static void printArray() {
System.out.println("Docks:");
for(int i = 0; i < dock1.length; i++)
{
if(dock1[i].getDockedShip() == null)
{
System.out.println("Dock " + i + " is empty. Size: " + dock1[i].getSupportedSize().name().toLowerCase());
}
else
{
System.out.println("Dock " + i + ": " + dock1[i].getDockedShip().getShipName() + " " + dock1[i].getDockedShip().getShipSize().name().toLowerCase());
}
}
}
}
I also added a Dock class. It works fine.
public class Dock {
private Ship.ShipSize supportedSize;
private Ship dockedShip = null;
public Dock(Ship.ShipSize supportedSize) {
this.supportedSize = supportedSize;
}
public Ship.ShipSize getSupportedSize() {
return supportedSize;
}
public void setSupportedSize(Ship.ShipSize supportedSize) {
this.supportedSize = supportedSize;
}
public Ship getDockedShip() {
return dockedShip;
}
public void setDockedShip(Ship dockedShip) {
this.dockedShip = dockedShip;
}
}

Java Constructor & Arrays

I am learning java. This is for a class that I take online. My assignment is finished.
I am trying to figure out the cause for the following.
The two main issues I have are:
1)It seems to be storing only one flower and ignoring the other inputs. How can I correct this?
2) Display flower (e.g Roses - 2):
Immediately after it displays the flowers and their count it will give me the following error message.
Flower Pack:
Daffodils - 1
Roses - 1
Exception in thread "main" java.lang.NullPointerException
at Assignment2.displayFlowers(Assignment2.java:203)
at Assignment2.<init>(Assignment2.java:44)
at Assignment2.main(Assignment2.java:9)
I believe it's origination from this statement
flowerName = searchingPack[i].getName();
Here is my code:
public class Flower {
private String name;
private String color;
private String thorns;
private String smell;
public Flower(){
}
public Flower(String flowerName, String flowerColor, String flowerThorns, String flowerSmell){
name = flowerName;
color = flowerColor;
thorns = flowerThorns;
smell = flowerSmell;
}
public String getName(){
return name;
}
public void setName(String flowerName){
name = flowerName;
}
public String getColor(){
return color;
}
public void setColor(String flowerColor){
color = flowerColor;
}
public String getThorns(){
return thorns;
}
public void setThorns(String flowerThorns){
thorns = flowerThorns;
}
public String getSmell(){
return smell;
}
public void setSmell(String flowerSmell){
smell = flowerSmell;
}
}
import java.util.Scanner;
public class Assignment2 {
public static void main(String[] args){
new Assignment2 ();
}
// This will act as our program switchboard
public Assignment2 (){
Scanner input = new Scanner(System.in);
Flower[] flowerPack = new Flower[25];
System.out.println("Welcome to my flower pack interface.");
System.out.println("Please select a number from the options below");
System.out.println("");
while(true){
// Give the user a list of their options
System.out.println("1: Add an item to the pack.");
System.out.println("2: Remove an item from the pack.");
System.out.println("3: Search for a flower.");
System.out.println("4: Display the flowers in the pack.");
System.out.println("0: Exit the flower pack interfact.");
// Get the user input
int userChoice = input.nextInt();
switch(userChoice){
case 1:
addFlower(flowerPack);
break;
case 2:
removeFlower(flowerPack);
break;
case 3:
searchFlowers(flowerPack);
break;
case 4:
displayFlowers(flowerPack);
break;
case 0:
System.out.println("Thank you for using the flower pack interface. See you again soon!");
System.exit(0);
}
}
}
//ADD FLOWERS
private void addFlower(Flower[] flowerPack) { //This is storing 1 flower but not anything else*********
Scanner add = new Scanner(System.in);
String name,color, thorns, smell;
System.out.println("\nEnter the name of the flower to add: ");
name = add.nextLine();
System.out.println("\nEnter the color of the flower: ");
color = add.nextLine();
System.out.println("\nAre there thorns present: YES or NO ");
thorns = add.nextLine();
System.out.println("\nDoes the flower smell: YES or NO ");
smell = add.nextLine();
boolean flowerInserted = false;
for(int i = 0; i < flowerPack.length; i++){
if(flowerPack[i] == null){
Flower newFlower = new Flower(name, color, thorns, smell);
flowerPack[i] = newFlower;
flowerInserted = true;
break;
}
}
if(flowerInserted){
System.out.println("Flower inserted.");
System.out.println();
}else{
System.out.println("\nFlower pack is full and could not add another flower.\n");
}
}
//REMOVE FLOWERS
private void removeFlower(Flower[] flowerPack) {
Scanner remove = new Scanner(System.in);
String removeName, removeColor;
for(int i = 0; i < flowerPack.length; i++){
System.out.println("\nEnter the name of the flower to remove: ");
removeName = remove.nextLine();
System.out.println("\nEnter the color of the flower: ");
removeColor = remove.nextLine();
if (flowerPack[i] != null)
if (flowerPack[i].getName().equalsIgnoreCase(removeName) && flowerPack[i].getColor().equalsIgnoreCase(removeColor)){
for(int j = i; j < flowerPack.length - 1; j++) {
flowerPack[j] = flowerPack[j + 1];
}
flowerPack[flowerPack.length - 1] = null;
System.out.println("\nFlower removed.\n");
break;
}
else{
System.out.println("\nThat flower was not found.\n");
}
}
}
//SEARCH FOR FLOWERS
private void searchFlowers(Flower[] flowerPack) {
Scanner flowerSearch = new Scanner(System.in);
String name, color, thorns, smell;
int options;
System.out.println("1: Seach by name.");
System.out.println("2: Seach by color.");
System.out.println("3: Seach for flowers with thorns.");
System.out.println("4: Seach for flowers that smell.");
options = flowerSearch.nextInt();
flowerSearch.nextLine();
boolean found = false;
for(int i = 0; i < flowerPack.length; i++){
if(options == 1){
System.out.println("\nEnter the name of the flower: ");
name = flowerSearch.nextLine();
if (flowerPack[i] != null) {
if (flowerPack[i].getName().equalsIgnoreCase(name)) {
found = true;
System.out.println("\nFlower was found at index " + i + ".");
break;
}
}
}
if(options == 2){
System.out.println("\nEnter the color of the flower: ");
color = flowerSearch.nextLine();
if (flowerPack[i] != null) {
if (flowerPack[i].getColor().equalsIgnoreCase(color)) {
found = true;
System.out.println("\nFlower was found at index " + i + ".");
break;
}
}
}
if(options == 3){
System.out.println("\nFlowers with thorns or no thorns: YES or NO ");
thorns = flowerSearch.nextLine();
if (flowerPack[i] != null) {
if (flowerPack[i].getThorns().equalsIgnoreCase(thorns)) {
found = true;
System.out.println("\nFlower was found at index " + i + ".");
break;
}
}
}
if(options ==4){
System.out.println("\nFlower with aroma or no aroma: YES or NO ");
smell = flowerSearch.nextLine();
if (flowerPack[i] != null) {
if (flowerPack[i].getSmell().equalsIgnoreCase(smell)) {
found = true;
System.out.println("\nFlower was found at index " + i + ".");
break;
}
}
}
if(!found){
System.out.println("\nSorry, no match found.");
}
}
}
//DISPLAY FLOWERS
private void displayFlowers(Flower[] flowerPack) {
System.out.println("Flower Pack: \n");
Flower[] searchingPack = new Flower[flowerPack.length];
for (int i = 0; i < searchingPack.length; i++) {
searchingPack[i] = flowerPack[i];
}
String flowerName = null;
int count = 0;
for(int i = 0; i < searchingPack.length; i++) {
i = 0;
flowerName = searchingPack[i].getName(); // this line is giving me an error!***********************************
if (searchingPack[i].getName() == null || searchingPack[i].getName().equals(null)) {
break;
}
for (int j = 0; j < flowerPack.length; j++) {
if (flowerPack[j] != null) {
if (flowerPack[j].getName().equalsIgnoreCase(flowerName)) {
count++;
}
}
}
for (int k = 0; k < count; k++) {
silentRemove(searchingPack, flowerName);
}
System.out.println(flowerName + " - " + count);
System.out.println();
count = 0;
}
}
private void silentRemove(Flower flowerPack[], String flowerName) {
for (int i = 0; i < flowerPack.length; i++) {
if (flowerPack[i] != null) {
if (flowerPack[i].getName().equalsIgnoreCase(flowerName)) {
for (int j = i; j < flowerPack.length - 1; j++) {
flowerPack[j] = flowerPack[j + 1];
}
flowerPack[flowerPack.length - 1] = null;
break;
}
}
}
}
}
Does it need to be an array? A List<Flower> is more appropriate here. What is happening is you're only adding 2 flowers, but looping over all 25 elements in the array, some of which are still null
The problem is with
flowerName = searchingPack[i].getName();
because searchingPack[i] might be null and then you're trying to reach an address that doesn't exists.
do something like this:
if(searchingPack[i]==null)
flowerName="";
else
flowerName = searchingPack[i].getName();
If you are planning on doing the same kinds of actions you might consider putting an "empty" flower at each index in the array so it won't throw an error.

Getting incorrect value reading from arrray

The problem is when I create three accounts for example 1, 2 and 3. Then delete 2 and add a new one the result is 1, 3 and 2, everything ok. When I add another account the results is 1, 3, 2, 3. Adding yet another one gets me 1, 3, 2, 3, 4.
The values are stored in a text file from where the array reads and writes them to.
The problem is I get the same account number twice. Also just making it always increment by one isn't ok, because I need it to fill the gaps from the deleted accounts.
Can't figure out the problem and would really appreciate some help!
The code responsible:
private int choice;
public String name;
public int accountNr = 1;
public int cash;
public int funds;
private boolean run = true;
private int index = 0;
private int index1 = 0;
Scanner scan = new Scanner(System.in);
Random rand = new Random();
ArrayList<Account> acc = new ArrayList<Account>();
ArrayList<TransferHistory> transferHistory = new ArrayList<TransferHistory>();
public int c;
public int amount;
private int c1;
private int size;
ReaderWriter io = new ReaderWriter();
private int account0;
private Account ac;
private int account1;
private int account3;
private int account2;
private int viewAnswer;
private int deleteAnswer;
private String s = "";
public void startMessage() {
System.out.println("***** Welcome to our bank system *****");
}
public void mainMenu() {
while (run == true) {
acc = io.readFromFile();
Scanner scan = new Scanner(System.in);
System.out.println("**** Main menu ****");
System.out.println("1. Create a new account");
System.out.println("2. Deposit/Withdraw from account");
System.out.println("3. Transfer money");
System.out.println("4. View the account properties");
System.out.println("5. View one account properties");
System.out.println("6. Delete account");
System.out.println("7. Show transfer history");
System.out.println("8. Show transfer history for one account");
System.out.println("9. Quit");
try {
choice = scan.nextInt();
} catch (InputMismatchException e) {
System.out.println("Please enter valid choice");
}
if (choice == 1) {
addAccount();
}
if (choice == 2) {
transfer();
}
if (choice == 3) {
transferWithin();
}
if (choice == 4) {
view();
}
if (choice == 5) {
viewOne();
}
if (choice == 6) {
delete();
}
if (choice == 7) {
showTransfers();
}
if (choice == 8) {
showOneTransfer();
}
if (choice == 9) {
quit();
}
}
}
public void addAccount() {
System.out.print("Enter your name: ");
name = scan.next();
for (int i = 0; i < acc.size(); i++) {
if(acc.get(i).getAcc() == accountNr) {
accountNr++;
}
}
System.out.println("Your account nr is: " + accountNr);
System.out.print("Enter your starting funds: ");
try {
cash = scan.nextInt();
if(cash < 0){
System.out.println("Incorrect input!");
System.out.println(s);
scan.reset();
return;
}
index = acc.size();
acc.add(index, new Account(name, accountNr, cash)); //Add new account object to specified element in acc arraylist
index = acc.size();
io.writeToFile(acc);
} catch (InputMismatchException e) {
System.out.println("The scanner couldn´t read your input, use digits next time.");
System.out.println("The funds for this account has been set to zero, use transfers to adjust");
scan.reset();
}
}
public void transfer() {
System.out.print("Enter account number to withdraw/deposit to: ");
try {
account1 = Integer.parseInt(scan.nextLine());
if(account1 > acc.size() || account1 <= 0){
System.out.println("Incorrect input!");
System.out.println(s);
scan.reset();
return;
}
} catch (Exception e) {
System.out.println("Enter a number!");
scan.reset();
return;
}
System.out.print("Enter a positive number to deposit and negative to withdraw: ");
try {
funds = Integer.parseInt(scan.nextLine());
} catch (Exception e) {
System.out.println("Enter a number!");
scan.reset();
return;
}
for (int i = 0; i < acc.size() + 1; i++) {
if (account1 == i) {
if (funds > 0) {
acc.get(account1 - 1).setCash(funds + acc.get(account1 - 1).getCash());
System.out.println("The amount is changed to " + acc.get(account1 - 1).getCash());
index1 = transferHistory.size();
transferHistory.add(index1, new TransferHistory(account1, funds, account1));
io.writeTransferedToFile(transferHistory);
index1 = transferHistory.size();
}
if (funds < 0 && funds + acc.get(account1 - 1).getCash() > 0) {
acc.get(account1 - 1).setCash(funds + acc.get(account1 - 1).getCash());
System.out.println("The amount is changed to " + acc.get(account1 - 1).getCash());
index1 = transferHistory.size();
transferHistory.add(index1, new TransferHistory(account1, funds, account1));
io.writeTransferedToFile(transferHistory);
index1 = transferHistory.size();
} else if (acc.get(account1 - 1).getCash() + funds < 0) {
System.out.println("This transaction is not allowed since the balance will be negative");
}
}
}
io.writeToFile(acc);
}
public void view() {
acc = io.readFromFile();
for (int i = 0; i < acc.size(); i++) {
System.out.println(s);
System.out.println("Account name: " + acc.get(i).tempName);
System.out.println("Account number: " + acc.get(i).tempAccNr);
System.out.println("Funds: " + acc.get(i).tempCash);
}
if (acc.isEmpty()) {
System.out.println("No accounts to show");
}
}
public void quit() {
System.exit(0);
}
private void transferWithin() {
System.out.print("Enter account you want to transfer from: ");
try {
account3 = Integer.parseInt(scan.nextLine());
if(account3 > acc.size() || account3 <= 0){
System.out.println("Incorrect input!");
System.out.println(s);
scan.reset();
return;
}
} catch (Exception e) {
System.out.print("Enter a account number: ");
scan.reset();
return;
}
System.out.print("Enter amount you want to transfer: ");
try {
amount = Integer.parseInt(scan.nextLine());
} catch (Exception e) {
System.out.print("Enter a number: ");
scan.reset();
return;
}
System.out.print("Enter account you want to transfer to: ");
try {
account2 = Integer.parseInt(scan.nextLine());
if(account2 > acc.size() || account2 <= 0){
System.out.println("Incorrect input!");
System.out.println(s);
scan.reset();
return;
}
} catch (Exception e) {
System.out.print("Enter a account number:");
scan.reset();
return;
}
for (int i = 0; i < acc.size() + 1; i++) {
if (i == account3) {
c = acc.get(i - 1).getCash();
if (c - amount >= 0) {
acc.get(i - 1).setCash(c - amount);
System.out.println("Funds in account: " + acc.get(i - 1).getAcc() + " " + acc.get(i - 1).getCash());
index1 = transferHistory.size();
transferHistory.add(index1, new TransferHistory(account3, amount, account2));
io.writeTransferedToFile(transferHistory);
index1 = transferHistory.size();
} else if (c - amount < 0) {
System.out.println("Not enough funds in account");
mainMenu();
}
}
}
for (int j = 0; j < acc.size() + 1; j++) {
if (j == account2) {
c1 = acc.get(j - 1).getCash();
acc.get(j - 1).setCash(c1 + amount);
System.out.println("Funds in account " + acc.get(j - 1).getAcc() + " " + acc.get(j - 1).getCash());
}
}
io.writeToFile(acc);
}
private void viewOne() {
System.out.println("Enter account number you want to look at");
try {
viewAnswer = Integer.parseInt(scan.nextLine());
if(viewAnswer > acc.size() || viewAnswer <= 0){
System.out.println("Incorrect input!");
System.out.println(s);
scan.reset();
return;
}
} catch (Exception e) {
System.out.println("Enter a account number!");
scan.reset();
return;
}
for (int i = 0; i < acc.size() + 1; i++) {
if (i == viewAnswer) {
System.out.println("Account name: " + acc.get(i - 1).getName());
System.out.println("Account nr: " + acc.get(i - 1).getAcc());
System.out.println("Funds: " + acc.get(i - 1).getCash());
}
}
}
private void delete() {
System.out.print("Enter account you want to delete: ");
try {
deleteAnswer = Integer.parseInt(scan.nextLine());
if(deleteAnswer > acc.size() || deleteAnswer < 0){
System.out.println("Incorrect input!");
System.out.println(s);
scan.reset();
return;
}
} catch (Exception e) {
System.out.println("Enter a account number!");
scan.reset();
return;
}
for (int i = 0; i < acc.size(); i++) {
if (acc.get(i).getAcc() == deleteAnswer) {
acc.remove(i);
io.writeToFile(acc);
}
}
}
private void showTransfers() {
transferHistory = io.readTransferedFromFile();
System.out.println(s);
System.out.println("***Transactions***");
System.out.println(s);
for (int i = 0; i < transferHistory.size(); i++) {
int t = transferHistory.get(i).tempFromAccount;
int t1 = transferHistory.get(i).temptransfered;
int t2 = transferHistory.get(i).tempToAccount;
System.out.println("Transfer from: " + t);
System.out.println("Transfered amount: " + t1);
System.out.println("Transfered to: " + t2);
System.out.println(s);
}
}
private void showOneTransfer() {
transferHistory = io.readTransferedFromFile();
System.out.println(s);
System.out.println("***Transactions***");
System.out.println(s);
System.out.print("Enter account nr: ");
int z = scan.nextInt();
System.out.println("Transactions made my account nr "+z+":");
for (int i = 0; i < transferHistory.size(); i++) {
if(transferHistory.get(i).tempFromAccount == z){
int t = transferHistory.get(i).tempFromAccount;
int t1 = transferHistory.get(i).temptransfered;
int t2 = transferHistory.get(i).tempToAccount;
System.out.println("Transfer from: " + t);
System.out.println("Transfered amount: " + t1);
System.out.println("Transfered to: " + t2);
System.out.println(s);
}
}
}
}
Here I populate the array from the file:
public ArrayList<Account> readFromFile() {
FileReader reader = null;
ArrayList<Account> result = new ArrayList<Account>();
try {
reader = new FileReader(new File(text));
BufferedReader br = new BufferedReader(reader);
String row = br.readLine();
while (row != null) {
String[] splits = row.split(":");
if (splits.length == 3) {
int saveNR = Integer.valueOf(splits[1]);
int saveAmount = Integer.valueOf(splits[2]);
String saveName = splits[0];
result.add(new Account(saveName,saveNR,saveAmount));
} else {
System.out.println("Error in file format");
}
row = br.readLine();
}
} catch (Exception e) {
System.out.println("Error while reading from file");
} finally {
try {
reader.close();
} catch (IOException ex) {
System.out.println("Ignore");
}
return result;
}
}
private void delete() {
System.out.print("Enter account you want to delete: ");
try {
deleteAnswer = Integer.parseInt(scan.nextLine());
if(deleteAnswer > acc.size() || deleteAnswer < 0){
System.out.println("Incorrect input!");
System.out.println(s);
scan.reset();
return;
}
} catch (Exception e) {
System.out.println("Enter a account number!");
scan.reset();
return;
}
for (int i = 0; i < acc.size(); i++) {
if (acc.get(i).getAcc() == deleteAnswer) {
acc.remove(i);
io.writeToFile(acc);
}
}
}
If you want a counter, have it be a static variable on the class and increment it when you need a new value. Something like:
private static int counter = 0;
private static int nextCounter() {
return ++counter;
}
Or, for synchronization reasons, use
private static AtomicInteger counter = new AtomicInteger();
private static int nextCounter() {
return counter.incrementAndGet();
}
However, I suggest you stop thinking that you need to fill in all the gaps in the account numbers. Typically in database work, account numbers are never reused. You aren't formally using a database, but you should work the same way. Reuse buys you nothing, and there is always a chance your code may confuse a new user 17 with the an old user 17. Just imagine what would happen were the US Social Security Administration were to reuse social security numbers.
Here's the reason for your error, by the way. In the code:
for (int i = 0; i < acc.size(); i++) {
if(acc.get(i).getAcc() == accountNr) {
accountNr++;
}
}
Suppose accountNr starts as 1, there are 3 accounts, and they have account numbers 2, 1, 3. After each runthrough of the loop, accountNr changes to:
1 ⇢ 1⇢ 2 ⇢ 2.
2 is an existing accont number, but your code sets account number to 2 after the last time it would be checked.
Getting the first unused integer
You want a way to get the first unused integer in acc. Here goes:
private int firstUnusedId(List<Account> accounts) {
List<Integer> ids = new ArrayList<>();
// Foreach loop.
for(Account account: accounts) {
ids.add(account.getAcc());
}
Collections.sort(ids);
for (int index = 0; index < ids.size(); ++index) {
if (ids.get(index) != index + 1) {
return index + 1;
}
}
return ids.size() + 1;
}
If the ids are 2, 1, 5 then they sort to 1, 2, 5. Then the loop compares:
index = 0, index + 1 = 1, compare to 1, equal.
index = 1, index + 1 = 2, compare to 2, equal.
index = 2, index + 1 = 3, compare to 5, not equal, return 3.
If the ids were 3, 2, 1, they would sort to 1, 2, 3, and the only difference would be the last comparison:
index = 2, index + 1 = 3, compare to 3, equal.
return size + 1 = 4.
You must share more of you code but from what i have seen and predict that you are creating the new account from the last accountNr +1 so if your last account in the list is 2 then 3 will be created ...4 etc..so review your new account and set your accountNr = acc.size+1

Java skipping a number in the sequence

This is very interesting, i notice. Before i can explain further its best i show the code and you will understand what i mean.
This is the code:
public class Qn3 {
static BigDecimal[] accbal = new BigDecimal[19];
private static Integer[] accnums = new Integer[19];
public static void main(String[] args) {
addaccount();
}
public static void addAccount() {
int i = 0, accno, input, j, check;
BigDecimal accbala;
DecimalFormat df = new DecimalFormat("0.00");
Scanner sc = new Scanner(System.in);
Scanner in = new Scanner(System.in);
accnums[1] = new Integer(1);
while (accnums.length >= count(accnums)) {
System.out.print("Enter the account number: ");
while (sc.hasNext("[0-9]{7}")) {
accno = sc.nextInt();
System.out.print("Enter account balance: ");
accbala = in.nextBigDecimal();
for (j = 0; j < accnums.length; j++) {
if (accnums[j] == null)
break;
else if (accnums[j].equals(accno)) {
break;
}
}
if (j == accnums.length) {
System.out.print("No more than 20 accounts can be added.");
} else if (accnums[j] != null) {
if ((accnums[j].equals(accno)))
System.out.println("Account already exists");
break;
} else {
accnums[j] = accno;
accbala = accbala.setScale(2, RoundingMode.HALF_UP);
accbal[j] = accbala;
check = j;
System.out.println("Current number of accounts in the system: "
+ (check + 1)
+ "\nNumber of accounts still can be added: "
+ (20 - (check + 1)));
}
}
while (!sc.hasNext("[0-9]{7}")) {
System.out.println("Wrong NRIC");
break;
}
while (accnums.length <= count(accnums)) {
System.out.println("20 accounts have already been created");
break;
}
break;
}
}
private static int count(Integer[] array) {
int count = 0;
// accnums = new Integer[] {1,2};
for (int index = 0; index < array.length; index++) {
if (array[index] != null) {
count++;
}
}
// System.out.println("You have used " + count + " slots");
return count;
}
}
So now that you have seen the code the problem that is hard to notice is this, take note of the line in the addaccount() method where
System.out.println("Current number of accounts in the system: "+(check+1)+"\nNumber of accounts still can be added: "+(20 - (check+1)));
this line the first check+1 will give me 1 then the next one gives me 3! and then the next time i run the method it gives me 4 and then again 5 and so on so forth, what is happening to 2?
You have that println in an else block, and when j == 1 you're hitting the else if case. Try removing this line
accnums[1] = new Integer (1);

Categories