I have a text file that looks like this.
BEGINNING OF LIST
Name: Janet
Age: 21
Birthday month: April
END OF LIST
BEGINNING OF LIST
Name: Peter
Age: 34
Birthday month: January
END OF LIST
So I want to grab info and put it into an object array. it is an extensive list and I am using the delimiters beginning of list and end of list to delimit the content.
How can I store these items in an object array?
I would suggest you create a class first for storing the information, with name, age, and birthday month attributes. It's a very good practice to override the toString() method so you can print out the class neatly.
Then you can check for each line whether it contains information about the name, age, or birthday month through splitting each line into an array of words, and checking for the information.
Once the line reads "END OF LIST", you can add a class Person with the parameters to the ArrayList.
For the example I used "people.txt" as the file (make sure you place the text document outside of the src folder which contains your .java files).
Main.java
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args)
{
BufferedReader bufferedReader = null;
FileReader fileReader = null;
String name = null;
String age = null;
String month = null;
List<Person> people = new ArrayList<Person>();
try
{
String fileName = "people.txt";
fileReader = new FileReader(fileName);
bufferedReader = new BufferedReader(fileReader);
String line = null;
while ((line = bufferedReader.readLine()) != null)
{
String[] information = line.split(" ");
if (Arrays.asList(information).contains("Name:"))
{
name = information[1];
}
if (Arrays.asList(information).contains("Age:"))
{
age = information[1];
}
if (Arrays.asList(information).contains("month:"))
{
month = information[2];
}
if (line.equals("END OF LIST"))
{
people.add(new Person(name, age, month));
name = "";
age = "";
month = "";
}
}
for (Person person : people)
{
System.out.println(person);
System.out.print("\n");
}
}
catch (FileNotFoundException e)
{
System.out.println(e.getMessage());
}
catch (IOException ex)
{
System.out.println("Error reading people.txt");
}
finally
{
if (bufferedReader != null)
{
try
{
bufferedReader.close();
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
if (fileReader != null)
{
try
{
fileReader.close();
}
catch (IOException ex)
{
System.out.println(ex.getMessage());
}
}
}
}
}
Person.java
public class Person {
private String name;
private String age;
private String birthday;
public Person(String name, String age, String birthday)
{
this.name = name;
this.age = age;
this.birthday = birthday;
}
#Override
public String toString()
{
String information = "Name: " + name + "\nAge: " + age + "\nBirthday: " + birthday;
return information;
}
}
Related
I'm trying to figure out how to sort the arrayLists that come out of a .txt file. I want to be able to sort them alphabetically by name. Here is an example of how the txt file is listed:
Alvarez, Eliezer
74
2B
IA
22
Bowman, Matt
67
P
A
26
Each piece is on a single line by itself (except lastName, firstName being on a line together).
Is there a way to do a collections sort that will adjust the rest of the Arraylists based off the name Arraylist? Thanks.
Scanner keyboard = new Scanner(System.in);
String filename;
fileName = "cardinals.txt";
File baseball = new File(fileName);
if (!baseball.exists()) {
System.out.println("The input file was not found.");
System.exit(0);
}
ArrayList<String> name = new ArrayList<>();
ArrayList<Integer> number = new ArrayList<>();
ArrayList<String> position = new ArrayList<>();
ArrayList<String> status = new ArrayList<>();
ArrayList<Double> age = new ArrayList<>();
Scanner stats = new Scanner(baseball);
if (!stats.hasNext()) {
System.out.println("The file is empty.");
}
else {
while (stats.hasNext()) {
name.add(stats.nextLine());
number.add(stats.nextInt());
position.add(stats.next());
status.add(stats.next());
age.add(stats.nextDouble());
try {
stats.nextLine();
} catch (Exception e) {
}
}
} stats.close();
sortArrayPosition();
sortArrayPosition (ArrayList<String> name, ArrayList<Integer> number, ArrayList<String> position, ArrayList<String> status, ArrayList<Double> age) {
When organizing and managing complex data, using an object to group the data together is the best approach.
Here is an example using an object to store the information:
package example;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
class StatisticsReader {
private static class PlayerStats {
String name;
Integer number;
String position;
String status;
Double age;
public PlayerStats(String name, Integer number, String position, String status, Double age) {
this.name = name;
this.number = number;
this.position = position;
this.status = status;
this.age = age;
}
#Override
public String toString() {
return "PlayerStats{" +
"name='" + name + '\'' +
", number=" + number +
", position='" + position + '\'' +
", status='" + status + '\'' +
", age=" + age +
'}';
}
}
public static void main(String[] args) {
File baseball = new File("cardinals.txt");
if (!baseball.exists()) {
System.out.println("The input file was not found.");
System.exit(0);
}
List<PlayerStats> statsList = new ArrayList<>();
try (Scanner stats = new Scanner(baseball)) {
if (!stats.hasNext()) {
System.out.println("The file is empty.");
}
else {
while (stats.hasNext()) {
String name = stats.nextLine();
Integer number = stats.nextInt();
String position = stats.next();
String status = stats.next();
Double age = stats.nextDouble();
statsList.add(new PlayerStats(name, number, position, status, age));
stats.nextLine();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
statsList.sort(Comparator.comparing(o -> o.name));
statsList.forEach(System.out::println);
}
}
You can customize the toString() method to change the output if necessary.
As a part of my assignment I had to store objects of an array in a flat-file and retrieve them when certain criteria was met. I can save the objects fine but when retrieving them I have an issue with getting more than one value, I understand what is going wrong but I am struggling to find a solution. Here is the concept of whats happening.
Button no 10,A (R1S10 in the code)is my testing button, When I click it it creates an event that I will show below.
Click event for button 10A -
private void R1S10ActionPerformed(java.awt.event.ActionEvent evt) {
seats.add(seat1);
if (R1S10.getBackground().equals(Color.red) &&(IsSeatBooked().equals("true"))){
Component frame = null;
JOptionPane.showMessageDialog(frame, "Seat UnBooked");
seat1.setBooked("false");
seat1.setName("");
R1S10.setBackground(Color.yellow);
try {
reader();
writer();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
else{
Component frame = null;
String name = JOptionPane.showInputDialog(frame, "Please enter name of Customer booking");
if (name.isEmpty()) {
JOptionPane.showMessageDialog(frame, "No value entered");
} else if (name != null) {
seat1.setName(name);
seat1.setBooked("true");
R1S10.setBackground(Color.red);
JOptionPane.showMessageDialog(frame, "Your Booking has been placed");
try {
writer();
reader();
//String booked = "true";
//Pass String booked into csv file
} catch (IOException ex) {
Logger.getLogger(SeatingPlan.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Followed by the screen below -
Outcome -
And when the button is pressed again -
I am using three methods in this SeatingPlan.java - writer(),reader() and IsSeatBooked().
SeatingPlan -
public class SeatingPlan extends javax.swing.JFrame {
/**
* Creates new form SeatingPlan
*/
String seatNo, name, bookedSeat;
FileWriter fileWriter = null;
List<Seat> seats = new ArrayList<Seat>();
//Seat Object Declaration
Seat seat1 = new Seat("R1S10","","false");
Seat seat2 = new Seat("R1S9", "", "false");
String fileName = "seat.csv";
writer -
public void writer() throws IOException {
//Delimiter used in CSV file
final String NEW_LINE_SEPARATOR = "\n", COMMA_DELIMITER = ",";
//CSV file header
final String FILE_HEADER = "seatID,name,booked";
//fileName = System.getProperty("user.home") + "/seat.csv";
try {
fileWriter = new FileWriter(fileName);
//Write the CSV file header
fileWriter.append(FILE_HEADER.toString());
//Add a new line separator after the header
fileWriter.append(NEW_LINE_SEPARATOR);
//Write a new student object list to the CSV file
for (Seat seat : seats) {
fileWriter.append(String.valueOf(seat.getSeatID()));
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.getName());
fileWriter.append(COMMA_DELIMITER);
fileWriter.append(seat.isBooked());
fileWriter.append(NEW_LINE_SEPARATOR);
}
System.out.println("CSV file was created successfully !!!");
} catch (Exception e) {
System.out.println("Error in CsvFileWriter !!!");
e.printStackTrace();
} finally {
fileWriter.flush();
fileWriter.close();
}
}
reader -
public void reader() {
//Delimiter used in CSV file
final String COMMA_DELIMITER = ",";
//Student attributes index
final int SEAT_ID_IDX = 0;
final int SEAT_NAME_IDX = 1;
final int SEAT_BOOKED = 2;
//private static final int STUDENT_LNAME_IDX = 2;
BufferedReader fileReader = null;
try {
//Create a new list of student to be filled by CSV file data
List<Seat> seats = new ArrayList<>();
String line = "";
//Create the file reader
fileReader = new BufferedReader(new FileReader(fileName));
//Read the CSV file header to skip it
fileReader.readLine();
//Read the file line by line starting from the second line
while ((line = fileReader.readLine()) != null) {
//Get all tokens available in line
String[] tokens = line.split(COMMA_DELIMITER);
if (tokens.length > 0) {
//Create a new seat object and fill his data
Seat seat = new Seat(tokens[SEAT_ID_IDX],
tokens[SEAT_NAME_IDX], tokens[SEAT_BOOKED]);
seats.add(seat);
seatNo = tokens[SEAT_ID_IDX];
//System.out.println("Seat Number: " + seatNo);
bookedSeat = tokens[SEAT_BOOKED];
}
}
//Print the new student list
for (Seat seat : seats) {
System.out.println(seat.toString());
}
} catch (Exception e) {
System.out.println("Error in CsvFileReader !!!");
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
System.out.println("Error while closing fileReader !!!");
e.printStackTrace();
}
}
}//end reader
SeatingPlan - This if where I have tried to have the arguments controlling the outcome but IsBooked is colliding when multiple seats are selected.
public SeatingPlan() throws IOException {
setVisible(true);
initComponents();
//reader();
ColourSectionGold();
ColourSectionBronze();
reader();
if(R1S10.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true"))){ R1S10.setBackground(Color.red);}
//if(R1S9.getBackground().equals(Color.yellow) && (IsSeatBooked().equals("true2"))){ R1S9.setBackground(Color.red);}
}
IsSeatBooked -
public String IsSeatBooked(){
return bookedSeat;
}//end IsSeatBooked
Im using the method above as my argument to see whether a seat is booked or not, but when a new seat is click it sets the whole value of 'bookedSeat' - which leaves the system not working correctly. I understand the code is not very efficient but is there any temporary fix for this problem, if I have explained it correctly.
Also I will include my class for Seat -
public class Seat {
private String seatID;
private String booked;
private String name;
private int price;
public Seat(String seatID,String name,String booked){
this.seatID = seatID;
this.booked = "";
this.name = name;
this.price = price;
}
public String getSeatID() {
return seatID;
}
public void setSeatID(String seatID) {
this.seatID = seatID;
}
public String isBooked() {
return booked;
}
public void setBooked(String booked) {
this.booked = booked;
}
public String getStatus(){
return booked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setPrice() {
this.price = price;
}}//end class Seat
And a look at the CSV file that is created -
I wish to be able to click more than one button and save its state, Button 10 works fine at the moment, but as IsBooked only has one value at a time it clashes.
If you took the time to check this out, I appreciate it. Any constructive criticism is helpful and any ideas would be great!
Thanks,
Paddy.
Too much code to look at to see exactly what you are doing.
Instead of using your csv file, you could create a Properties file. The Propertiesfile will store the data in the form of:
key:data
So in your case the key would be the id: A1, A2... and the data would be the name of the person who booked the seat.
So the file would start out as empty. When you create the GUI you would create a loop that checks each id to see if an entry is found in the Properties field. If it is found then you display the seat as taken, otherwise it is empty.
Then whenever you want to book a seat you just use the setProperty(...) method.
The Properties class has load(...) and store(...) methods.
So the Properties class allows you to easily manage a flat file database with minimal effort.
Note, you would never have variable names like R1S10. That would requirement 100 different variables with if/else statements. Instead you would extend JButton and pass in the row and seat as parameters the button. Then in the ActionListener for the button you can access the row/seat information to built the ID used as the key for the properties file.
Edit:
Couldn't quite make the loop that checks if the ID is in the properties file.
If the property is null, the seath is empty.
import java.util.*;
public class Main
{
public static void main(String[] args)
{
Properties properties = new Properties();
properties.setProperty("A2", "Smith");
properties.setProperty("C3", "Jones");
String[] rows = { "A", "B", "C", "D" };
int seats = 4;
for (int row = 0; row < rows.length; row++)
{
for (int seat = 1; seat <= seats; seat++)
{
String key = rows[row] + seat;
String property = properties.getProperty( key );
System.out.println(key + " : " + property);
}
}
}
}
I have a code that reads an id block of three lines from a text file, I want to split those lines in Strings and an int, and pass this to a constructor from another class.
Right now, this class asks for an id number and prints everything below the # sign, down to and including the third line of each id block. I want those three lines in each id to be parsed as 'name', 'age' and 'job' to an Employee class, in order to create an object of the id, like this: Employee("Richard Smith",22,"Electric engineer"). There will always be three lines in the file for an id, so how can I "find" those lines and split them into Strings and an int?
#1000
Richard Smith
22
Electric engineer
#1001
Elliot Smith
23
Physicist
public class RdB
{
String b; //file name
RdB(String ename) {
b = ename;
}
//info about an employee
boolean showE (String id) {
int ch;
String code, info;
//open the file with the info
try (BufferedReader showERdr =
new BufferedReader (new FileReader(b)))
{
do {
//read characters until a '#' is found
ch = showERdr.read();
//check
if(ch == '#') {
code = showERdr.readLine();
if(id.compareTo(code) == 0) { //found employee
do {
info = showERdr.readLine();
if(info != null) {
System.out.println(info);
}
} while(((info != null) &&
(info.compareTo("") != 0)));
return true;
}
}
} while(ch != -1);
}
catch(IOException exc) {
System.out.println("File error!");
return false;
}
return false; //employee not found
}
//Access a registered employee
String getE() {
String id = "";
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter id number: ");
try{
id = br.readLine();
}
catch(IOException exc) {
System.out.println("Access error");
}
return id;
}
}
Edit:
Employee class
class Employee {
private String name, job;
private int age;
public Employee (String name, int age, String job) {
this.name = name;
this.age = age;
this.job = job;
}
public String getName () {
return name;
}
public int getAge () {
return age;
}
public String getJob () {
return job;
}
}
You can simply use an ArrayList to save what you read from the file and process it later. Since you are certain about the features of your saved file that it will always contain 3 lines before the line which contains ID, here is the working code I wrote to solve your problem. You can see the output wrapped between ( )
Here is the code:
import java.io.*;
import java.util.List;
import java.util.ArrayList;
public class Emp{
public static void main(String[] args) throws IOException{
List data = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new FileReader("PeopleData.txt"));
String str;
while((str = reader.readLine()) != null){
// System.out.println(str);
data.add(str);
}
for(int i= 0; i< data.size(); i ++){
i++;
System.out.println("(");
System.out.println(data.get(i));
String name = (String) data.get(i);
i++;
System.out.println(data.get(i));
int age = Integer.valueOf((String) data.get(i));
i++;
System.out.println(data.get(i));
String job = (String) data.get(i);
i++;
System.out.println(")");
//new Employee(name, age, job);
}
}
}
This project I'm working on, here is the function which write data's in to file :
public void writetofile(){
String bucky[]={custname,custlname,agee,address,id};
for(int i = 0; i < bucky.length; i++) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("records.txt", true))) {
String s;
s = bucky[i];
bw.write(s);
bw.newLine();
bw.flush();
}
catch(IOException ex) {
JOptionPane.showMessageDialog(null, "Error In File");
}
}
};
and there is another function defined which reads data's from file ,
public void filereader (){
int i=0;
Object[] options = {"OK"};
try
{
FileInputStream in = new FileInputStream("records.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
StringBuffer sb = new StringBuffer();
while((strLine = br.readLine())!= null)
{
sb.append(strLine +"\n");
}
JOptionPane.showMessageDialog( null, sb.toString());
}catch(Exception e){
JOptionPane.showOptionDialog(null, "Error", "Customers", JOptionPane.PLAIN_MESSAGE,JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
}
};
and the problem is , let's say I want to create an account for a customer in my project , so few questions were asked such as name , last name , gender , etc. and all those info's have been saved , but when I try to read files all the data's will appear in no format , I want them to be appear in the proper way like this :
customer name : Michelle ,
gender : Female ;
but right now it appears as this :
michelle ,
female ,
You can construct the desired output first and callbw.write(s); only once
or follow R.J 's suggestion. Put everything to an object and override toString methid of that class. This will be the perfect way of solving your problem
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JOptionPane;
public class Customer
{
private final String firstName;
private final String lastName;
private final String address;
private final int age;
private final int id;
public Customer(String firstName, String lastName, String address, int age,
int id)
{
super();
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.age = age;
this.id = id;
}
#Override
public String toString ()
{
return "Customer [firstName=" + firstName + ", lastName=" + lastName
+ ", address=" + address + ", age=" + age + "]";
}
public static void main (String[] args)
{
}
public void writetofile (String custname, String custlname, int agee,
String address, int age)
{
Customer customer = new Customer(custname, custlname, address, age, id);
try (BufferedWriter bw = new BufferedWriter(new FileWriter(
"records.txt", true)))
{
String s = customer.toString();
bw.write(s);
bw.newLine();
bw.flush();
}
catch (IOException ex)
{
JOptionPane.showMessageDialog(null, "Error In File");
}
}
}
I have a text file, formatted as follows:
Han Solo:1000
Harry:100
Ron:10
Yoda:0
I need to make an arrayList of objects which store the player's name (Han Solo) and their score (1000) as attributes. I would like to be able to make this arrayList by reading the file line by line and splitting the string in order to get the desired attributes.
I tried using a Scanner object, but didn't get far. Any help on this would be greatly appreciated, thanks.
You can have a Player class like this:-
class Player { // Class which holds the player data
private String name;
private int score;
public Player(String name, int score) {
this.name = name;
this.score = score;
}
// Getters & Setters
// Overrride toString() - I did this. Its optional though.
}
and you can parse your file which contains the data like this:-
List<Player> players = new ArrayList<Player>();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt"))); // I used BufferedReader instead of a Scanner
String line = null;
while ((line = br.readLine()) != null) {
String[] values = line.split(":"); // Split on ":"
players.add(new Player(values[0], Integer.parseInt(values[1]))); // Create a new Player object with the values extract and add it to the list
}
} catch (IOException ioe) {
// Exception Handling
}
System.out.println(players); // Just printing the list. toString() method of Player class is called.
You can create a Class call player. playerName and score will be the attributes.
public class Player {
private String playerName;
private String score;
// getters and setters
}
Then you can create a List
List<Player> playerList=new ArrayList<>();
Now you can try to do your task.
Additionally, you can read from file and split each line by : and put first part as playerName and second part as score.
List<Player> list=new ArrayList<>();
while (scanner.hasNextLine()){
String line=scanner.nextLine();
Player player=new Player();
player.setPlayerName(line.split(":")[0]);
player.setScore(line.split(":")[1]);
list.add(player);
}
If you have Object:
public class User
{
private String name;
private int score;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getScore()
{
return score;
}
public void setScore(int score)
{
this.score = score;
}
}
Make an Reader class that reads from the file :
public class Reader
{
public static void main(String[] args)
{
List<User> list = new ArrayList<User>();
File file = new File("test.txt");
BufferedReader reader = null;
try
{
reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null)
{
String[] splitedString = line.split(":");
User user = new User();
user.setName(splitedString[0]);
user.setScore(Integer.parseInt(splitedString[1]));
list.add(user);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (reader != null)
{
try
{
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
for (User user : list)
{
System.out.println(user.getName()+" "+user.getScore());
}
}
}
The output will be :
Han Solo 1000
Harry 100
Ron 10
Yoda 0
Let's assume you have a class called Player that comprises two data members - name of type String and score of type int.
List<Player> players=new ArrayList<Player>();
BufferedReader br=null;
try{
br=new BufferedReader(new FileReader("filename"));
String record;
String arr[];
while((record=br.readLine())!=null){
arr=record.split(":");
//Player instantiated through two-argument constructor
players.add(new Player(arr[0], Integer.parseInt(arr[1])));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally{
if(br!=null)
try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
For small files (less than 8kb), you can use this
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class NameScoreReader {
List<Player> readFile(final String fileName) throws IOException
{
final List<Player> retval = new ArrayList<Player>();
final Path path = Paths.get(fileName);
final List<String> source = Files.readAllLines(path, StandardCharsets.UTF_8);
for (final String line : source) {
final String[] array = line.split(":");
if (array.length == 2) {
retval.add(new Player(array[0], Integer.parseInt(array[1])));
} else {
System.out.println("Invalid format: " + array);
}
}
return retval;
}
class Player {
protected Player(final String pName, final int pScore) {
super();
this.name = pName;
this.score = pScore;
}
private String name;
private int score;
public String getName()
{
return this.name;
}
public void setName(final String name)
{
this.name = name;
}
public int getScore()
{
return this.score;
}
public void setScore(final int score)
{
this.score = score;
}
}
}
Read the file and convert it to string and split function you can apply for the result.
public static String getStringFromFile(String fileName) {
BufferedReader reader;
String str = "";
try {
reader = new BufferedReader(new FileReader(fileName));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append("\n");
}
str = stringBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
public static void main(String[] args) {
String stringFromText = getStringFromFile("C:/DBMT/data.txt");
//Split and other logic goes here
}