I want to store the name and surname written in a running program, so when the program is closed and you run it again, if you click the option to Show List again it will display what was written before.
// program.java
package com.example;
import java.util.ArrayList;
import java.util.Scanner;
public class Program
{
public static void main(String[] args)
{
ArrayList<People> Person = new ArrayList<>();
Scanner input = new Scanner(System.in);
while (true)
{
System.out.println("""
*Death Note*
[1] Show List
[2] Write New Name
[3] Exit
Type: """);
String izbor = input.nextLine();
if (izbor.equals("1")) {
for (int i = 0; i < Person.size(); i = i 1) {
System.out.println(Person.get(i));
}
} else if (izbor.equals("2")) {
People o = new People();
System.out.println("Name: ");
o.setname(input.nextLine());
System.out.println("Surname: ");
o.setsurname(input.nextLine());
Person.add(o);
} else if (izbor.equals("3")) {
break;
} else {
System.err.println("D:");
}
}
}
}
And then there is another java class:
// People.java
package com.example;
public class People {
private String name;
private String surname;
public People() {}
public People(String in_name, String in_surname) {
name = in_name;
surname = in_surname;
}
public String getname(){ return name; }
public String getsurname(){ return surname; }
public void setname(String value) { name = value; }
public void setsurname (String value) { surname = value; }
public String toString() {return String.format("%s %s", name, surname); }
}
I use IntelliJ Idea. :)
CodePudding user response:
In order for the list to be saved between separate runs of your program, you need to save the list to some permanent storage. Usually permanent storage is either a file or a database. In this answer I use a file. The file can either be a text file or a data file. A text file can be opened in an editor (like Notepad ) and its contents are human-readable. A data file's contents are not human-readable.
The simplest solution, in my opinion, is to utilize Java's inbuilt serialization. In order to do this, class People
has to implement interface java.io.Serializable
. Note that class java.util.ArrayList
implements interface Serializable
.
The below code demonstrates how to integrate serialization into the code in your question.
(Notes after the code.)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class People implements Serializable {
/** For serializing instances of this class. */
private static final long serialVersionUID = -3122681927353521840L;
private static final String FILE = "persons.dat";
private String name;
private String surname;
@SuppressWarnings("unchecked")
private static List<People> loadList() throws ClassNotFoundException, IOException {
File f = new File(FILE);
if (f.isFile()) {
try (FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis)) {
return (List<People>) ois.readObject(); // Unchecked cast.
}
}
else {
return new ArrayList<People>();
}
}
private static void saveList(List<People> list) throws IOException {
if (list != null) {
File f = new File(FILE);
try (FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(list);
}
}
}
public void setName(String name) {
this.name = name;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String toString() {
return name " " surname;
}
public static void main(String[] args) throws ClassNotFoundException, IOException {
List<People> person = loadList();
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("""
*Death Note*
[1] Show List
[2] Write New Name
[3] Exit
Type: """);
String izbor = input.nextLine();
if (izbor.equals("1")) {
for (int i = 0; i < person.size(); i = i 1) {
System.out.println(person.get(i));
}
}
else if (izbor.equals("2")) {
People o = new People();
System.out.println("Name: ");
o.setName(input.nextLine());
System.out.println("Surname: ");
o.setSurname(input.nextLine());
person.add(o);
}
else if (izbor.equals("3")) {
saveList(person);
break;
}
else {
System.err.println("D:");
}
}
}
}
- In method
main
we first load the list from the file persons.dat. - Before exiting the program, we save the contents of
person
to the same file.
Alternatively, using a text file to save the list involves writing more code. The below code uses stream API, NIO.2 and method references. Both the code above and the code below use try-with-resources.
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class People {
private static final Path PATH = Paths.get("persons.txt");
private static final String DELIM = ";";
private String name;
private String surname;
public People() {
this(null, null);
}
public People(String name, String surname) {
setName(name);
setSurname(surname);
}
private static People createPeople(String line) {
String[] parts = line.split(DELIM);
return new People(parts[0], parts[1]);
}
private static List<People> loadList() throws ClassNotFoundException, IOException {
File f = PATH.toFile();
List<People> list = new ArrayList<>();
if (f.isFile()) {
try (Stream<String> lines = Files.lines(PATH)) {
list = lines.map(People::createPeople)
.collect(Collectors.toList());
}
}
return list;
}
private static void saveList(List<People> list) throws IOException {
if (list != null) {
try (BufferedWriter bw = Files.newBufferedWriter(PATH,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE)) {
for (People p : list) {
String line = String.format("%s%s%s%n",
p.getName(),
DELIM,
p.getSurname());
bw.write(line);
}
}
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String toString() {
return name " " surname;
}
public static void main(String[] args) throws ClassNotFoundException, IOException {
List<People> person = loadList();
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("""
*Death Note*
[1] Show List
[2] Write New Name
[3] Exit
Type: """);
String izbor = input.nextLine();
if (izbor.equals("1")) {
for (int i = 0; i < person.size(); i = i 1) {
System.out.println(person.get(i));
}
}
else if (izbor.equals("2")) {
People o = new People();
System.out.println("Name: ");
o.setName(input.nextLine());
System.out.println("Surname: ");
o.setSurname(input.nextLine());
person.add(o);
}
else if (izbor.equals("3")) {
saveList(person);
break;
}
else {
System.err.println("D:");
}
}
}
}
CodePudding user response:
You could make your Person
class serializable and store the persons in a file.
Here is how to do it with a pretty similar example(link).
This way you would have to deal with each Person individually,
I'd suggest you'd create a DeathNote
class. The object of DeathNote
would include the Person
objects.
Here in Code:
public static DeathNote readDeathNoteFromFile(String file){
DeathNote dn = new DeathNote();
try {
File myObj = new File(file);
if (myObj.createNewFile()) {
System.out.println("File created: " myObj.getName());
} else {
System.out.println("File already exists.");
FileInputStream fileInputStream = new FileInputStream(file);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
dn = (DeathNote) objectInputStream.readObject();
objectInputStream.close();
}
} catch (IOException | ClassNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
return dn;
}
public static void writeDeathNoteToFile(String file, DeathNote dn){
try {
File myObj = new File(file);
if (myObj.createNewFile()) {
System.out.println("File created: " myObj.getName());
}
FileOutputStream fileOutputStream = new FileOutputStream(file, false);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(dn);
objectOutputStream.flush();
objectOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I added a call to read at the top of main()
String filename = "deathnote.txt";
DeathNote dn = new DeathNote();
dn=readDeathNoteFromFile(filename);
and I called write at the bottom(could also be called after adding a person to the list):
} else if (izbor.equals("3")) {
break;
} else {
System.err.println("D:");
}
}
input.close();
writeDeathNoteToFile(filename, dn);
DeathNote class looks like this:
import java.io.Serializable;
import java.util.ArrayList;
public class DeathNote implements Serializable {
ArrayList<People> Person;
public DeathNote() {Person = new ArrayList<People>();}
public void addPerson(People p) {Person.add(p);}
public int size() {return Person.size();}
public People get(int i){return Person.get(i);}
}
And People needs to implement Serializable:
public class People implements Serializable{
I'd personally suggest, that you would change the name of the list Person
to People
, because it represents a list of people and the class People
to Person
, because every object of it is a single Person.
Furthermore my compiler says, that the scanner should be closed