Do I need multiple ArrayLists for this program? - java

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);
}
}
}

Related

How would I make a loop in java that will ask the user to pick a class from the array list and if they enter an invalid value to ask again?

My code:
import java.util.Scanner;
public class PartyTest {
public static void main(String[] args) {
Party party = new Party();
String[] classNames = {"theif","warrior","wizard","steve","bard"};
Hero Carmilla = new Hero("Carmilla");
Hero Alucard = new Hero("Alucard");
Hero Steve = new Hero("steve");
Hero Sypha = new Hero("sypha");
System.out.println("The avaliable classes are:\n" );
for(int i = 0; i < classNames.length; i++) {
System.out.println(classNames[i]);
}
Scanner ask = new Scanner(System.in);
System.out.println("Enter the class for Carmilla\n");
String nameC = ask.next();
Boolean temp;
I was attempting to do a while loop but I was not sure what conditions to use
while(temp = true) {
if(nameC.equalsIgnoreCase("theif")) {
Carmilla.sethClass(nameC);
temp = false;;
break;
} else {
System.out.println("Invalid class try again");
}
}
System.out.println(Carmilla);
Hero class just sets the values for everything, I would use (depending on the name of the person I'm calling) `Carmilla.sethClass(nameC)', which just sets the name of the chosen class to the hero class.
I want to ask the user what class they would like to set for each person(they are the names stated with Hero in front of them)and if the user does not type one of the classNames value then they are told that its an invalid statement and to try again, which will then ask again what class they want for (in this example) Carmilla.
Here is one way to accomplish it.
The class with main method is below. A few notes about it. First, I made the Party class just an ArrayList of Hero objects, since I'm assuming that a party is just a collection of heroes. This makes asking names for each of the four heroes easier because we can loop through the party list.
Next, I moved the instantiation of the Hero objects into the initialization of the party so that the list already contains our Hero objects.
I utilized a for-each loop to check and assign classes to each Hero and a while loop to redirect the user back if they entered an invalid class. I check whether the class is valid using the boolean validClass. The final output of running this is shown at the very bottom.
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class PartyTest {
public static void main(String[] args) {
List<Hero> party = Arrays.asList(new Hero("Carmilla"),
new Hero("Alucard"),
new Hero("steve"),
new Hero("sypha"));
String[] classNames = { "theif", "warrior", "wizard", "steve", "bard" };
Scanner ask = new Scanner(System.in);
for (Hero hero : party) {
if (hero.getHclass()
.equals("Default")) {
boolean validClass = false;
while (!validClass) {
System.out.println("Enter the class for " + hero.getName());
String hClass = ask.nextLine();
for (String name : classNames) {
if (hClass.equals(name)) {
validClass = true;
}
}
if (validClass) {
hero.setHclass(hClass);
}
}
}
}
party.forEach(hero -> {
System.out.println(hero.getName() + " has class " + hero.getHclass());
});
}
}
The Hero class:
public class Hero {
private String name;
private String hclass = "Default";
public Hero(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHclass() {
return hclass;
}
public void setHclass(String hclass) {
this.hclass = hclass;
}
}
Output:
Use for-each loop to match the entered name against the classNames
Code:
import java.util.Scanner;
import java.io.*;
//Hero class replace with your class
class Hero{
String name="";
String className="";
public Hero(){}
public Hero(String name){
this.name=name;
}
public void sethClass(String className){
this.className=className;
}
#Override
public String toString(){
return "Name : "+name+" className : "+className;
}
}
public class PartyTest {
public static void main(String[] args) throws IOException{
//Party party = new Party();
String[] classNames = {"theif","warrior","wizard","steve","bard"};
Hero Carmilla = new Hero("Carmilla");
Hero Alucard = new Hero("Alucard");
Hero Steve = new Hero("steve");
Hero Sypha = new Hero("sypha");
System.out.println("The avaliable classes are:\n" );
for(int i = 0; i < classNames.length; i++) {
System.out.println(classNames[i]);
}
//Scanner ask = new Scanner(System.in);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the class for Carmilla\n");
boolean matched=false;
while(!matched) {
String nameC = br.readLine();
//Use for-each loop to match the entered name
for(String name : classNames){
if(nameC.equalsIgnoreCase(name)) {
Carmilla.sethClass(nameC);
matched=true;//Matched
break;
}
}
if(matched)break;
System.out.println("Invalid class try again\n");
}
System.out.println(Carmilla);
}
}
OUTPUT:
$ javac PartyTest.java && java PartyTest
The avaliable classes are:
theif
warrior
wizard
steve
bard
Enter the class for Carmilla
blaba
Invalid class try again
qwertr
Invalid class try again
Wizard
Name : Carmilla className : Wizard

Getting incompatible error for parent child classes java

I have a HashMap defined:
HashMap<String,ArrayList<Thing>> hashmap = new HashMap<>();
I do need an ArrayList since I want one key to have multiple values. This was the best solution I found for that problem.
The Thing class is a parent class for a bunch of other classes. Problem is when I try to add I get an error.
hashmap.put(b, world.ports);
This is the error:
no suitable method found for put(String,ArrayList<SeaPort>)
method Map.put(String,ArrayList<Thing>) is not applicable
(argument mismatch; ArrayList<SeaPort> cannot be converted to ArrayList<Thing>)
method AbstractMap.put(String,ArrayList<Thing>) is not applicable
(argument mismatch; ArrayList<SeaPort> cannot be converted to ArrayList<Thing>)
method HashMap.put(String,ArrayList<Thing>) is not applicable
(argument mismatch; ArrayList<SeaPort> cannot be converted to ArrayList<Thing>)
`
I dont understand this since SeaPort extends Thing isn't it supposed to be compatible? I have read a bunch of upcasting and downcasting threads but I don't see how they apply here.
Here is the Thing class:
package seaportprogram;
import java.util.Scanner;
public class Thing implements Comparable<Thing>{
String name;
int index;
int parent;
World world;
public Thing(){
name = null;
index = 0;
parent =0;
}
//Thing Scanner Constructor
public Thing (Scanner sc){
if(sc != null){
name = sc.next();
index = sc.nextInt();
parent = sc.nextInt();
}
}
// Get Index
public int getIndex(){
return index;
}
//Get Name
public String getName(){
return name;
}
//Get Parent
public int getParent(){
return parent;
}
//Thing To String
public String toString(){
return name + " " + index;
}
//Auto-Gen Compare Method
#Override
public int compareTo(Thing o) {
// TODO Auto-generated method stub
return 0;
}
}//End - Class Thing
Here is the SeaPort class:
package seaportprogram;
import java.util.ArrayList;
import java.util.Scanner;
class SeaPort extends Thing {
ArrayList<Dock> docks;
ArrayList<Ship> que;
ArrayList<Ship> ships;
ArrayList<Person> persons;
//Sea Port Scanner Constructor
public SeaPort(Scanner sc){
super(sc);
docks = new ArrayList<>();
que = new ArrayList<>();
ships = new ArrayList<>();
persons = new ArrayList<>();
}
//Set Docks
public void setDocks(ArrayList<Dock> docks){
this.docks = docks;
}
//Get Docks
public ArrayList<Dock> getDocks(){
return docks;
}
//Set Ships
public void setShips(ArrayList<Ship> ships){
this.ships = ships;
}
//Get Ships
public ArrayList<Ship> getShips(){
return ships;
}
//Set Que
public void setQue(ArrayList<Ship> que){
this.que = que;
}
//Get Que
public ArrayList<Ship> getQue(){
return que;
}
//Sea Port To String
public String toString(){
String string = "\n\n Sea Port: " + super.toString() + "\n";
for(Dock md: docks){
string += "\n" + md + "\n";
}
string += "\n\n --- List of all ships in Que: ";
for(Ship ms: que){
string += "\n > " + ms;
}
string += "\n\n --- List of all Ships:";
for(Ship ms: ships){
string += "\n > " + ms;
}
string += "\n\n --- List of all Persons:";
for(Person mp: persons){
string += "\n > " + mp;
}
return string;
}//End
}// End Sea Port Class
This is World class:
package seaportprogram;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
public class World extends Thing{
ArrayList<SeaPort> ports;
PortTime time;
//World Scanner Constructor
public World(Scanner sc){
super (sc);
ports = new ArrayList<>();
}
//Set Ports
}
Any way to make this happen?
TIA!
update:
I am trying to print the map and I get an null pointer exception. I think this is because the list is being initialized both in seaport and in the MyHashMap class. I cant seem to find a way to get around this and I'm not even sure this is the reason for the error. Here is the toString():
public String toString(){
if(map.isEmpty())
{
System.out.println("The hashMap is empty");
return "empty";
}
String display=" ";
Iterator<String> itr = map.keySet().iterator();
while (itr.hasNext()) {
display =display + itr.next();
Iterator<ArrayList<T>> itr2 = map.values().iterator();
while (itr2.hasNext()) {
display +=itr2.next();
}
}
return display;
}
and this is the call to it from the gui:
jta.setText(map.toString());
ArrayList<Derived_Class> does not extend ArrayList<Base_Class>.
If you want to use an HashMap like this, one solution could be to write your own wrapper class using templates:
import java.util.ArrayList;
import java.util.HashMap;
public class MyHashMap<T extends Thing> {
private HashMap<String, ArrayList<T>> map;
public MyHashMap() {
map = new HashMap<>();
}
public void add(String s, T element) {
ArrayList<T> list = null;
if ((list = map.get(s)) == null)
map.put(s, list = new ArrayList<T>());
list.add(element);
}
public ArrayList<T> get(String s) {
return map.get(s);
}
}
if you want an HashMap of SeaPorts, you can create a new HashMap like this,
MyHashMap<SeaPort> map = new MyHashMap<SeaPort>();
and use custom setters and getters to access the arraylists
Seaport may extend Thing, but ArrayList<SeaPort> does not extend ArrayList<Thing>.
If you just want to store a map of Strings to Things, you don't need ArrayList. If you really want to map Strings to Lists of Things, then you can't do it like this.

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("-------------------------");
}
}
}

Writing data from a List field to a .txt file in Java

I have just completed the following program -
//interface IFile
package zad;
public interface IFile {
void readFromFile();
}
//class Student
package zad;
public class Student implements Comparable {
private String studentName;
private int facNum, studentPoints;
public Student(int facNum, String studentName, int studentPoints) {
this.facNum = facNum;
this.studentName = studentName;
this.studentPoints = studentPoints;
}
public void setFacNum(int facNum) {
this.facNum = facNum;
}
public int getFacNum() {
return facNum;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentName() {
return studentName;
}
public void setStudentPoints(int studentPoints) {
this.studentPoints = studentPoints;
}
public int getStudentPoints() {
return studentPoints;
}
public boolean equals(Object o) {
if(o instanceof Student && ((Student) o).getFacNum() == this.facNum) {
return true;
} else {
return false;
}
}
public String toString() {
return ("FacNum = " + facNum + ", name = " + studentName
+ ", points = " + studentPoints );
}
public int compareTo(Object o) {
return Integer.compare(this.facNum, ((Student)o).getFacNum());
}
}
//class StudentsGroup
package zad;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class StudentsGroup implements IFile, Comparable {
private String groupName;
private List<Student> studentsList = new ArrayList<Student>();
public StudentsGroup(String groupName) {
this.groupName = groupName;
}
public void printArrayList() {
for(Student o : studentsList)
System.out.println(o);
}
public int compareTo(Object o) {
if(getTotalPoints(studentsList) > getTotalPoints(((StudentsGroup)o).studentsList))
return 1;
else if(getTotalPoints(studentsList) < getTotalPoints(((StudentsGroup)o).studentsList))
return -1;
else
return 0;
}
public List getList() {
return studentsList;
}
public static int getTotalPoints(List<Student> studentsList1) {
int totalPoints = 0;
for(Student o : studentsList1) {
totalPoints += o.getStudentPoints();
}
return totalPoints;
}
public void sortByPoints() {
Collections.sort(studentsList);
}
public void readFromFile() {
Scanner sc;
try {
sc = new Scanner(new File(groupName));
while(sc.hasNext()) {
int facNum = sc.nextInt();
String studentName = sc.next();
int studentPoints = sc.nextInt();
Student object = new Student(facNum, studentName, studentPoints);
studentsList.add(object);
}
sc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
public String toString() {
return "StudentsGroup [groupName=" + groupName + ", studentsList=" + studentsList + "]";
}
}
//class main
package zad;
import java.io.FileNotFoundException;
public class demo {
public static void main(String[] args) throws FileNotFoundException {
StudentsGroup studentsGroup1 = new StudentsGroup("D://test.txt");
StudentsGroup studentsGroup2 = new StudentsGroup("D://test2.txt");
studentsGroup1.readFromFile();
studentsGroup2.readFromFile();
studentsGroup1.printArrayList();
studentsGroup1.sortByPoints();
studentsGroup1.printArrayList();
int compareResult = studentsGroup1.compareTo(studentsGroup2);
switch(compareResult) {
case 0: System.out.println("The two lists are equal by points.");
break;
case 1: System.out.println("The first list is larger than the second.");
break;
case -1: System.out.println("The first list is smaller than the second.");
break;
}
}
}
In general, it makes an object from class StudentsGroup, reads from a file and adds to an ArrayList field, as objects of another class - Student.
How should I implement a method to write that data to a new file? Any thoughts on that?
Note: also, if possible, I would like some tips on my coding to help me write better code. Am I doing something completely wrong or unnecessary in my program? The method getTotalPoints needs to be declared as static, so that is not discussed.
UPDATE:
When I try to write the data to a file with the following code:
FileOutputStream out = new FileOutputStream("D://test3.txt");
ObjectOutputStream oout = new ObjectOutputStream(out);
for(Student o : studentsList)
oout.writeObject(o);
out.close();
oout.close();
I get an error:
Exception in thread "main" java.io.NotSerializableException: zad.Student
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at zad.StudentsGroup.writeToFile(StudentsGroup.java:80)
at zad.demo.main(demo.java:27)
Am I doing something wrong?
According to the documentation for ObjectOutputStream, the writeObject method throws a NotSerializableException because Students does not implement Serializable.
NotSerializableException - Some object to be serialized does not implement the java.io.Serializable interface.
Update your class signature to the following and implement any methods required by Serializable.
public class Student implements Comparable, Serializable
By using the ObjectOutputStream.writeObject method you have no control over the output. If you want to control how the content is actually output to the file you'll want to look into an alternative writer. Look into examples of using BufferedWriter. You could then pass Student.toString() to the writer and control the way in which the data shows up. For instance, your toString() method in Student could output field1 + "\t" + field2 + "\t" + field3 + "\t" + field4 - and you'd essentially have a tab-delimited file that you could then, for instance, import into Excel.

Linking array with Subclasses [closed]

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.

Categories