I'm just practicing java and at the moment I am currently experimenting with getter/setter methods and constructors. The java program works as I am able to store the user inputs into the object but when I input the String "Dice and rollers" into the gametype string variable, a Suspended uncaught exception InputMismatch error comes up.
This is the error I'm getting whenever I input "Dice and Rollers"
However, if I use String variables that does not include spaces, it works fine.
Can someone please explain to me why this is?
Ps. I've shared my source code below.
package test;
import java.util.Scanner;
public class Test8a {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please enter the following information: Boardgame name, Alternative Name, Game Type, Year Released, Price and Maximum amount of Players");
String name = in.next();
String secondaryname = in.next();
String type = in.next();
int date = in.nextInt();
double price = in.nextDouble();
int player = in.nextInt();
System.out.println();
new Test8b(name, secondaryname, type, date, price, player);
}
}
The one above is the superclass while the source code below is the constructor and getter/setter java file.
package test;
public class Test8b {
private String boardname;
private String secondaryname;
private String gametype;
private int date;
private double price;
private int numberofPlayers;
public Test8b(String boardname, String secondaryname, String gametype, int date, double price, int players) {
setBoardname(boardname);
setSecondaryname(secondaryname);
setGametype(gametype);
setDate(date);
setPrice(price);
setNumberofPlayers(players);
this.printDetails();
}
public String getBoardname() {
return boardname;
}
public String getSecondaryname() {
return secondaryname;
}
public String getGametype() {
return gametype;
}
public int getDate() {
return date;
}
public double getPrice() {
return price;
}
public int getNumberofPlayers() {
return numberofPlayers;
}
public void setBoardname(String boardname) {
if (boardname.length() >= 15) {
System.out.println("There is no boardgame with this name length! Please enter a valid name!");
} else this.boardname = boardname;
}
public void setSecondaryname (String secondaryname) {
if (secondaryname.length() >= 15) {
System.out.println("There is no boardgame with this name length! Please enter a valid name!");
} else this.secondaryname = secondaryname;
}
public void setGametype(String gametype) {
this.gametype = gametype;
}
public void setDate(int date) {
if (date > 2021) {
System.out.println("This game haven't been invented yet or are you a time traveller?");
} else this.date = date;
}
public void setPrice(double price) {
if (price <= 0) {
System.out.println("Can't give away free games!");
} else this.price = price;
}
public void setNumberofPlayers(int numberofPlayers) {
if (numberofPlayers <= 0) {
System.out.println("Need someone to play the game!");
} else this.numberofPlayers = numberofPlayers;
}
public void printDetails() {
System.out.print(
"Board Game: " + this.getBoardname() + "\n" +
"Alternative Title: " + this.getSecondaryname() + "\n" +
"Game Type: " + this.getGametype() + "\n" +
"Year Released: " + this.getDate() + "\n" +
"Price: " + this.getPrice() + "\n" +
"Maximum # of Players: " + this.getNumberofPlayers() + "\n"
);
}
}
The exception is being thrown by the Scanner object's next() method because the input when you enter a string with spaces does not match the Scanner's default delimiter pattern used for scanning. When you enter a String with spaces, the Scanner sees a line of characters, not just one word of input. In other words, it it differentiates between a single word and a line of words separated by white spaces.
The java.util.Scanner.nextLine() method advances the scanner past the current line and returns the input that was skipped and is the method you should use to scan the game type. Modify your code to use Scanner.nextLine() for the game type and any other type that may have multiple words in it.
Related
just entered this community and this is my first question here, so please bear with a noob. I created two classes, first is Student, a basic one with fields, constructor and getters. The second one has the main method, a LinkedList, a multiple-entry Scanner (for...) and two simple methods.
My problem is that despite the fact that the For loop has maximum index 1 (x = 0; x < 2), the Scanner expects a third row input and an enter but does not print the third line. I add the two classes, maybe I made a mistake and I would appreciate your help. Thank you in advance.
public class Student {
private String name;
private String surname;
private int firstMark;
private int secondMark;
private int finalExamMark;
public Student(String name, String surname, int firstMark, int secondMark, int finalExamMark) {
this.name = name;
this.surname = surname;
this.firstMark = firstMark;
this.secondMark = secondMark;
this.finalExamMark = finalExamMark;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
public int getFirstMark() {
return firstMark;
}
public int getSecondMark() {
return secondMark;
}
public int getFinalExamMark() {
return finalExamMark;
}
#Override
public String toString (){
return this.name + " " + this.surname + " got " + this.firstMark + " at English, " + this.secondMark + " at Math and " + this.finalExamMark + " at the final exam.";
}
}
public class StudentMain {
static LinkedList<Student> courseAttend = new LinkedList<>();
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
addStudent();
printList(courseAttend);
}
private static void addStudent() {
for (int x = 0; x < 2; x++) {
String s1 = scanner.nextLine();
String[] split = s1.split("\\s");
courseAttend.add(new Student(split[0], split[1], Integer.parseInt(split[2]), Integer.parseInt(split[3]), Integer.parseInt(split[4])));
scanner.nextLine();
}
scanner.close();
}
private static void printList(LinkedList<Student> lista) {
for (Student elem : lista) {
System.out.println(elem);
}
}
}
For example, if I input (without quotes)
"Young John 9 9 9"
"Johnson Anne 8 8 8" and I press enter, the cursor moves to next line and waits another input. Only after that third line and the final enter, the message is displayed but the third line is not shown.
courseAttend should be a List<Student> courseAttend = new ...List<>(); like your methode argument printList(List<Student> students) because both could be also a ArrayList and it is the normal way to in implement variables if they have not to be sepciefied, like in your case.
The loop has two nextLine() but you ignore the second one so you are creating a student and waiting of the next input and not saving the input
When a User has to enter multiple arguments for any given prompt, you can expect to have typos. Your prompt expects the User to enter 5 arguments and they are not even from the same typ on a single line delimited with a whitespace. What if the user accidentally give you an ivalid input like a integer as name or a String as mark.
public class StudentMain {
static List<Student> courseAttend = new LinkedList<>();
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
for (int x = 0; x < 2; x++) {
courseAttend.add(createStudent());
}
scanner.close();
printList(courseAttend);
}
private static Student createStudent(){
System.out.print("name: ");
String name = scanner.nextLine();
System.out.print("surname: ");
String surname = scanner.nextLine();
System.out.print("first mark: ");
int firstMark = scanner.nextInt();
System.out.print("second mark: ");
int secondMark = scanner.nextInt();
System.out.print("final exam mark: ");
int finalExamMark = scanner.nextInt();
return new Student(name, surname, firstMark, secondMark ,finalExamMark);
}
private static void printList(List<Student> students) {
for (Student elem : students) {
System.out.println(elem);
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
So everything works great in my program, but I read that making variable not private in class is a big mistake, because it can make problems with others part of big program.
Well I tried making HashMap airplane and flight private but I get error that "The field Airplane.airplane is not visible",which is of course true.
But how do I then make it visible in interface class?
Thanks in advance, I'm still learning and I got to this part in course.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner imeskanera = new Scanner(System.in);
Airplane airplane = new Airplane();
flight flight = new flight();
interface_aerodrom ui = new interface_aerodrom(imeskanera,airplane,flight);
ui.start();
}
}
/ Airplane class
import java.util.HashMap;
public class Airplane {
HashMap<String,Integer>airplane;
private String id;
private int capacity;
public Airplane() {
this.airplane = new HashMap<String,Integer>();
}
public void add(String id, int capacity) {
this.id = id;
this.capacity = capacity;
this.airplane.put(id, capacity);
}
public String id() {
return this.id;
}
public int capacity() {
return this.capacity;
}
public String airplaneinfo() {
return this.id + "( " + this.capacity + " )";
}
}
/interface class
import java.util.Scanner;
public class interface_aerodrom {
private Scanner imeskanera;
private Airplane airplane;
private flight flight;
public interface_aerodrom(Scanner scanner, Airplane airplane,flight flight) {
this.imeskanera = scanner;
this.airplane = airplane;
this.flight = flight;
}
public void start() {
System.out.println("Airport panel\r\n"
+ "--------------------");
System.out.println();
while(true) {
System.out.println("Choose operation:\r\n"
+ "[1] Add airplane\r\n"
+ "[2] Add flight\r\n"
+ "[x] Exit");
String input = this.imeskanera.nextLine();
input = input.toLowerCase();
input = input.trim();
if(input.equals("x")) {
flight_service();
break;
}
else if(input.equals("1")) {
addairplane();
}
else if(input.equals("2")){
addflight();
}
}
}
public void flight_service() {
System.out.println("Flight service\r\n"
+ "------------");
while(true) {
System.out.println("Choose operation:\r\n"
+ "[1] Print planes\r\n"
+ "[2] Print flights\r\n"
+ "[3] Print plane info\r\n"
+ "[x] Quit");
String input = this.imeskanera.nextLine();
input = input.toLowerCase();
input = input.trim();
if(input.equals("quit")){
break;
}
else if(input.equals("1")) {
for(String name : this.airplane.airplane.keySet()) {
int numberofseats = this.airplane.airplane.get(name);
String list = name + "( " + numberofseats + " )";
System.out.println(list);
}
}
else if(input.equals("2")){
for(String name : this.flight.flight.keySet()) {
String value = this.flight.flight.get(name);
String list = name + value;
System.out.println(list);
}
}
else if(input.equals("3")) {
System.out.println("Give plane ID: ");
String planeid = this.imeskanera.nextLine();
if(airplanecontains(planeid)) {
int numberofseats = this.airplane.airplane.get(planeid);
System.out.println(planeid + "( " + numberofseats + " )" );
} else {
System.out.println("That plane is not in our database");
}
}
}
}
public void addairplane() {
System.out.println("Give plane ID: ");
String ID = this.imeskanera.nextLine();
System.out.println("Give plane capacity: ");
int capacity = Integer.parseInt(this.imeskanera.nextLine());
this.airplane.add(ID, capacity);
}
public boolean airplanecontains(String ID) {
if(this.airplane.airplane.containsKey(ID)) {
return true;
}else {
return false;
}
}
public void addflight() {
System.out.println("Give plane ID: ");
String ID = this.imeskanera.nextLine();
if(airplanecontains(ID)) {
System.out.println("Give departure airport code: ");
String departure = this.imeskanera.nextLine();
System.out.println("Give destination airport code: ");
String destination = this.imeskanera.nextLine();
int seats = this.airplane.airplane.get(ID);
this.flight.flight.put(ID + " ( " + seats + " ) ",departure + "-" + destination);
}
else {
System.out.println("This plane is not in our database");
}
}
}
/ flight class
import java.util.HashMap;
public class flight {
HashMap<String,String>flight;
public flight() {
this.flight = new HashMap<String,String>();
}
public void add(String departure, String destination) {
this.flight.put(departure, destination);
}
}
Making a field private does not necessarily mean you can't share it. You can use a getter to return the HashMap.
private Map<String,Integer>airplane = new HashMap<>();
public Map<String,Integer> getAirPlaneMap() {
return airplane;
}
The reason being is that this hides implementation details and allows for future changes without affecting users of the class. Users don't need to know where the map comes from within your class. You could have retrieved it from some where yourself and the user wouldn't know.
You may also want to ensure a user can't change it. So you could do the following:
public Map<String,Integer> getAirPlaneMap() {
return Collections.unModifiableMap(airplane);
}
The above will prevent the user from adding or deleting map elements. But it won't prevent them from changing a retrieved object from the map unless that object is also immutable.
In general, setter and getters are the best way to allow users to set and retrieve values. And it is usually a good idea to make defensive copies of mutable items that they are retrieving to ensure that the retrieved values are consistent for all users during execution of the program.
How can I be able to print out the objects that I gave the program in case 2
What I'm trying to implement is case 2 giving me all the info about the stuff I put into case 1
At first I tried to just use the setters and getters but for some reason I was having a NullPointerException when I used the do-while method.
So I decided to use the constructor but at the same time it gave me an error when trying to implement case 2. so any help would be appreciated.
import java.util.Scanner;
public class GameProject {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int choice;
do{
GameSale[] game;
System.out.println("Hello! welcome to the menu!");
System.out.println("Please Choose your option!");
System.out.println(" 1-Enter a new game's Info \n 2-Check a game's Information \n 3- Check a game's sales \n 0-Exit");
choice = input.nextInt();
switch (choice){
case 0:
break;
case 1:
System.out.println("");
System.out.print("How many games do you want to add? : ");
int size = input.nextInt();
game = new GameSale[size];
for (int i = 0; i < size; i++) {
System.out.print("Enter Game "+(i+1) + "'s Name!: \n");
String tempname = input.next();
System.out.print("Enter the ID of the Game : \n");
int tempid = input.nextInt();
System.out.print("Enter the Game Type : \n");
String tempgametype=input.next();
System.out.print("Enter the development Company's Name : \n");
String tempgamecomp = input.next();
System.out.print("Enter the Release Sale : \n");
double temprelsale = input.nextDouble();
System.out.print("Enter the total Sales : \n");
double temptotsale = input.nextDouble();
game[i]=new GameSale(temprelsale,temptotsale,tempid,tempname,tempgamecomp,tempgametype);
}break;
case 2:
for(int i = 0; i < game.length; i++){
System.out.println(game[i].toString());
}
}while(choice!=0);
}
}
i got a class that has the setters and getters for some of the regular info
public class GameInfo {
protected int ID;
protected String GameName;
protected String DevelopmentCompany;
protected String GameType;
public GameInfo(int ID, String GameName, String DevelopmentCompany, String GameType) {
this.ID = ID;
this.GameName = GameName;
this.DevelopmentCompany = DevelopmentCompany;
this.GameType = GameType;
}
public void SetID(int id) {
this.ID = id;
}
public int GetID() {
System.out.println("The ID is " + ID);
return ID;
}
public void SetName(String Name) {
this.GameName = Name;
}
public String GetName() {
System.out.println("The Name of the Game Is " + GameName);
return GameName;
}
public void SetCompanyName(String CompanyName) {
this.DevelopmentCompany = CompanyName;
}
public String GetCompanyName() {
System.out.println("The Name Of the Development company Is " + DevelopmentCompany);
return DevelopmentCompany;
}
public void SetGameType(String GameType){
this.GameType=GameType;
}
public String GetGameType(){
System.out.println("The Game Type is : "+GameType);
return GameType;
}
}
and a super class with the sales and a constructor for the sales
public class GameSale extends GameInfo {
protected double ReleaseSales;
protected double TotalSales;
public GameSale(double ReleaseSales, double TotalSales, int ID, String GameName, String DevelopmentCompany, String GameType) {
super(ID, GameName, DevelopmentCompany, GameType);
this.ReleaseSales = ReleaseSales;
this.TotalSales = TotalSales;
}
public void SetReleaseSales(double RelSale){
this.ReleaseSales=RelSale;
}
public void SetTotalSales(double totSales){
this.TotalSales=totSales;
}
public double GetReleaseSales(){
System.out.println("The Release Sales Are "+ReleaseSales );
return ReleaseSales;
}
public double GetTotalSales(){
System.out.println("The Total Sales Are "+TotalSales);
return TotalSales;
}
}
Answered by Alex (thanks a lot dude)
here's a temporary fix just for debugging so far by initializing the array dimensions outside the do-while loop
main
import java.util.Scanner;
public class GameProject {
public static void main(String[] args) {
Scanner input = new Scanner(System. in );
int choice;
GameSale[] games = new GameSale[1];
do {
System.out.println("Hello! welcome to the menu!");
System.out.println("Please Choose your option!");
System.out.println(" 1-Enter a new game's Info \n 2-Check a game's Information \n 3- Check a game's sales \n 0-Exit");
choice = input.nextInt();
switch (choice) {
case 0:
break;
case 1:
for (int i = 0; i < games.length; i++) {
System.out.print("Enter Game " + (i + 1) + "'s Name!: \n");
String tempname = input.next();
System.out.print("Enter the ID of the Game : \n");
int tempid = input.nextInt();
System.out.print("Enter the Game Type : \n");
String tempgametype = input.next();
System.out.print("Enter the development Company's Name : \n");
String tempgamecomp = input.next();
System.out.print("Enter the Release Sale : \n");
double temprelsale = input.nextDouble();
System.out.print("Enter the total Sales : \n");
double temptotsale = input.nextDouble();
games[i] = new GameSale(temprelsale, temptotsale, tempid, tempname, tempgamecomp, tempgametype);
}
break;
case 2:
for (int i = 0; i < games.length; i++) {
System.out.println(games[i].toString());
}
}
} while ( choice != 0 );
}
}
game info
public class GameInfo {
protected int ID;
protected String GameName;
protected String DevelopmentCompany;
protected String GameType;
public GameInfo(int ID, String GameName, String DevelopmentCompany, String GameType) {
this.ID = ID;
this.GameName = GameName;
this.DevelopmentCompany = DevelopmentCompany;
this.GameType = GameType;
}
public void SetID(int id) {
this.ID = id;
}
public int GetID() {
System.out.println("The ID is " + ID);
return ID;
}
public void SetName(String Name) {
this.GameName = Name;
}
public String GetName() {
System.out.println("The Name of the Game Is " + GameName);
return GameName;
}
public void SetCompanyName(String CompanyName) {
this.DevelopmentCompany = CompanyName;
}
public String GetCompanyName() {
System.out.println("The Name Of the Development company Is " + DevelopmentCompany);
return DevelopmentCompany;
}
public void SetGameType(String GameType){
this.GameType=GameType;
}
public String GetGameType(){
System.out.println("The Game Type is : "+GameType);
return GameType;
}
}
game sale
public class GameSale extends GameInfo {
protected double ReleaseSales;
protected double TotalSales;
public GameSale(double ReleaseSales, double TotalSales, int ID, String GameName, String DevelopmentCompany, String GameType) {
super(ID, GameName, DevelopmentCompany, GameType);
this.ReleaseSales = ReleaseSales;
this.TotalSales = TotalSales;
}
public void SetReleaseSales(double RelSale){
this.ReleaseSales=RelSale;
}
public void SetTotalSales(double totSales){
this.TotalSales=totSales;
}
public double GetReleaseSales(){
System.out.println("The Release Sales Are "+ReleaseSales );
return ReleaseSales;
}
public double GetTotalSales(){
System.out.println("The Total Sales Are "+TotalSales);
return TotalSales;
}
public String toString(){
return this.ID + " " + this.GameName + " " + this.DevelopmentCompany + " " + this.GameType;
}}
Solution
toString()
In your class you should implement a toString() method.
This basically returns all the property values of your object as a String
public String toString(){
return this.ID + " " + this.GameName + " " + this.DevelopmentCompany + " " + this.GameType;
}
Then call it on your object in case2
game[i].toString()
Display
To list all games you have to iterate over your gamesArray and print out the informations with your toString() method;
for(int i = 0; i < games.length(); i++){
System.out.println(game[i].toString());
}
Scope
Create the games array outside of you case1 scope.
GameSale[] game = new GameSale[SomeFixedSize];
If you wanted to print a game's info at a given index in case 2:
if (game == null) { // Break if no game exists
System.out.println("There is no games to show!");
break;
}
System.out.print("Enter game index to show information: ");
int index = input.nextInt();
// Break if index is not in bounds
if (index < 0 || index > game.length) {
System.out.println("Incorrect index");
break;
}
System.out.println("Info of game: " + game[index].toString());
This code should ask for index as input and prints the info of the game and it will print 'There is no games to show!' if there was no any game added yet
Note you must add the toString() method in your GameSale class:
#Override
public String toString() {
return "ID: " + this.ID + " Name: " + this.GameName + " Development Company: " +
this.DevelopmentCompany + " Game Type: " + this.GameType + " Release Sales: " + ReleaseSales + " Total Sales: " + TotalSales;
}
also move the decleration of the game variable out of the scope of the do-while loop (above it) it will look like
GameSale[] game = null;
do { ...
Also if you want case 2 to show all games info you can replace the index part with a loop that iterates the whole 'game' array and prints every element's toString.
So I took everyone's feedback and information and have spent quite a bit of time trying to work on my code prior to submitting. Here are the changes that I have:
import java.util.*;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
class Automobiles {
String make;
String model;
String color;
int year;
int mileage;
int i;
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMileage() {
return mileage;
}
public void setMileage(int mileage) {
this.mileage = mileage;
}
public void setMake(String make) {
this.make = make;
}
public Automobiles() {
make = "";
model = "";
color = "";
year = 0;
mileage = 0;
}
public void Inventory(String make, String model, String color, int year, int mileage) {
System.out.println("Car is: " + make + " " + model + " " + color + " " + year + " " + mileage);
}
String getMake() {
return make;
}
}
public class AutomobileInventory {
public static void main(String[] args)
{
Automobiles[] carInventory = new Automobiles[15];
int i;
String fileName = "out.txt";
boolean quit = false;
String quit1 = "No";
Scanner scnr = new Scanner(System.in);
while (quit1 != "Yes") {
for(i=0; i<carInventory.length; i++) {
carInventory[i] = new Automobiles();
System.out.println("");
System.out.println("Please Enter the make of the vehicle: ");
carInventory[i].make = scnr.nextLine();
System.out.println("Please Enter the model of the vehicle: ");
carInventory[i].model = scnr.nextLine();
System.out.println("Please Enter the vehicle color: ");
carInventory[i].color = scnr.nextLine();
System.out.println("Please Enter the year of the vehicle: ");
carInventory[i].year = scnr.nextInt();
System.out.println("Please Enter the vehicle's mileage: ");
carInventory[i].mileage = scnr.nextInt();
System.out.println("Are you done? Yes or No");
quit1 = scnr.nextLine();
}
}
for(i=0; i<carInventory.length; i++)
System.out.println(carInventory[i].make + " " + carInventory[i].model + " " + carInventory[i].color + " " + carInventory[i].year + " " + carInventory[i].mileage);
try {
PrintWriter outputstream = new PrintWriter(fileName);
outputstream.println(carInventory[i].make + " " + carInventory[i].model + " " + carInventory[i].color + " " + carInventory[i].year + " " + carInventory[i].mileage);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I am running into an issue now that as it completes the loop the first and second instance are combining and it is not allowing me to enter a string for Make each time. Also when I printed to a file it only printed one instance and not all of the instances. Any help is appreciated.
Because you aren't initializing the quit variable, and are using a do-while loop, the loop executes once without checking if quit = "quit". This causes the loop to appear to execute fine, but then crash on the second iteration.
If we examine the structure of how the loop executes:
1) Print "Car Model:"
2) Print "Car Make:"
3) Print "Car Color:"
4) Print "Car Year:"
5) Print "Car Mileage:"
6) Execute For loop
7) Evaluate whether quit == "quit"
8) Print "Car Model"
9) Etc...
When step #7 attempts to evaluate the equality, it is actually performing this comparison:
!null.equalsIgnoreCase("quit"));
Because above in the code, the variable quit was never initialized, and is still set to null. The two code snippets below are in essence equivalent:
// Initialization without assignment:
String quit;
// Explicit initialization to null:
String quitTwo = null;
// Output
print quit
// >> NullPointerException
print quitTwo
// >> NullPointerException
Your Automobile class is fine.
In your automobileInventory class, your are initializing static data member in a non-static method (Check the function where you are initializing the automobiles array).
You can simply initialize it where you are declaring it i.e.:
private static Automobile[] automobiles = new Automobile[ INVENTORY_SIZE ];
Another way is to initialize it in a static block i.e.:
private static Automobile[] automobiles;
static {
automobiles = new Automobile[ INVENTORY_SIZE ];
}
Another way is to initialize it in your function before your loop.
In your sentinel-controlled loop, you are checking exit condition on quit variable but you are not assigning it anything. You need to get value from user whether he/she intends to quit or not.
Here's an example:
String quit; // In your function; not a class member
do {
// ... Rest of your code ...
System.out.println("Do you want to quit [Yes/No]? ");
quit = scnr.nextLine();
}
while ( !quit.equalsIgnoreCase("yes") );
And, you need to take care of your array instance of automobiles that it is correctly being populated. You need to take care of its index that it remains valid.
String quit; // In your function; not a class member
int i = 0;
do {
// ... Rest of your code ...
if ( i < INVENTORY_SIZE ) {
automobiles[i] = new Automobile(make, model, color, year, mileage);
i++;
}
else {
// ... Display error message here that array is full ...
// ... You can then break this loop to exit if you want to ...
break;
}
System.out.println("Do you want to quit [Yes/No]? ");
quit = scnr.nextLine();
}
while ( !quit.equalsIgnoreCase("yes") );
Here's your working code: https://ideone.com/JqX9Y9
Some of the lines are commented for my own testing. You can easily correlate the changes with this answer and figure out yourself what is going on.
Best of luck!
Happy coding!
As #kushagra mentioned, you need to initialize your quit variable. It's currently null, hence the NullPointerException (trying to call a method that doesn't yet exist for your variable)
One tip regarding your quit variable though, I would change it to type boolean since all you need is a true/false. This way, you don't have to do any string comparisons. It would look something like this:
boolean quit = false;
...
do { /* loop stuff */ }
while(quit != true);
Then in your do loop, you can add logic to change your quit variable to true when your user is ready to quit.
Regarding your inventory, I wouldn't use an array if you don't have to; I would use a list (arrays can't change size, whereas lists can). Then instead of using your for loop (you're already looping with your do-while - makes it a little redundant), you can add a new automobile to your list where you currently have it commented out. It would look something like this:
private static List<Automobile> automobiles;
...
automobiles.add(new Automobile(make, model, Color, year, mileage));
UPDATE
Your code is pretty messy - make sure you're consistent with your tabbing/spacing/etc. You should also come up with a clean way of organizing your methods. For example, I like to keep all my getters and setters together with constructors right below the class properties. The bottom of the class is where I like to keep general class methods, overridden methods, etc.
One issue you have with your code is in your main(...); try not to loop within loops if you don't have to (obviously there are always exceptions, such as multidimensional arrays, traversing "grids", etc) - this can slow down execution quite a bit (check out Big O notation - this is a pretty good article: https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/). This will also help you keep track of when your loop closes.
Your file write only happens once because you're not looping (this is where consistent indentation/spacing may help you).
Couple more quick tips: whenever you reuse a value, make a variable for it. You did this a few times, but there were several instances where you could have used a variable (remember: method calls take time to run, so limiting redundant calls will speed up your program). Also, don't be afraid to override the toString() method in your classes - the automobiles class is actually a really good use case for it.
I tried not to give you all the answers, but I've rewritten your code a bit to help you get going:
import java.util.ArrayList;
import java.util.List;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
class Automobiles {
String color = "";
String make = "";
String mileage = "";
String model = "";
String year = "";
// -------------------- getters -------------------- //
public String getColor() { return color; }
public String getMake() { return make; }
public String getModel() { return model; }
public String getMileage() { return mileage; }
public String getYear() { return year; }
// -------------------- setters -------------------- //
public void setColor(String color) { this.color = color; }
public void setMake(String make) { this.make = make; }
public void setMileage(String mileage) { this.mileage = mileage; }
public void setModel(String model) { this.model = model; }
public void setYear(String year) { this.year = year; }
#Override
public String toString() {
return year + " " + model + " " + make;
}// end toString()
}// end class Automobiles
public class AutomobileInventory {
public static void main(String[] args) {
List<Automobiles> carInventory = new ArrayList<>();
String fileName = "out.txt";
boolean quit = false;
Scanner scnr = new Scanner(System.in);
do {
Automobiles car = new Automobiles();
System.out.println("Please Enter the year of the vehicle: ");
car.setYear(scnr.nextLine());
System.out.println("Please Enter the make of the vehicle: ");
car.setMake(scnr.nextLine());
System.out.println("Please Enter the model of the vehicle: ");
car.setModel(scnr.nextLine());
System.out.println("Please Enter the vehicle color: ");
car.setColor(scnr.nextLine());
System.out.println("Please Enter the vehicle's mileage: ");
car.setMileage(scnr.nextLine());
carInventory.add(car);
System.out.println("Are you done? Yes or No");
quit = "yes".equals(scnr.nextLine().trim().toLowerCase()) ? true : false;
} while(quit == false);// end do-while-loop
int numCars = carInventory.size();
for(int i = 0; i < numCars; i++) {
String currentCar = carInventory.get(i).toString();
System.out.println(currentCar);
try {
PrintWriter outputstream = new PrintWriter(fileName);
outputstream.println(currentCar);
} catch( FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}// end try-catch
}// end for-loop
}// end main(String[] args)
}// end class AutomobileInventory
I have this basic enough Java program that asks the user to input songs to a music library array list. From there the user can shuffle their songs, delete a song, delete all etc. It's nearly finished, I just have one issue I can't resolve. It happens when I try export the array list to a text file. Instead of the content of the array list, my output would look like this, as opposed to the details the user submitted:
"1: MainClass.SongClass#c137bc9
MainClass.SongClass#c137bc9"
I'll post my code below, I'd really appreciate if someone could point me in the right direction!
My Final Project class which serves as my main class:
package MainClass;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FinalProject extends UserInput {
public String nextInt;
public static void main(String[] args) {
// SongLibrary iTunes; //Object stores the file cars.txt
// iTunes = new SongLibrary("MUSIC LIBRARY.txt");
// songData CLO = iTunes.readFileIntoList();
UserInput ui;
ui = new UserInput();
Scanner input = new Scanner(System.in);
int opt;
//Calls Methods Class so methods can be used below
Menu menuFunctions = new Menu();
//Calls FileReaderTest Class so file can be read
SongLibrary Reader = new SongLibrary();
//initial prompt only displayed when program is first ran
System.out.println("Welcome to your music library!");
do {
//Menu Prompts printed to the screen for the user to select from
System.out.println(" ");
System.out.println("Main Menu:");
System.out.println("........ \n");
System.out.println("Press 0 to Exit");
System.out.println("Press 1 to Add a Song");
System.out.println("Press 2 to View All Songs");
System.out.println("Press 3 to Remove a Song");
System.out.println("Press 4 to Shuffle Library");
System.out.println("Press 5 to Play a Random song");
System.out.println("Press 6 to Remove ALL Songs");
System.out.println("Press 7 to Save Library\n");
//Monitors the next Int the user types
opt = input.nextInt();
//"if" statements
if (opt == 0) {
//This corresponds to the condition of the while loop,
//The program will exit and print "Goodbye!" for the user.
System.out.println(" ");
System.out.println("Goodbye!");
} else if (opt == 1) {
//This method allows the user to add a song to the library.
//With the format being Title, Artist, Year.
System.out.println(" ");
menuFunctions.addEntry();
} else if (opt == 2) {
//This method prints the contents of the Array List to the screen
System.out.println("\n");
menuFunctions.viewAll();
} else if (opt == 3) {
//This method allows the user to remove an indiviual song from
//their music library
System.out.println("\n");
menuFunctions.removeOne();
} else if (opt == 4) {
//This method uses the Collections.shuffle method
//to re-arrange the track list
//song to simulate a music player's shuffle effect.
System.out.println("\n");
menuFunctions.shuffleSongs();
} else if (opt == 5) {
//This method will clear all contents of the library.
//It will ask the user to confirm their choice.
System.out.println("\n");
menuFunctions.randomSong();
} else if (opt == 6) {
//This method will clear all contents of the library.
//It will ask the user to confirm their choice.
System.out.println("\n");
menuFunctions.clearLibrary();
}
else if (opt == 7) {
try {
menuFunctions.saveLibrary();
} catch (FileNotFoundException x) {
System.out.println("File not found. " + x);
}
}
else {
//If the user selects an incorrect number, the console will
//tell the user to try again and the main menu will print again
System.out.println("\n");
System.out.println("Incorrect Entry, please try again");
}
} //do-while loop
while (opt > 0);
}
}
My SongClass class which holds the constructor and Get/Set methods
package MainClass;
public class SongClass {
private int songMinutes;
private int songSeconds;
private String songTitle;
private String songArtist;
private String songAlbum;
private int songYear;
public SongClass(int m, int ss, String t, String art, String al, int y){
songMinutes = m;
songSeconds = ss;
songTitle = t;
songArtist = art;
songAlbum = al;
songYear = y;
}
//GET METHODS
public int getMinutes() {
return songMinutes;
}
public int getSeconds() {
return songMinutes;
}
public String getTitle() { //
return songTitle;
}
public String getArtist() {
return songArtist;
}
public String getAlbum() {
return songAlbum;
}
public int getYear() {
return songYear;
}
//SET METHODS
public void setMinutes(int m){
songMinutes = m;
}
public void setDuration(int ss){
songSeconds = ss;
}
public void setTitle(String t){
songTitle = t;
}
public void setArtist(String art){
songArtist = art;
}
public void setAlbum(String al){
songAlbum = al;
}
public void printSong(){
System.out.println(songMinutes+":"+ songSeconds + " - " + songTitle + " - " + songArtist + " - " +songAlbum + " - "+ "("+songYear+")");
}
}
My menu class which holds most of the methods used in the program
package MainClass;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;
public class Menu {
public void add(SongClass s) throws NumberFormatException {
try {
songLibrary.add(s);
} catch (NumberFormatException x) {
}
}
Scanner input = new Scanner(System.in);
UserInput ui = new UserInput();
public ArrayList<SongClass> songLibrary;
public Menu() {
songLibrary = new ArrayList<SongClass>();
}
public void removeOne() throws ArrayIndexOutOfBoundsException {
try {
System.out.println("Which song would you like to delete? (1 of " + songLibrary.size() + ")");
viewAll();
//calls the viewAll method to print current library to screen
int remove = input.nextInt();
//creates an int that corresponds to the nextInt typed.
if (remove > songLibrary.size()) {
System.out.println("Invalid ");
//if the user types a number higher than the highest index of the
//array list, they will be shown an error and return to the menu
}
else {
remove --;
SongClass s = songLibrary.get(remove);
System.out.println("Are you sure you would like to delete the following track from your music library? ");
s.printSong();
//confirms user wants to delete the selected track
System.out.print("1: Yes \n2: No" + "\n");
int confirmDelete = input.nextInt();
//Asks the user to input 1 or 2,
if (confirmDelete == 1) {
songLibrary.remove(remove);
//removes the index of the 4 array lists
System.out.println( "Removed.");
viewAll();
} else if (confirmDelete == 2) {
System.out.println("\n" + "Okay, the song won't be removed");
} else {
System.out.println("\n" + "Invalid option.");
}
}
}
catch (ArrayIndexOutOfBoundsException x) {
System.out.println("Please select an valid entry");
}
}
public void clearLibrary() {
System.out.println("Confirm?");
System.out.print("1: Yes \n2: No" + "\n");
int confirmDelete = input.nextInt();
//if the user types one, this triggers the clear method.
if (confirmDelete == 1) {
songLibrary.clear();
System.out.println("\n" + "Your music library has been cleared" + "/n");
}
}
public void shuffleSongs() {
//The shuffle function shifts the location of all the elements of an
//array list. This mimics the shuffle effect of a Music player
//The attributes of the song all get shuffled together because they
//are all linked by the same seed.
long seed = System.nanoTime();
Collections.shuffle(songLibrary, new Random(seed));
System.out.println("Your library is now shuffled" + "\n");
viewAll();
//Shuffles library, then outputs the new library list.
}
public void viewAll() {
if (songLibrary.isEmpty()) {
System.out.println("Your library is currently empty!");
} else {
System.out.println("Your Music Library" + "\n" + "Duration - Artist - Song - Album -(Year) " + "\n");
for (int i = 0; i < songLibrary.size(); i++) {
SongClass s = songLibrary.get(i);
s.printSong();
}
}
System.out.println("\n");
}
public void randomSong() {
int randomSong = (int) (Math.random() * (songLibrary.size() - 1));
//uses Math.random to generate a random double between 0.0 and 1.0
//it then multiplies it by the size of the array list - 1
//The end result is that a random index of the array list is selected
System.out.println("Now Playing:");
//the selected song randomSong is then outputted
//this changes each time the randomSong method is called
SongClass s = songLibrary.get(randomSong);
s.printSong();
}
public void saveLibrary() throws FileNotFoundException {
try (PrintWriter pw1 = new PrintWriter("MUSIC LIBRARY.txt")) {
File inFile = new File("MUSIC LIBRARY.txt");
Scanner in = new Scanner(inFile);
System.out.println("Your music library has been successfully exported!\n");
pw1.println("Your Music Library");
pw1.println(" ");
pw1.println("Duration - Artist - Song - Album (Year) " + "\n");
pw1.println(" ");
for (int i = 0; i < songLibrary.size(); i++) {
System.out.println("The loop ran this many times");
System.out.println(i);
int counter = i + 1;
pw1.println(counter + ": " + songLibrary.get(i));
}
System.out.println("Loop is over, PrintWriter should close.");
pw1.close();
}
}
public void addEntry() throws NumberFormatException {
try {
int minutes = ui.getInt("How many minutes does this song last?");
int seconds = ui.getInt("How many seconds does this song last?");
String title = ui.getString("What is the title of the track?");
String artist = ui.getString("Who performs the track?");
String album = ui.getString("What album is the track from?");
int year = ui.getInt("What year was the track released?");
System.out.println("Please enter a number:");
System.out.println("\n");
SongClass s = new SongClass(minutes, seconds, title, artist, album, year);
songLibrary.add(s);
System.out.println("Thank you!" + " " + title + " " + "was added to your library:");
} catch (NumberFormatException x) {
System.out.println(" ");
System.out.println("Year/Duration can use numbers only, please try again.");
System.out.println(" ");
}
}
}
And my user input class
package MainClass;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class UserInput{
private Scanner keyboard;
public UserInput() {
this.keyboard = new Scanner(System.in);
}
public String getString(String prompt) {
String line;
System.out.print(prompt + ": ");
line = this.keyboard.nextLine();
return line;
}
public int getInt(String prompt) {
String line;
int num;
System.out.print(prompt + ": ");
line = this.keyboard.nextLine();
num = Integer.parseInt(line);
return num;
}
public Date getDate(String prompt) {
String line;
SimpleDateFormat formatter;
Date date;
System.out.print(prompt + " (dd/MM/yyyy): ");
line = this.keyboard.nextLine();
formatter = new SimpleDateFormat("dd/MM/yyyy");
try {
date = formatter.parse(line);
}
catch (ParseException ex) {
date = null;
}
return date;
}
public boolean getBoolean(String prompt) {
String line;
System.out.print(prompt + "? (Y|N)");
line = this.keyboard.nextLine();
return line.equalsIgnoreCase("Y");
}
}
"1: MainClass.SongClass#c137bc9 MainClass.SongClass#c137bc9"
This is what the default implementation of toString outputs.
You need to override toString in your SongClass:
#Override
public String toString(){
return String.format("%d:%d - %s - %s - %s - (%d)",
songMinutes,songSeconds, songTitle, songArtist , songAlbum, songYear);
}
An alternative (which may be better if you don't want to override toString, because that method is used elsewhere) is to loop over all elements of your list and explicitly format the output by calling appropriate getters (or another method similar to your printSong method).