Adding console input to ArrayList in Java - java

I'm trying to add items from the console input and scanner input to arraylists in java.
(To run the program user types Program ID)
The problem is that each time I run the program the contents of the arraylists update to only what has been entered that time. I would like the arraylists to contain all of the inputs that have been entered.
public class User{
private static List<String> listNames = new ArrayList<String>();
private static List<Integer> listIds = new ArrayList<Integer>();
public static void main(String[] args)
{
int tempID = 5000;
if (args.length>0) tempID= Integer.parseInt(args[0]);
System.out.println("Login "+tempID);
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your Name : ");
tempName = scanner.nextLine();
User n = new User();
n.ID= tempID;
n.name = tempName;
listIds.add(n.ID);
listNames.add(n.name);
}
}
}
Does anyone know if this is possible?

Everytime you run the program it is going to initialize a different array. To solve this, you can store your data in a database such as MySQL or Oracle. But a more efficient way to solve this is that to save your ArrayList as an object locally using java.io.ObjectInputStream and java.io.ObjectOutputStream
I wrote the following 2 functions
public static ArrayList<Object> loadArrayList(String filename)
{
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(filename));
ArrayList<Object> arr = (ArrayList<Object>) ois.readObject();
return arr;
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void saveArrayList(ArrayList<Object> arr, String filename)
{
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filename));
oos.writeObject(arr);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Call saveArrayList with the first argument is your ArrayList instance and the second argument the filename. You can then load from your local file system using the loadArrayList method with the argument is your filename.
In your case, just call the saveArrayList method when your user exits the program and call the loadArrayList to get all your elements from the previous inputs to resume the user's progress

Every time you compile your program you create new Arrays. So you need another way of saving your inputs like in a SQL Database or you can run your program infinitely with a loop and ask each time for a new entry and collect it with the scanner like you already did but with that method, you can do nothing with the array entries because your asking for entries never stops.

Related

Change ArrayList from an Object to more specific type

Is it possible to change the object type of an array list i.e. from an Object ArrayList to a specific object ArrayList. I have tried using a for each. Alternatively is there a way to change the filehandling method such that it can return a specific type depending on which file it reads from without duplicating code?
My Attempt:
ArrayList<Object> librarianList = FileHandling.getLibrarianRecords(fileName);
ArrayList<Librarian> libList = new ArrayList<>();
for (Object addType: librarianList) {
libList.add(addType);
}
getLibrarianRecords code
public static ArrayList<Object> getLibrarianRecords(String filename){
ArrayList<Object> fromFile = new ArrayList<>(); //Array of
// existing librarians
try{
FileInputStream fIS =
new FileInputStream(SYSTEM_PATH + filename);
ObjectInputStream oIS = new ObjectInputStream(fIS);
fromFile = (ArrayList<Object>)oIS.readObject();
} catch (IOException ex){
System.out.println("Failed to read from file " + ex.getMessage());
ex.printStackTrace(); //Catches an IO exception.
} catch (ClassNotFoundException ex){
System.out.println("Error class not found" + ex.getMessage());
ex.printStackTrace(); //Catches a class not found
// exception.
}
return fromFile; //Returns the array list.
}
It is rarely a good idea to read objects from a file like this. That said all you really need to do is to cast the result of oIS.readObject() to an ArrayList<Librarian> instead of carrying it to ArrayList<Object> (as you do now) and then amend the return type of getLibrarianRecords. Oh, and naturally also the type of the local variable fromFile.
public static ArrayList<Librarian> getLibrarianRecords(String filename){
ArrayList<Librarian> fromFile = new ArrayList<>(); //Array of
// existing librarians
try{
FileInputStream fIS =
new FileInputStream(SYSTEM_PATH + filename);
ObjectInputStream oIS = new ObjectInputStream(fIS);
fromFile = (ArrayList<Librarian>)oIS.readObject();
} catch (IOException ex){
System.out.println("Failed to read from file " + ex.getMessage());
ex.printStackTrace(); //Catches an IO exception.
} catch (ClassNotFoundException ex){
System.out.println("Error class not found" + ex.getMessage());
ex.printStackTrace(); //Catches a class not found
// exception.
}
return fromFile; //Returns the array list.
}
There should then be no need to loop over the list to actually do the type conversion on an element by element basis.
Thanks to #user3170251 for suggesting casting
ArrayList<Object> librarianList = FileHandling.getLibrarianRecords(fileName);
ArrayList<Librarian> libList = new ArrayList<>();
for (Object addType: librarianList) {
libList.add((Librarian) addType);
}
For changing the type this does work.
You can use this generic class definition
class ArrayListConverter<T> {
List<T> cast;
public ArrayListConverter(List<T> typeList){
cast = new ArrayList<>();
for (Object addType: typeList) {
cast.add((T)addType);
}
}
public List<T> getList(){
return cast;
}
}
Just do this:
ArrayListConverter<Librarian> conv = new ArrayListConverter<>(libList);
ArrayList<Librarian> libListOg = conv.getList();

JAVA objectinputstream cant drop out from the loop

Here is the code I have:
ObjectInputStream ois = null;
UserRegistration UR = new UserRegistration();
Scanner pause = new Scanner(System.in);
Admin go = new Admin();
try {
//ItemEntry book = new ItemEntry();
ois = new ObjectInputStream(new FileInputStream("Account.txt"));
while ((UR = (UserRegistration) ois.readObject()) != null) {
//if (book.getName().equals("1"))
{
System.out.println(UR);
}
}
} catch (EOFException e) {
System.out.println("\nEnd**");
}catch (ClassNotFoundException ex) {
System.out.println(ex.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
ois.close();
System.out.println("Press \"ENTER\" to continue...");
pause.nextLine();
go.startup();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
How can I make it drop out from the loop and not to straight enter to the EOFException when it reach the last object? Help please !
This is a duplicate of this question :
Java FileInputStream ObjectInputStream reaches end of file EOF
Bottom line is that ObjectInputStream does not return null when it reaches the end of the stream. Instead, the underlying FileInputStream throws an EOFException. Although you could interpret that as the end of file, it does not allow you to distinguish a truncated file. So, practically speaking, ObjectInputStream expects you to know how many objects you will be reading in.
To get around this you could write an integer to the start of the file indicating how many UserRegistration objects are in the file. Read that value, then use a for loop to read that many objects.
Alternatively, you may be able to serialize your UserRegistration objects as an array or other container and then de-serialize the whole array/container.

Object Serialization and Deserialization using ArrayList in Java

I am trying to serialize an object array and write it to a file named address.ser and then read back from the file, deserialize the object array and display its attributes. I tried serializing the whole arrayList at once(deserializing it in a single session while reading) and also tried serializing each object of the object array one by one(deserializing it one by one while reading). The problem is, while reading back from the address.ser file I am getting data only of the last object which was written and none other.
Here is the code snippet:
Employee[] a=new Employee[5];
List<Employee> arr=new ArrayList<Employee>();
for(int i=0;i<=4;i++)
{
a[i]=new Employee();
System.out.println("Enter name,age,height,weight,house_no:");
a[i].name=sc.next();
a[i].age=sc.nextInt();
a[i].height=sc.nextDouble();
a[i].weight=sc.nextDouble();
a[i].house_no=sc.nextInt();
arr.add(a[i]);
}
This is the code snippet for writing objects to address.ser:
for(int i=0;i<=4;i++)
{
try
{
fout = new FileOutputStream("e:\\address.ser");
oos = new ObjectOutputStream(fout);
oos.writeObject(a[i]);
//oos.writeChars("\n");
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
oos.close();
fout.close();
}
}
This is the code snippet for reading objects from address.ser:
List<Employee> recordList=new ArrayList<Employee>();
for(int i=0;i<=4;i++)
{
try
{
file = new FileInputStream("e:\\address.ser");
input = new ObjectInputStream (file);
//deserialize the List
Employee readCase=(Employee) input.readObject();
recordList.add(readCase);
System.out.print("Employee "+i+" ");
System.out.print((recordList.get(i).name)+" ");
System.out.print((recordList.get(i).age)+" ");
System.out.print((recordList.get(i).height)+" ");
System.out.print((recordList.get(i).weight)+" ");
System.out.print((recordList.get(i).house_no)+" ");
System.out.println();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
file.close();
input.close();
}
}
The final output being:
This is the way to do,
public class Test {
public static void main(String[] args) {
Employee employee=new Employee("jhon");
Employee employee2=new Employee("jojo");
Employee employee3=new Employee("albin");
ArrayList<Employee> list=new ArrayList<Employee>();
list.add(employee);
list.add(employee2);
list.add(employee3);
try {
FileOutputStream outputStream=new FileOutputStream("add.ser");
ObjectOutputStream objectOutputStream= new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(list);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream inputStream=new FileInputStream("add.ser");
ObjectInputStream objectInputStream =new ObjectInputStream(inputStream);
ArrayList<Employee> list2=(ArrayList<Employee>) objectInputStream.readObject();
for (Employee employee4 : list2) {
System.out.println(employee4.getName());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
The problem is you are trying to write the object in a wrong way. You are writing each element of the ArrayList in a same file. So what is happening is a new element is replacing the old one. So write the whole List at a time liek
oos.writeObject(yourList);
Corrected Solution
You're overwriting the file for each element you attempt to serialize. Therefore, the last serialized element remains. A file of serialized data has a header, so you must write your data in one shot.
fout = new FileOutputStream("e:\\address.ser");
oos = new ObjectOutputStream(fout);
for(int i=0;i<=4;i++)
{
try
{
oos.writeObject(a[i]);
}catch(Exception e){}
}
However, it's more efficient to serialize the entire list in one shot.

Loading From File Error In Java?

I have to implement Object Files for a java project, however I am having trouble when it comes to loading the file (Save is all OK)
public static void loadStudentList() {
boolean endOfFile = false;
try {
// create a FileInputStream object, studentFile
FileInputStream studentFile = new FileInputStream("Students.obf");
// create am ObjectImnputStream object to wrap around studentStream
ObjectInputStream studentStream = new ObjectInputStream(studentFile) ;
// read the first (whole) object with the readObject method
Student tempStudent = (Student) studentStream.readObject();
while (endOfFile != true) {
try {
tempStudent = (Student) studentStream.readObject();
stud1.add(tempStudent);
}
catch(EOFException e) {
endOfFile = true;
}
}
studentStream.close();
//use the fact that the readObject throws an EOFException to check whether the end of eth file has been reached
}
catch(FileNotFoundException e) {
System.out.println("File not found");
}
catch(ClassNotFoundException e) { // thrown by readObject
/* which indicates that the object just read does not correspond to any class
known to the program */
System.out.println("Trying to read an object of an unkonown class");
}
catch(StreamCorruptedException e) { //thrown by constructor
// which indicates that the input stream given to it was not produced by an ObjectOutputStream object
System.out.println("Unreadable File Format");
}
catch(IOException e) {
System.out.println("There was a problem reading the file");
}
}
This is the code I used to load the files. The program will load ONLY the last 2 records in my file. The Idea is that I load all of them to an array list for future use in the program. Also I am not getting any of my catches back. Any help? Thanks :)
You never add to the list the first Student that you read
Student tempStudent = (Student) studentStream.readObject();
while (endOfFile != true)
{
try
{
tempStudent = (Student) studentStream.readObject();
stud1.add(tempStudent);
}
Remove the read before the while, like the code below
while (endOfFile != true)
{
try
{
Student tempStudent = (Student) studentStream.readObject();
stud1.add(tempStudent);
}
I am not sure if this will solve your problem
Why don't you add the objects to an ArrayList<Type> then write/serialize them to file
and then for reading/deserialize it, read the data into one ArrayList<Type>.
Then you could fetch your objects one by one from the ArrayList
This might be an easier trouble free way of doing it.
//Serialize
ArrayList<Student> students = new ArrayList<Student>();
//Add the student objects to the array list
File f = new File("FileName.ser");
ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(f));
objOut.writeObject(students);
//Deserialize
ArrayList<Student> students = new ArrayList<Student>();
ObjectInputStream objIn = new ObjectInputStream(new FileInputStream(new File("FileName.ser")));
students = (ArrayList<String>) objIn.readObject();

Parse String Output to File

The first part of this “Frankenstein-ed” Java works perfectly, however the second part outputs some jumbled nonsense. So the variable of result will be my input from the user. I had to first UpperCase the string before I did the parsing for some dumb reason, it’s hard when you come from the Database/Analysis background and know you do something in seconds and not get an error... I gave credit where credit is due within the code...
myfile.txt ---> [Ljava.lang.String;#19821f
import java.io.*;
/*http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#split%28java.lang.String%29*/
public class StringParser {
public static void main (String arg[])
throws FileNotFoundException {
String result = "eggs toast bacon bacon butter ice beer".toUpperCase();
String[] resultU = result.split("\\s");
String[] y = resultU;
{
for (int x=0; x< resultU.length; x++)
System.out.println(resultU[x]);
/*http://www.javacoffeebreak.com/java103/java103.html#output*/
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object
try
{
// Create a new file output stream
// connected to "myfile.txt"
out = new FileOutputStream("myfile.txt");
// Connect print stream to the output stream
p = new PrintStream( out );
p.println (resultU);
p.close();
}
catch (Exception e)
{
System.err.println ("Error writing to file");
}
}
}
}
Do you realize you're overwriting the same file for each element in your array?
You should use
out = new FileOutputStream("myfile.txt", true); // appends to existing file
As well as printing the actual element, not the String representation of the whole array
p.println(resultU[x]); // resultU without index prints the whole array - yuk!
Although you should probably update your code to only create the output File once and just write each element of the array to the same output stream, as the current method is a bit inefficient.
Something like
public static void main(String[] args) {
String result = "eggs toast bacon bacon butter ice beer".toUpperCase();
PrintStream p = null;
try {
p = new PrintStream(new FileOutputStream("myfile.txt"));
for (String s : result.split("\\s")) {
p.println(s);
p.flush(); // probably not necessary
}
} catch (Exception e) {
e.printStackTrace(); // should really use a logger instead!
} finally {
try {
p.close(); // wouldn't need this in Java 7!
} catch (Exception e) {
}
}
}
You have to iterate the array and write each element one after one.
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object
try
{
out = new FileOutputStream("myfile.txt");
p = new PrintStream( out );
for(String str:resultU)
{
p.println (str);
}
p.close();
}
catch (Exception e)
{
System.err.println ("Error writing to file");
}
Your line
p.println (resultU);
is printing a string representation of the array itself, not the elements in it. To print the elements, you'll need to loop through the array and print them out individually. The Arrays class has a convenience method to do this for you, of course.
That "jumbled non-sense" is the Strings location in memory, but that's not important right now.
The solution to your problem is this:
try {
FileOutputStream out = new FileOutputStream("myfile.txt", true);
PrintStream = new PrintStream(out);
for(String s : resultU)
p.println(s);
p.close();
} catch(Exception e) {
e.printStackTrace();
}
This replaces your entire for loop.

Categories

Resources