Linking array with Subclasses [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
my current program is a pupil library system, I have my array lists, menus and methods which all work. My problem is i need the arrays to be reading from the superclass LoanBook which takes in overrides from the Subclasses (Fiction and NonFiction).
As you can see from the AddBook method, it takes in details of the book and stores to an array list.
My Question :
I need to add the option Fiction or Non-Fiction but i need the arraylist take take property's from the Superclass and SubClasses. Can i get some help please.
Im happy to answer any questions you may have or provide more information.
Main Class
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
import java.util.Scanner;
public class Main{
static Scanner keyboard = new Scanner(System.in);
static boolean run = true;
static Formatter x;
public static void main(String[]args){
LoanBook myBook = new LoanBook();
while (run){ // this while statement allows the menu to come up again
int answer = 0;
boolean isNumber;
do{ // start of validation
System.out.println("1. Add book");
System.out.println("2. Display the books available for loan");
System.out.println("3. Display the books currently on loan");
System.out.println("4. Make a book loan");
System.out.println("5. Return book ");
System.out.println("6 Write book details to file");
if (keyboard.hasNextInt()){ // I need to consider putting in a =>1 <=6
answer = keyboard.nextInt();
isNumber = true;
} else {
System.out.print(" You must enter a number from the menu to continue. \n");
isNumber = false;
keyboard.next(); // clears keyboard
}
}
while (!(isNumber));
switch (answer){
case 1:
addBook();
break;
case 2:
viewAll();
break;
case 3:
booksOnLoan();
break;
case 4:
loanBook();
break;
case 5:
returnBook();
break;
case 6:
writeToFile();
break;
case 7:
break;
}
}
}
static List<String>pupilName = new ArrayList<String>();
static List<String>issueDate = new ArrayList<String>();
static List<String>bookTitle = new ArrayList<String>();
static List<String>bookAuthor = new ArrayList<String>();
static List bookOnloan = new ArrayList<Boolean>();
public static void viewAll(){
System.out.println("\n");
for (int x = 0; x < bookTitle.size();x++){
int counter = x+1;
System.out.println("BookID:" +counter + "\n " + bookTitle.get(x) + " - " + bookAuthor.get(x)+" " + bookOnloan.get(x));
}
}
public static void booksOnLoan(){
System.out.println("\n");
for (int x = 0; x < pupilName.size();x++){
if (bookOnloan.contains(true)){
int counter = x+1;
System.out.println("BookID:" +counter + "\n "+"Pupil name: " + pupilName.get(x)
+"\n Book Title: "+ bookTitle.get(x) + " by " + bookAuthor.get(x)+" " + bookOnloan.get(x)+ "\n Issued: "+ issueDate.get(x)) ;
}
}
}
public static void addBook(){
System.out.println("Please enter the book title: ");
String newTitle = keyboard.next();
bookTitle.add(newTitle);
System.out.println("Please enter the book author");
String newAuthor = keyboard.next();
bookAuthor.add(newAuthor);
bookOnloan.add(false);
System.out.println("\n Your book: "+ bookTitle.get(bookTitle.size()-1)+ " has been added to the library" + "\n");
}
public static void loanBook(){
viewAll();
System.out.println("Please choose the BookID you would like to issue: ");
int issue = keyboard.nextInt()-1;
if (issue > 10){
System.out.println("Invalid book selection");
}
else {
bookOnloan.set(issue,true);
System.out.println("Please enter pupil name: ");
String newPupil = keyboard.next();
pupilName.add(newPupil);
System.out.println("Please enter date of issue: ");
String newIssue = keyboard.next();
issueDate.add(newIssue);
}
}
public static void returnBook(){
// booksOnLoan();
System.out.println("Please choose the BookID you would like to return: ");
int issue = keyboard.nextInt()-1;
if (issue > 10){
System.out.println("Invalid book selection");
}
else {
bookOnloan.set(issue,false);
Next is my Superclass
public class LoanBook {
private int bookID;
private String title,author,name,date;
boolean onLoan;
private static int count = 0;
static List<String> bookTitle = new ArrayList<String>();
static List<String>bookAuthor = new ArrayList<String>();
static List<String> pupilName = new ArrayList<String>();
static List<String>issueDate = new ArrayList<String>();
static List bookOnloan = new ArrayList<Boolean>();
public LoanBook(String title,String author){ //constructor
this.bookID = count;
this.author = author;
this.title = title;
bookOnloan.add(false);
count++;
}
public void setTitle(String title){
bookTitle.set(1,title);
}
public String getTitle(){
return bookTitle.toString();
}
public void setAuthor(String author){
bookTitle.set(1,author);
}
public String getAuthor(){
return bookAuthor.toString();
}
public String getName(){
return pupilName.toString();
}
public void setName(String name){
pupilName.set(1,name);
}
public String getDate(){
return issueDate.toString();
}
public void setDate(String date){
issueDate.set(1,date);
}
public Boolean getOnloan(){
return bookOnloan.add(false);
}
public void setOnLoan(Boolean onLoan){
bookOnloan.add(false);
}
}
Next my subclasses
public class Fiction extends LoanBook {
private String type;
public Fiction(){
}
public Fiction(String title,String author, String type){
super(title,author); //calls constructor of the superclass
this.type = type;
}
public void setType(String type){
type = "Fiction";
}
public String getType(){
return type;
}
public String toString(){
return super.toString() + " The book type is: " + getType()+"\n";
}
}
and the other subclasss
public class NonFiction extends LoanBook {
private String type;
public NonFiction(){
}
public NonFiction(String title,String author, String type){
super(title,author); //calls constructor of the superclass
this.type = type;
}
public void setType(String type){
type = "Fiction";
}
public String getType(){
return type;
}
public String toString(){
return super.toString() + " The book type is: " + getType()+"\n";
}
}

Your whole program structure is broken from your over-use of static fields to your mis-use of inheritance, to your combining the concepts of a Book and a Book collection all in one class.
Suggestions:
Don't mix your Book class with your Book collection. This looks to be the primary problem with your code.
Start with just a Book class. It should contain no lists at all.
You can have FictionBook and NonFictionBook extend Book if so desired.
Or you could simply give Book a boolean field, fiction, and set it to true or false depending on the needs.
Create a LoanBook class that holds List of Books.
Don't use inheritance unless a true "is-a" relationship exists. Your code does not satisfy this mainly due to your first problem, your mixing your Book class together with your Book Library code, which forces your Fiction book and your non-Fiction book to inherit library code which is not only not needed, but really detrimental.
Avoid use of static anythings, unless they are there for a specific static purpose.
You will likely be best served by trashing your current code and re-starting over.

Related

Why is my stack.get(stack.size-1) not working in my code?

My return stack.get(stack.size-1).getBookName() in my adt class is not working. The line of code is in pop. Whenever I run it and want to remove something from the very top of the stack, it removes the correct thing but doesn't return the correct book removed. Is it the .getBookName() part that is wrong? Please help!
//main class
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner scan=new Scanner (System.in);
Scanner scanString= new Scanner(System.in);
int menuInput=0;
String bookName;
int pages;
String author;
ADT stack=new ADT ();
while(menuInput!=6)
{//menu
System.out.println("1. Add an book to the stack");
System.out.println("2. Remove an book from the stack");
System.out.println("3. Return the top book");
System.out.println("4. Return the length of the stack");
System.out.println("5. Return if the list is empty");
System.out.println("6. Exit");
menuInput=scan.nextInt();
if (menuInput==1)
{
System.out.println("What book do you want to add?");
bookName=scanString.nextLine();
System.out.println("How many pages are in the book?");
pages=scan.nextInt();
System.out.println("Who is the author of the book?");
author=scanString.nextLine();
stack.push(bookName, pages, author);
}
if (menuInput==2)
{
System.out.println(stack.pop());
}
if (menuInput==3)
{
System.out.println(stack.peek());
}
if (menuInput==4)
{
System.out.println(stack.length());
}
if (menuInput==5)
{
System.out.println(stack.isEmpty());
}
}
}
}
//adt class
import java.util.*;
public class ADT { //ADT stands for Abstract Data Type
String piece;
ArrayList <Book> stack = new ArrayList<Book>();
public ADT(){
ArrayList <Book> stack = new ArrayList<Book>();
}
public ADT(Book b){
ArrayList <Book> stack = new ArrayList<Book>();
stack.add(b);
}
public void push(String bN,int pg, String aut)
{
Book one=new Book(bN,pg,aut);
stack.add(one);
}
public String pop()
{
stack.remove(stack.size()-1);
return "Book removed: " + stack.get(stack.size()-1).getBookName();
}
public String peek()
{
return "First book of the stack: " + stack.get(stack.size()-1).getBookName();
}
public int length()
{
return stack.size();
}
public boolean isEmpty()
{
if (stack.size()==0)
return true;
else
return false;
}
}
//book class
public class Book{
private String bookName;
//name of the book
private int pages;
//pages in the book
private String author;
//author of the book
public Book(String bN,int pg, String aut)//bN=book name, pg=pages, aut=author
{
bookName=bN;
pages=pg;
author=aut;
}
public String getBookName()
{
return bookName;
}
}
You're calling get() after remove(), so it's returning the next last book. If you want the removed book, just use the return value of remove():
public String pop() {
return "Book removed: " + stack.remove(stack.size()-1).getBookName();
}
The reason this doesn't work is that you're removing the object from the stack, then trying to find it still in the stack. That is, you're calling remove correctly, but then you're calling get on the same stack, which is going to return the next available element if there is one.
Fortunately, the remove method actually returns the object that it removed. So you could write something like
public String pop()
{
Book removedBook = stack.remove(stack.size()-1);
return "Book removed: " + removedBook.getBookName();
}

Exception thrown while calling scanner more than once. "Exception in thread main" java.util.NoSuchElementException: No line found"

I am pretty new at Java and am just learning so please be kind.
I am doing a coding Inheritance challenge and I'm trying to use user inputs to set up a car before driving.
When I call the 2 methods I am using to set the parameters with Scanner this first method testCar.drivingTest() works fine, however when testCar.carAgeType() is called, I get an exception.
Below are the requests and inputs as well as the exception.
Would you like to test a used car today? : y or n
y
great , do you have a driving licence :type: big, medium or small
big
Great you passed your 'big' exam. Lets check the MOT : type: pass or fail
pass
What type of car were you looking for :type: sports , town or 4X4
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at learning.java.Car.carAgeType(Car.java:30)
at learning.java.Main.main(Main.java:17)
Process finished with exit code 1
From what I can gather searching google most people use .hasNextLine() to check something but I don't know what to do or why this is coming back as false on testCar.carAgeType. both methods use basically the same code and when I call only one of the methods testCar.carAgeType or testCar.drivingTest they work fine when on there own but when called one after the other I get the exception. I am also unsure what to do when I use .hasNextLine and it comes back false.
Can anyone help me understand why Scanner throws an exception when it is called in multiple methods?
All help is much appreciated, thanks.
Code sample bellow has main and 2 classes, Vehicle parent and car child
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner (System.in);
System.out.println("Would you like to test a used car today? : y or n");
if ("y".equals(scanner.nextLine())){
while (true) {
Car testCar = new Car();
testCar.drivingTest();
testCar.carAgeType();
break;
}
}else{
System.out.println("dang");
}
scanner.close();
}
}
import java.util.Scanner;
public class Vehicle {
private String licence, MOT;
public Vehicle(){
this("null", "null");
}
public Vehicle(String licence, String MOT) {
this.licence = licence;
this.MOT = MOT;
}
public String getLicence() {
return licence;
}
public String getMOT() {
return MOT;
}
public void drivingTest(){
Scanner DTScan = new Scanner (System.in);
System.out.println("great , do you have a driving licence :type: big, medium or small");
String reply = DTScan.nextLine();
if ("big".equals(reply) || "medium".equals(reply) || "small".equals(reply)) {
this.licence = reply;
} else {
this.licence = "fail";
}
System.out.println("Great you passed your '" + licence + "' exam. Lets check the MOT : type: pass or fail");
reply = DTScan.nextLine();
if ("pass".equals(reply) || "fail".equals(reply)) {
this.MOT = reply;
} else {
this.MOT = "invalid";
}
DTScan.close();
}
}
import java.util.Scanner;
public class Car extends Vehicle{
private String type;
private int age;
public Car(){
}
public Car(String licence, String MOT, String type, int age) {
super(licence, MOT);
this.type = type;
this.age = age;
}
public String getType() {
return type;
}
public int getAge() {
return age;
}
public void carAgeType(){
Scanner ATScan = new Scanner (System.in);
System.out.println("What type of car were you looking for :type: sports , town or 4X4");
ATScan.nextLine();
String reply = ATScan.nextLine();
if ("sports".equals(reply) || "town".equals(reply) || "4X4".equals(reply)) {
this.type = reply;
} else {
this.type = "invalid";
}
System.out.println("And what sort of Age :type: between 1 and 10");
int years = ATScan.nextInt();
if (years > 0 && years < 10) {
this.age = years;
} else {
this.age = -1;
}
ATScan.close();
}
}
class Main34 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Would you like to test a used car today? : y or n");
String val = scanner.nextLine();
if ("y".equals(val)) {
while (true) {
Car testCar = new Car();
testCar.drivingTest(scanner);
testCar.carAgeType(scanner);
break;
}
} else {
System.out.println("dang");
}
scanner.close();
}
}
class Vehicle {
private String licence, MOT;
public Vehicle() {
this("null", "null");
}
public Vehicle(String licence, String MOT) {
this.licence = licence;
this.MOT = MOT;
}
public String getLicence() {
return licence;
}
public String getMOT() {
return MOT;
}
public void drivingTest(Scanner scanner) {
System.out.println("great , do you have a driving licence :type: big, medium or small");
String reply = scanner.nextLine();
if ("big".equals(reply) || "medium".equals(reply) || "small".equals(reply)) {
this.licence = reply;
} else {
this.licence = "fail";
}
System.out.println("Great you passed your '" + licence + "' exam. Lets check the MOT : type: pass or fail");
reply = scanner.nextLine();
if ("pass".equals(reply) || "fail".equals(reply)) {
this.MOT = reply;
} else {
this.MOT = "invalid";
}
}
}
class Car extends Vehicle {
private String type;
private int age;
public Car() {
}
public Car(String licence, String MOT, String type, int age) {
super(licence, MOT);
this.type = type;
this.age = age;
}
public String getType() {
return type;
}
public int getAge() {
return age;
}
public void carAgeType(Scanner scanner) {
System.out.println("Enter age");
System.out.println("What type of car were you looking for :type: sports , town or 4X4");
String reply = scanner.next();
if ("sports".equals(reply) || "town".equals(reply) || "4X4".equals(reply)) {
this.type = reply;
} else {
this.type = "invalid";
}
System.out.println("And what sort of Age :type: between 1 and 10");
int years = scanner.nextInt();
if (years > 0 && years < 10) {
this.age = years;
} else {
this.age = -1;
}
}
}
Instead of creating Scanner object for every call, you just need to pass your existing scanner object to method.
Also instead of directly checking if ("y".equals(scanner.nextLine())) , you need to check using some variable like this if ("y".equals(val))
Try above code, it will work fine.
The problem comes from the fact that you use Scanner with System.in (which is a static InputStream). Whenever you call close() on a Scanner, it will automatically close the underlying InputStream, in this case System.in. Once System.in is closed, no other Scanner can read from it.
The solution to that problem is to don't close the Scanner in each of the functions and only do that in the main method.
From the Oracle documentation on the Scanner class:
When a Scanner is closed, it will close its input source if the source implements the Closeable interface.
This means that when your first method closes the scanner, it closes also the input (System.in) and that's why you get the exception and also why calling only one method doesn't throw the exception.
Just close only the first scanner you have in your main and it should solve your issue.

validate private variable of another class when giving input

hello I have written code where it takes book details using setter method and displaying details using getter method. When user enters the input it has to enter three details.
Book NameBook PriceAuthor Name
I want to check if user has given any negative value or Zero value in Book Price.
How do I do that? Below is the code. I am practicing Encapsulation problem
//Book.java file
class Book
{
private String bookName;
private int bookPrice;
private String authorName;
public String getBookName()
{
return bookName;
}
public int getBookPrice()
{
return bookPrice;
}
public String getAuthorName()
{
return authorName;
}
public void setBookName(String a)
{
bookName=a;
}
public void setBookPrice(int b)
{
bookPrice=b;
}
public void setAuthorName(String c)
{
authorName=c;
}
}
//TestBook.java file
import java.util.*;
class TestBook
{
public static void main(String args[])
{
Book bobj = new Book();
Scanner sc = new Scanner(System.in);
try
{
System.out.println("Enter the Book name:");
bobj.setBookName(sc.nextLine());
System.out.println("Enter the price:");
bobj.setBookPrice(sc.nextInt());
sc.nextLine();
System.out.println("Enter the Author name:");
bobj.setAuthorName(sc.nextLine());
System.out.println();
System.out.println("Book Details");
System.out.println("Book Name :"+bobj.getBookName());
System.out.println("Book Price :"+bobj.getBookPrice());//should not be -ve or 0
System.out.println("Author Name :"+bobj.getAuthorName());
}
catch(Exception e)
{
System.out.println("Invalid Input");
}
}
}
You should put this check in your setter method to check if it is greater than zero. For example:
public void setBookPrice(int b)
{
if(b>0)
bookPrice=b;
else
{
throw new IllegalArgumentException("b must be positive")
}
}
Above code will prevent setting of negative and zero price. You can replace exception throwing code with your own handling.
If you are practising encapsulation I suggest creating a specific validation method for the price so this can be easily modified without changing the public interface.
public boolean isValidPrice() {
return bookPrice > 0;
}
This can now be checked with
if (!bobj.isValidPrice()) {
//error handling
}
And if the validation rules for price would change the calling code will remain unchaged

Understanding ArrayLists and Objects

Let's suppose I've the following Class Product:
public class Product {
// Variables.
private String name; // Name
private Double price; // Price
Product() {} // Default constructor with no parameters.
Product(String name, Double price) { // Constructor with parameters.
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price= price;
}
public String toString() { // Overriding "toString()".
return "\nName: " + this.name + "\nPrice: " + this.price;
}
public boolean equals(Object obj) { // Overriding equals()
if(this == obj) {
return true;
}
if(obj == null || obj.getClass() != this.getClass()) {
return false;
}
Product product = (Product) obj;
return this.name.equals(product.name)&& this.price.equals(product.price);
}
}
Now, let's suppose I've an ArrayList in my Main.class and my Main looks something like this:
import java.util.*;
import java.io.*;
public class Main {
private static BufferedReader r = new BufferedReader (new InputStreamReader(System.in));
private static String readln() throws IOException{
return r.readLine();
}
private static long readInput() throws IOException{ // Use this to read input for the menu options.
return Integer.valueOf(readln());
}
public static void menu(){ // Menu
System.out.println("-------------------------" +
"\nAdd new product(1)" +
"\nSearch for product(2)" +
"\nDelete product(3)" +
"\nShow all products(4)" +
"\nReturn the number of products(5)" +
"\nExit(-1)" +
"\n-------------------------");
}
public static void main (String args[]) throws IOException{
// This is the ArrayList for the "Product".
ArrayList<Product> products = new ArrayList<Product>();
int option = 0;
do {
menu();
option = (int)readInput();
switch (option){
case 1:{
System.out.println("Insert product name: ");
String name= readln();
System.out.println("Insert product price: ");
Double price = Double.parseDouble(readln());
products.add(new Product(name, price));
break;
}
case 2:{
System.out.println("Insert product name: ");
String name= readln();
System.out.println("Insert product price: ");
Double price= Double.parseDouble(readln());
if ((products.contains(new Product (name, price)))){
System.out.println("Works!");
}
break;
}
case 3:{
break;
}
case 4:{
break;
}
case 5:{
System.out.println("Number of products: " + products.size());
//This prints with no problems, therefor the objects DO exist in the ArrayList.
break;
}
}
}while((option > 0) && (option < 6));
}
}
According to this in order to insert an object into an ArrayList you need to write it like this "ArrayListName.add(new ObjectName(param1, param2));" or you can create an object called object1 and then add it with ArrayListName.add(object1); In my case, from what I understand, I'm inserting objects into the ArrayList but those objects do not really exist, because if I tried to use the overridden toString() method, it does not print anything. If my understanding is wrong, why does it not print anything? According to this, my method is correct.
If I've understood this correctly, objects do not need a variable to point to them, but if you've directly inserted them into an ArrayList, like I have, how are you supposed to get the index position of an object? Because the equals() in my case, compares objects, so you can't use it to search the ArrayList. Nor can you try something like "products.contains(name, price);" because, .contains() uses equals().
I was also thinking of doing something like this, but it's only useful if you want to create a new Class and not an object like product1, in my case. I gave up on it as well because forName() kept saying that it can't find the Class for some reason that I could not find out why.
What about the "Delete" option? Would it work the same way as the "Search" one?
Edit: for the equals() the last line, you can also put:
if( (this.price.equals(product.getPrice())) && (this.name.equals(product.getName())) ) {
return true;
}
To make it work you should also rewrite your equals method to compere fields inside people object overriding equals method
There could be a bug in your parametrized constructor. It should looks like:
Product(final String name, final Double price) { // Constructor with parameters.
this.name = name;
this.price = price;
}
Final word prevent us to change value of incoming parameter.
According to the article above the implementation should be
#Override
public boolean equals(Object obj) { // Overriding "equals()".
// at first check if objects are the same -> your code
if (this == obj) {
return true;
}
// secondly we chack if objects are instances of the same class if not return false
if (obj != null && this.getClass() != obj.getClass()) {
return false;
}
// then compare objects fields. If fields have the same values we can say that objects are equal.
Product product = (Product) obj;
return this.name.equals(product.name) && this.price.equals(product.price);
}
To handle nulls in fields we can write additional checks.
With new implementation of equals method to search for the element on the list you can pass new instance of product to contains mathod
instead of doing
products.contains(name, price);
try
products.contains(new Product(name, price))
To delete element from the list you can first find index of element and the use remove method.
products.remove(products.indexOf(new Product(name, price)))
Actually, this is not good example to understand of working with ArrayList. First of all, this collection is not good for product list. Yes, you could use it, but Map is much better. I do not think, that you're learning Java. If so, I prefer to use Map instead of List.
Moreover, I recommend to avoid using option numbers. Use named constants as minimum, but using OOP is much better. E.g. you could use enum where each element is one menu option.
E.g. like below.
public class Main {
public static void main(String... args) {
List<Product> products = readProducts();
// final list of products
}
private static List<Product> readProducts() {
Map<String, Product> products = new LinkedHashMap<>();
try (Scanner scan = new Scanner(System.in)) {
while (true) {
MenuItem.show();
MenuItem menuItem = MenuItem.parseOption(scan.nextInt());
if (menuItem == MenuItem.EXIT)
break;
menuItem.action(products, scan);
}
}
return products.isEmpty() ? Collections.emptyList() : new ArrayList<>(products.values());
}
private enum MenuItem {
ADD_NEW_PRODUCT(1, "Add new product") {
#Override
public void action(Map<String, Product> products, Scanner scan) {
System.out.println("Insert product name: ");
String name = scan.next();
System.out.println("Insert product price: ");
double price = scan.nextDouble();
if (products.containsKey(name))
products.get(name).setPrice(price);
else
products.put(name, new Product(name, price));
}
},
SEARCH_FOR_PRODUCT(2, "Search for product"),
DELETE_PRODUCT(3, "Delete product") {
#Override
public void action(Map<String, Product> products, Scanner scan) {
System.out.println("Insert product name: ");
String name = scan.next();
products.remove(name);
}
},
SHOW_ALL_PRODUCTS(4, "Show all products"),
RETURN_THE_NUMBER_OF_PRODUCTS(5, "Return the number of products") {
#Override
public void action(Map<String, Product> products, Scanner scan) {
System.out.println("Number of products: " + products.size());
}
},
EXIT(-1, "Exit");
private final int option;
private final String title;
MenuItem(int option, String title) {
this.option = option;
this.title = title;
}
public void action(Map<String, Product> products, Scanner scan) {
}
public static MenuItem parseOption(int option) {
for (MenuItem menuItem : values())
if (menuItem.option == option)
return menuItem;
return EXIT;
}
public static void show() {
System.out.println("-------------------------");
for (MenuItem menuItem : values())
System.out.printf("%s(%d)\n", menuItem.title, menuItem.option);
System.out.println("-------------------------");
}
}
}

Do I need multiple ArrayLists for this program?

I have to make a program that reads in a file of favorites, such as favorite animals. So say it reads in a file that says "Dog, Cat, Fox", 1 on each line. Those are then put into an Arraylist. After the user is prompted to either add or remove any, they are then asked to rank them. Heres where I'm confused- To reorder/rank the lines of the arraylist, would I need a second ArrayList to put the ranking into? Also, after they are ranked, they are asked to add a comment for each one, such as for cats-"I'm allergic to cats" or something like that. Would I need a 3rd Array list for these comments? Heres a sample output-
‘Favorite’ | Rank | Comments from this round (plus all previous comments)
Heres my code right now if you kind of wanna see where I'm going- it doesnt all work but you'll get the gist of it
Scanner input = new Scanner(System.in);
ArrayList <String> favoriteAnimals = new ArrayList <String>();
boolean repeat = true;
while (repeat) {
System.out.println("Enter the name of the file which contains your favorite animals ");
String fileName = input.nextLine().trim();
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
System.out.println("Here are your favorite animals according to the file:");
while ((line = reader.readLine()) != null) {
System.out.println(line);
favoriteAnimals.add((line));
}
System.out.println("Add more? (y/n)");
if (input.next().startsWith("y")) {
System.out.println("Enter : ");
favoriteAnimals.add(input.next());
} else {
break;
}
for (int i = 0; i < favoriteAnimals.size(); i++) {
System.out.println(favoriteAnimals);
}
System.out.println("Remove an animal?");
if (input.next().startsWith("y")) {
System.out.println("Which animal would you like to remove");
String removeAnimal = input.nextLine();
int index = favoriteAnimal.indexOf(removeAnimal);
favoriteAnimals.remove(index);
System.out.println(favoriteAnimals);
}
else {
break;
}
ArrayList <String> ranking = new ArrayList <String>();
int size = favoriteAnimals.size();
String first = favoriteAnimals.get(0);
System.out.println("What is your ranking of " + first + " out of " + size +"?");
}
catch (IOException ex) {
System.err.println("Your file does not exist!: " + ex.getLocalizedMessage());
repeat = true;
}
}
}
}
In all likelihood, you are supposed to write a small class Animal with fields like String name, String comment, etc. and then have an ArrayList<Animal>.
If you are familiar with Object Oriented OO, Then it is recommended to use classes to encapsulate the data structure you have, I wrote a simple example and I hope it will help you to solve the problem:
Animal class
package com.stackoverflow.q1;
import java.util.ArrayList;
import java.util.List;
public class Animal {
private String name;
private Integer rank;
private List<String> comments=new ArrayList<String>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRank() {
return rank;
}
public void setRank(Integer rank) {
this.rank = rank;
}
public List<String> getComments() {
return comments;
}
public void setComments(List<String> comments) {
this.comments = comments;
}
#Override
public String toString() {
return "Animal [name=" + name + ", rank=" + rank + ", comments="
+ comments + "]";
}
}
Main class
package com.stackoverflow.q1;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Animal> animals= new ArrayList<Animal>();
Animal dog=new Animal();
dog.setName("dog");
dog.setRank(1);
dog.getComments().add("Comment 1");
Animal horse=new Animal();
horse.setName("horse");
horse.setRank(2);
horse.getComments().add("Comment 1");
Animal cow=new Animal();
cow.setName("cow");
cow.setRank(1);
cow.getComments().add("Comment 1");
animals.add(dog);
animals.add(horse);
animals.add(cow);
for(Animal animal:animals){
System.out.println(animal);
}
}
}

Categories