Need help reading text file into Object - java

I have created a Person class, with parameters firstname, lastname, and year. I need to figure out how to read input from a text file and create an Array of Persons. Here is what I am trying, based on different sources I pooled from the web.
String name = "People.txt";
Person[] people = new ArrayList<Person>();
BufferedReader br = new BufferedReader(new FileReader(name));
String line = br.readLine();
while(line != null)
{
people.add(line);
line = br.readLine();
}
But of course, this isn't working. I doubt its even close to being correct, so I was wondering if you guys have any advice.
Also, the constructor for my Person class is as follows:
public Person(String firstName, String lastName, int age){
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
The error reads,
`SortingImplementation.java:15: incompatible types
found : java.util.ArrayList<Person>
required: Person[]
Person[] people = new ArrayList<Person>();
^
SortingImplementation.java:20: cannot find symbol
symbol : method add(java.lang.String)
location: class Person[]
people.add(line);
^
Note: SortingMethod.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors
`
Text file is
Larry Kim 45
Bob Stuart 51
Nancy Davis 38
John Doe 49
Henry Miles 23
Albert Lee 36
Mary Wing 43
Tony Rich 55
Ally Sneetch 19
Carrie Chrome 77
David Abkenzy 41
Young Old 18
Snow White 70
George Herald 60
Mike Bush 22
Peter Paul 33
Peter Pan 44
Mary Paul 25
Ray Romano 55
Well, sweet. You guys are awesome, maybe I'll get to sleep tonight. Been up for literally two days straight trying to get this done, starting to hallucinate. One last problem I am having, and I am sure it is something simple, but I am getting this error.
SortingImplementation.java:15: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
BufferedReader br = new BufferedReader(new FileReader("People.txt"));
^
SortingImplementation.java:16: unreported exception java.io.IOException; must be caught or declared to be thrown
String line = br.readLine();
I think it might just have to do with the way I am instantiating, or maybe I don't have the proper header files imported. Here's what I have imported.
import javax.swing.JOptionPane;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.io.*;
import java.nio.*;
Do you guys see anything that might be missing?

You have two options.
Without changing the Person class, after reading the line, you can parse the data into the firstName, lastName, and age, and send these arguments to the constructor.
You can add a constructor to Person that expects a single, unparsed String argument and does all the parsing within the constructor and assigns the initializes the variables from there.
For details on how to do either option, you'd have to show us what the text file looks like exactly.
But currently, your problem is that you're trying to add a String object to an ArrayList of Person objects.
You need to do this:
people.add(new Person(/*constructor arguments*/));
Now that you've updated to include the file format, try something like this:
while(line != null) {
String[] lineParts = line.split("\\s+");
people.add(new Person(lineParts[0],lineParts[1],parseInt(lineParts[2]));
line = br.readLine();
}
Doing via an additional Person constructor isn't much different.
In your Person class, add this constructor:
public Person(String s) {
String[] parts = s.split("\\s+");
this(parts[0], parts[1], parseInt(parts[2]));
}
Then in main, make your while loop look like this:
while(line != null) {
people.add(new Person(line));
line = br.readLine();
}

You can't just add a line String and expect it to magically transform into a Person. You need to split each line into separate Strings then create a person from those String
Person[] people = new ArrayList<Person>();
BufferedReader br = new BufferedReader(new FileReader(name));
String line = br.readLine();
while(line != null)
{
people.add(line);
line = br.readLine();
}
You need to do something like this, Note the change from array to ArrayList<Person>
ArrayList<Person> people = new ArrayList<Person>(); // Notice change here
BufferedReader br = new BufferedReader(new FileReader(name));
String line;
while((line = br.nextLine()) != null)
{
String[] tokens = line.split("\\s+");
String firstName = tokens[0];
String lastName = tokens[1];
int age = Integer.parseInt(tokens[2]); // parse String to int
people.add(new Person(firstName, lastName, age));
}
This is assuming the input text is formatted as follows
FirstName LastName Age
Also, make sure to wrap everything in a try/catch block, or have the method throws IOException;

Related

How to access each element after a split

I am trying to read from a text file and split it into three separate categories. ID, address, and weight. However, whenever I try to access the address and weight I have an error. Does anyone see the problem?
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;
class Project1
{
public static void main(String[] args)throws Exception
{
List<String> list = new ArrayList<String>();
List<String> packages = new ArrayList<String>();
List<String> addresses = new ArrayList<String>();
List<String> weights = new ArrayList<String>();
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while((str = br.readLine()) != null)
{
if(str.trim().length() > 0)
{
//System.out.println(str);
//Splits the string by commas and trims whitespace
String[] result = str.trim().split("\\s*,\\s*", 3);
packages.add(result[0]);
//ERROR: Doesn't know what result[1] or result[2] is.
//addresses.add(result[1]);
//weights.add(result[2]);
System.out.println(result[0]);
//System.out.println(result[1]);
//System.out.println(result[2]);
}
}
for(int i = 0; i < packages.size(); i++)
{
System.out.println(packages.get(i));
}
}
}
Here is the text file (The format is intentional):
,123-ABC-4567, 15 W. 15th St., 50.1
456-BgT-79876, 22 Broadway, 24
QAZ-456-QWER, 100 East 20th Street, 50
Q2Z-457-QWER, 200 East 20th Street, 49
678-FGH-9845 ,, 45 5th Ave,, 12.2,
678-FGH-9846,45 5th Ave,12.2
123-A BC-9999, 46 Foo Bar, 220.0
347-poy-3465, 101 B'way,24
,123-FBC-4567, 15 West 15th St., 50.1
678-FGH-8465 45 5th Ave 12.2
Seeing the pattern in your data, where some lines start with an unneeded comma, and some lines having multiple commas as delimiter and one line not even having any comma delimiter and instead space as delimiter, you will have to use a regex that handles all these behaviors. You can use this regex which does it all for your data and captures appropriately.
([\w- ]+?)[ ,]+([\w .']+)[ ,]+([\d.]+)
Here is the explanation for above regex,
([\w- ]+?) - Captures ID data which consists of word characters hyphen and space and places it in group1
[ ,]+ - This acts as a delimiter where it can be one or more space or comma
([\w .']+) - This captures address data which consists of word characters, space and . and places it in group2
[ ,]+ - Again the delimiter as described above
([\d.]+) - This captures the weight data which consists of numbers and . and places it in group3
Demo
Here is the modified Java code you can use. I've removed some of your variable declarations which you can have them back as needed. This code prints all the information after capturing the way you wanted using Matcher object.
Pattern p = Pattern.compile("([\\w- ]+?)[ ,]+([\\w .']+)[ ,]+([\\d.]+)");
// Reads the file
try (BufferedReader br = new BufferedReader(new FileReader("data1.txt"))) {
String str;
while ((str = br.readLine()) != null) {
Matcher m = p.matcher(str);
if (m.matches()) {
System.out.println(String.format("Id: %s, Address: %s, Weight: %s",
new Object[] { m.group(1), m.group(2), m.group(3) }));
}
}
}
Prints,
Id: 456-BgT-79876, Address: 22 Broadway, Weight: 24
Id: QAZ-456-QWER, Address: 100 East 20th Street, Weight: 50
Id: Q2Z-457-QWER, Address: 200 East 20th Street, Weight: 49
Id: 678-FGH-9845, Address: 45 5th Ave, Weight: 12.2
Id: 678-FGH-9846, Address: 45 5th Ave, Weight: 12.2
Id: 123-A BC-9999, Address: 46 Foo Bar, Weight: 220.0
Id: 347-poy-3465, Address: 101 B'way, Weight: 24
Id: 678-FGH-8465, Address: 45 5th Ave, Weight: 12.2
Let me know if this works for you and if you have any query further.
The last line only contains one token. So split will only return an array with one element.
A minimal reproducing example:
import java.io.*;
class Project1 {
public static void main(String[] args) throws Exception {
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while ((str = br.readLine()) != null) {
if (str.trim().length() > 0) {
String[] result = str.trim().split("\\s*,\\s*", 3);
System.out.println(result[1]);
}
}
}
}
With this input file:
678-FGH-8465 45 5th Ave 12.2
The output looks like this:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Project1.main(a.java:22)
Process finished with exit code 1
So you will have to decide, what your program should do in such cases. You might ignore those lines, print an error, or only add the first token in one of your lists.
you can add following code in your code
if (result.length > 0) {
packages.add(result[0]);
}
if (result.length > 1) {
addresses.add(result[1]);
}
if (result.length > 2) {
weights.add(result[2]);
}

JAVA- Splitting string into tokens but fails with error [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I am trying to read from a text file that has 20 lines and supposed to store them into an array and assign them a variable, firstname lastname and grade. Because I have to output them as last name, firstname and grade, I decided to use tokens but somehow I get this error: java.lang.ArrayIndexOutOfBoundsException: 1
public static void main(String[] args) throws IOException {
int numberOfLines = 20;
studentClass[] studentObject = new studentClass[numberOfLines];
readStudentData(studentObject);
}
public static void readStudentData(studentClass[] studentObject)throws {
//create FileReader and BufferedReader to read and store data
FileReader fr = new FileReader("/Volumes/PERS/Data.txt");
BufferedReader br = new BufferedReader (fr);
String line = null;
int i = 0;
//create array to store data for firstname, lastname, and score
while ((line = br.readLine()) != null){
String[] stuArray = line.split(" ");
String stuFName = stuArray[0];
String stuLName = stuArray[1];
int score = Integer.parseInt(stuArray[2]);
studentObject[i] = new studentClass (stuFName, stuLName, score);
i++;
}
br.close();
for(i = 0; i<studentObject.length; i++){
System.out.print(studentObject[i].getStudentFName());
}
}
The error that I get is specifically this line:
String stuLName = stuArray[1];
Here is the text file:
Duckey Donald 85
Goof Goofy 89
Brave Balto 93
Snow Smitn 93
Alice Wonderful 89
Samina Akthar 85
Simba Green 95
Donald Egger 90
Brown Deer 86
Johny Jackson 95
Greg Gupta 75
Samuel Happy 80
Danny Arora 80
Sleepy June 70
Amy Cheng 83
Shelly Malik 95
Chelsea Tomek 95
Angela Clodfelter 95
Allison Nields 95
Lance Norman 88
I think at the last line of your file you have white spaces. make sure last line hast no white space like space or tab.
First, next time you should include the import and output also in your code
for us to easy to fix it, and one more thing, the Class name should be
StudentClass, not studentClass, it have to me different with methods.
Second, I can't test your code without your studentClass ... So I only can guess it:
Consider 1: The text file have one more line (with white space) >> Impossible because String test = " "; test.split(" ")[0] == null;
Consider 2: Your text file has error, to test it, I suggest you to add
System.out.println(line + ".") after while ((line = br.readLine()) != null){
to test it, believe me, you will receive the last line because it's bloged;

reading student record from file

I'm trying to read a file that has student record(first name, last name, and grade).
I have written a simple code to accomplish this task but the code fails after reading two lines from the text file. Here is my code:
public class Student {
private final String first,last;
final int MAXGRADE = 100;
final int LOWGRADE = 0;
private final int grade;
public Student(String firstname,String lastname, int grade){
this.first = firstname;
this.last = lastname;
this.grade = grade;
}
#Override
public String toString(){
return first + " " + last + "\t" + grade;
}
}
and the driver has this code
public class driver {
public static void main(String[] args) throws FileNotFoundException {
String first_name ,last_name;
int grade;
Scanner fileInput = new Scanner(new File("data1.txt"));
while (fileInput.hasNextLine())
{
first_name = fileInput.next();
last_name = fileInput.next();
grade = fileInput.nextInt();
Student st = new Student(first_name, last_name,grade);
System.out.println(st);
}
}
}
the compiler is pointing to this
grade = fileInput.nextInt();
as the source of the error.
This code is working for me. Make Sure
The location of text file correctly given,
Integer value given at 3rd position in each line (like:- steve smith 22)
If you are using Java 8, then functional way of doing this would be:
String filePath = "C:/downloads/stud_records.txt"; // your file path
/*
* Gives you a list of all students form the file
*/
List<Student> allStudentsFromFile = Files.lines(Paths.get(filePath)).map(line -> {
String[] data = line.split("\\s+"); //Split on your delimiter
Student stud = new Student(data[0], data[1], Integer.parseInt(data[2]));
return stud;
}).collect(Collectors.toList());
Note: I've made an assumption that this:
FirstName LastName Grade
is the input file format.
From the comment you post "#AxelH each line represents a single student first, last name and grade" we can see the problem.
Your actual loop to read a line
while (fileInput.hasNextLine())
{
first_name = fileInput.next();
last_name = fileInput.next();
grade = fileInput.nextInt();
Student st = new Student(first_name, last_name,grade);
System.out.println(st);
}
Is reading 3 lines, one per fileInput.nextXXX();. What you need to do is
Read a line as a String : `String line = fileInput.nextLine();
Split that line base on the delimiter : `String[] data = line.split(" "); //Or your delimiter if not space (carefull with some names...)
Set the value from this array (parse are need for integer)
EDIT :
I have made a mistake since I am used to use nextline and not next, I can't delete the answer as it is accepted so I will update it to be more correct without changing the content.
The code is indeed correct, next will take the following input until the next delimiter, \\p{}javaWhitespace}+, but using the given solution would give you more solution to manage composed names as it could be Katrina Del Rio 3.

Java Scanner Class useDelimiter Method

I have to read from a text file containing all the NCAA Division 1 championship games since 1933,
the file is in this format: 1939:Villanova:42:Brown:30
1945:New York University:70:Ohio State:65 **The fact that some Universities have multiple white spaces is giving me lots of trouble beause we are only to read the school names and discard the year, points and colon. I do not know if I have to use a delimiter that discards what spaces, but buttom line is I am a very lost.
We are to discard the date, points, and ":". I am slightly fimilar with the useDelimiter method but, I have read that a .split("") might be useful. I am having a great deal of problems due to my lack of knowledge in patterns.
THIS IS WHAT I HAVE SO FAR:
class NCAATeamTester
{
public static void main(String[]args)throws IOException
{
NCAATeamList myList = new NCAATeamList(); //ArrayList containing teams
Scanner in = new Scanner(new File("ncaa2012.data"));
in.useDelimiter("[A-Za-z]+"); //String Delimeter excluding non alphabetic chars or ints
while(in.hasNextLine()){
String line = in.nextLine();
String name = in.next(line);
String losingTeam = in.next(line);
//Creating team object with winning team
NCAATeamStats win = new NCAATeamStats(name);
myList.addToList(win); //Adds to List
//Creating team object with losing team
NCAATeamStats lose = new NCAATeamStats(losingTeam);
myList.addToList(lose)
}
}
}
What about
String[] spl = line.split(':');
String name1 = spl[1];
String name2 = spl[3];
?
Or, if there are more records at the same line, use regular expressions :
String line = "1939:Villanova:42:Brown:30 1945:New York University:70:Ohio State:65";
Pattern p = Pattern.compile("(.*?:){4}[0-9]+");
Matcher m = p.matcher(line);
while (m.find())
{
String[] spl = m.group().split(':');
String name = spl[1];
String name2 = spl[3];
}

string tokenizer stopping after first line

I have a text file I am trying to break up with string tokenizer. Here is a few lines of the text file:
Mary Smith 1
James Johnson 2
Patricia Williams 3
I am trying to break up into first name, last name and Customer ID.
I have so far been able to do that but it stops after mary smith.
Here is my code:
public static void createCustomerList(BufferedReader infileCust,
CustomerList customerList) throws IOException
{
String firstName;
String lastName;
int custId;
//take first line of strings before breaking them up to first last and cust ID
String StringToBreak = infileCust.readLine();
//split up the string with string tokenizer
StringTokenizer st = new StringTokenizer(StringToBreak);
firstName = st.nextToken();
while(st.hasMoreElements())
{
lastName = st.nextToken();
custId = Integer.parseInt(st.nextToken());
CustomerElement CustomerObject = new CustomerElement();
CustomerObject.setCustInfo(firstName,lastName,custId);
customerList.addToList(CustomerObject);
}
}
String StringToBreak = infileCust.readLine();
reads the FIRST line from the file. And you feed the StringTokenizer with it. It's normal that StringTokenized doesn't find more tokens.
You have to create a second loop enclosing all this to read every line. It is:
outer loop: readLine until it gets null {
create a StringTokenizer that consumes *current* line
inner loop: nextToken until !hasMoreElements()
}
Well, indeed you don't need to do an inner loop because you have three different fields. It's enough with:
name = st.nextToken();
lastName = st.nextToken();
id = st.nextToken;
For the outer loop, you need to store the contents of the current line in the stringToBreak variable so that you can access it inside the loop.
You need a new StringTokenizer for each line so it needs to be inside the loop.
String stringToBreak = null;
while ((stringToBreak = infileCust.readLine()) != null) {
//split up the string with string tokenizer
StringTokenizer st = new StringTokenizer(stringToBreak);
firstName = st.nextToken();
lastName = st.nextToken();
custId = Integer.parseInt(st.nextToken());
}
First off, you want to look at your loop, specifically how you have firstName outside of the loop so that is going to throw all of you tokens off. You will be trying to create new customer objects without enough information.

Categories

Resources