Creating objects via txt file into an array in Java - java

I am trying to complete a little program.
I've got a text file (.txt) to store different data on objects that i've got.
The structure of the file is the next (exemples data.txt) :
Sedane
2005
195000
Diesel
Blue
SUV
2013
34000
Fuel
Black
Each object is made true a class that i've build called Cars.
So the 1 line is the type of car, the 2nd the year of built, the 3rd line is the milage, the 4th is the type of fuel, and the 5th line is the color of the car.
So basicly i need to open the file, and load the data into the memory when i execute my program into an array with object in it.
I'm ok to open the file but i'm blocked when it comes to reading the data and putting it in an array.
The array size is 2 for this exemple, but if i have more entries in the file it's going to adapt it's size when loading at the startup of the program.
Here's what i've got unti now (for my code ...)
public static void loadCars () {
FileReader fopen;
BufferedReader opened;
String line;
try {
fEntree = new FileReader( "data.txt" );
opened = new BufferedReader( fopen );
while ( opened.ready() ) {
line = opened.readLine();
// Don't know what to do here ????
}
opened.close();
} catch ( IOException e ) {
System.out.println( "File doesn't exist !" );
}
}

Someting like this will do the trick. I'm adding the file contents line by line to an Arraylist instead of an array though. This way you don't have to know how big your array needs to be before hand. Plus you can always change it to an array later.
public ArrayList<String> readFileToMemory(String filepath)
{
in = new BufferedReader(new FileReader( "data.txt" ));
String currentLine = null;
ArrayList<String> fileContents = new ArrayList<String>();
try
{
while((currentLine = in.readLine()) != null)
{
fileContents.add(currentLine);
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
in.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
return fileContents;
}

LineNumberReader lnr = new LineNumberReader(new FileReader(new File("File1")));
lnr.skip(Long.MAX_VALUE);
long length = lnr.getLineNumber();
lnr.close();
in = new BufferedReader(new FileReader( "data.txt" ));
Car[] cars= new Car[length/5];
String currentLine;
int i=0;
for(int i=0;i<length/5;i+=5) {
String name = in.readLine();
String year = in.readLine();
String miles = in.readLine();
String gas = in.readLine();
String color = in.readLine();
cars[i] = new Car(name,year,miles,gas,color);
}
You'll have to handle exceptions too, surround stuff in try catch structures.

You can look at my solution here below (I also corrected/simplified some problems with the variables for reading the file, anyway this was not the main topic):
public static void loadCars() {
FileReader fopen;
BufferedReader opened;
String line;
ArrayList<Car> carList = new ArrayList<Car>();
try {
fopen = new FileReader("data.txt");
opened = new BufferedReader(fopen);
int nFields = 5; // we have 5 fields in the Car class
String[] fields = new String[nFields]; // to temporary store fields values read line by line
int lineCounter = 0;
while ((line = opened.readLine()) != null) {
fields[lineCounter] = line;
lineCounter++;
if ((lineCounter) % nFields == 0) { //it means we have all 5 fields values for a car
carList.add(new Car(fields)); //therefore we create a new car and we add it to the list of cars
}
}
opened.close();
} catch (IOException e) {
System.out.println("File doesn't exist !");
}
}
Basically we use an ArrayList to store all the cars, and we read the file, waiting to have all the fields values in order to create the Car object. I store the fields values in an array of Strings: I don't know how you implemented the Car class, but maybe it is useful to create a constructor that takes as parameter an array of strings, so it can set the fields, for instance:
class Car {
private String type;
private String year;
private String milage;
private String fuel;
private String color;
public Car(String[] fields) {
type=fields[0];
year=fields[0];
milage=fields[0];
fuel=fields[0];
type=fields[0];
}
}
But I've to say that probably this is a little 'too static'.
For simplicity I assumed that all your fields are of String type, but probably fields like 'year' or 'milage' might be of int type. In this case you can use array of Object[] (instead of String[]), and then cast the value with the right type.
I hope this may help you.

Related

Is there a way to generate n differentiable instances of a class using a loop?

I want to asign data, that I previously read from a simple "backup" text file (txt), to n differentiable instances of a class so that I can use those instances later on. Is there a way to achieve this using some kind of loop?
I tried creating multiple instances c_0, c_1, .. , c_n of a class "Category" which store the "category name" from the corresponding line in a txt file. A line from that file starts with the category name followed by a comma and negligible information. Now I want to have n (= amount of lines) different Category instances every time I call this function in the beginning of the script. Up till now I tried the following:
public class Backup{
static int maxC = 0;
public static void main(String[] args) throws IOException{
readC();
}
public static class Category{
private String categoryName;
public Category(String nameC){
categoryName = nameC;
}
}
private static void readC(){
BufferedReader br = null;
String line = "";
String seperate = ",";
int i = 0;
try{
br = new BufferedReader(new FileReader("C:/Users/Public/Category.txt"));
while((line = br.readLine()) != null){
String[] oneLineArray = line.split(seperate);
Category c_i = new Category(oneLineArray[0]); //I have a strong feeling
//that this only creates c_i and not the c_0 c_1 that I would want here
//How can one achieve that?
i++;
}
}catch(FileNotFoundException e){
System.out.println("File does not exist. "+e.getMessage());
}catch(IOException e){
System.out.println("I/O Error. "+e.getMessage());
}finally{
if (br != null){
try{
br.close();
}catch(IOException e){
System.out.println("I/O Error. "+e.getMessage());
}
}
}
maxC = i-1; //this is the amount (n) of instances created
}
}
Like I said, I expected to have multiple instances but i kinda suspect every cycle of the loop is just c_i and not c_0 etc. Can someone enlighten me? Where did I go wrong?
c_i is just the variable name, i there is just a character like c or _.
You want to create either an array or a collection. java.util.ArrayList collection is the easiest choice, it will store all new objects and dynamical adjust size.
List<Category> categories = new ArrayList<>();
while((line = br.readLine()) != null){
String[] oneLineArray = line.split(seperate);
Category c = new Category(oneLineArray[0]);
categories.add(c);
}

Problems parsing in objects from buffered file and sending to the proper constructors

So i am having trouble wrapping my head around an issue, current working on a midi player that reads a file using buffered reader. i am reading the each object from the file as a string into an array list. Problem is when within the file there can be three different potential objects, the frequency of a note which is double, the midi note value an int, and a the note in letters(c4#). How can i tell which type of object exists in the string object from the ArrayList i have built.
ArrayList<String> noteList = new ArrayList<String>();
Note note;
String file = JOptionPane.showInputDialog("enter the file name of the song");
String line;
try
{
BufferedReader bufread = new BufferedReader(new FileReader("res/"+file));
while((line = bufread.readLine()) != null)
{
String[] result = line.split(",");
for(String str : result)
{
noteList.add(str);
}
}
bufread.close();
}
catch (IOException e)
{
e.printStackTrace();
}
for(int i=0; i<al.size();i++)
{
note = new Note(al.get(i)); //this is where the three constructors should be called
int midiInteger = note.getMIDIAbsoluteNumber();
channels[15].noteOn(midiInteger,127);
Thread.sleep(400);
channels[15].noteOff(midiInteger,127);
}
The constructors are just simple
public Note(double frequency)
{
frequency = this.frequency;
}
public Note(int noteNum)
{
noteNum = this.Note;
}
public Note(String letterNote)
{
letterNote = this.letterNote;
}
How do i differentiate between string or double objects from an array List of type string. I can't tell if i should change to ArrayList and make the object Note serializable or to just test the ArrayList element for a . or isLetter() and go from there or is there a more efficient way.
It seems that regex should do.
Double is different from integer by floating point, test it with /^[0-9]+(\\.[0-9]+)?$ and as for the notes, this could help:
Regex for matching a music Chord

Reading from file and splitting the data in Java

I'm trying to read data from a .txt file. The format looks like this:
ABC, John, 123
DEF, Mark, 456
GHI, Mary, 789
I am trying to get rid of the commas and put the data into an array or structure (structure most likely).
This is the code I used to to extract each item:
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[]args){
try {
FileInputStream fstream = new FileInputStream("courses.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
for (String token : splitOut)
System.out.println(token);
}
in.close();
} catch (Exception e){
System.err.println("Error: " + e.getMessage());
}
}
}
At one point I had a print line in the "while" loop to see if the items would be split. They were. Now I'm just at a loss on what to do next. I'm trying to place each grouping into one structure. For example: ID - ABC. First Name - John. Room - 123.
I have a few books on Java at home and tried looking around the web. There is so much out there, and none of it seemed to lead me in the right direction.
Thanks.
Michael
create a class that looks something like this:
class structure {
public String data1;
public String data2;
public String data3;
}
This will form your basic data structure that you can use to hold the kind of data you have mentioned in your question. Now, you might want to follow proper object oriented methods like declaring all your fields as private, and writting getters and setters. you can find more on there here ... http://java.dzone.com/articles/getter-setter-use-or-not-use-0
Now, just outside your while loop, create an ArrayList like this: ArrayList<structure> list = new ArrayList<structure>(); This will be used to hold all the different rows of data that you will parse.
Now, in your while loop do something like this:
structure item = new structure();//create a new instance for each row in the text file.
item.data1 = splitOut[0];
item.data2 = splitOut[1];
item.data3 = splitOut[2];
list.add(item);
this will basically take the data that you parse in each row, put in the data structure that you declared by creating a new instance of it for each new row that is parsed. this finally followed by inserting that data item in the ArrayList using the list.add(item) in the code as shown above.
I would create a nice structure to store your information. I'm not sure if how you want to access the data, but here's a nice example. I'll go off of what you previously put. Please note that I only made the variables public because they're final. They cannot change once you make the Course. If you want the course mutable, create getters and setters and change the instance variables to private. After, you can use the list to retrieve any course you'd like.
package prerequisiteChecker;
import java.util.*;
import java.io.*;
public class TestUnit {
public static void main(String[] args) {
try {
FileInputStream fstream = new FileInputStream("courses.txt");
// use DataInputStream to read binary NOT text
// DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
List<Course> courses = new LinkedList<Course>();
while ((strLine = br.readLine()) != null) {
String[] splitOut = strLine.split(", ");
if (splitOut.length == 3) {
courses.add(new Course(splitOut[0], splitOut[1],
splitOut[2]));
} else {
System.out.println("Invalid class: " + strLine);
}
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
public static class Course {
public final String _id;
public final String _name;
public final String _room;
public Course(String id, String name, String room) {
_id = id;
_name = name;
_room = room;
}
}
}
public class File_ReaderWriter {
private static class Structure{
public String data;
}
public static void main(String[] args) throws IOException{
String allDataString;
FileInputStream fileReader = new FileInputStream ("read_data_file.txt");
DataInputStream in = new DataInputStream(fileReader);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(in));
String[] arrayString = {"ID - ", " NAME - ", " ROOM - "};
int recordNumber = 0;
Structure[] structure = new Structure[10];
for (int i = 0; i < 10; i++)
structure[i] = new Structure();
while((allDataString = bufferReader.readLine()) != null){
String[] splitOut = allDataString.split(", ");
structure[recordNumber].data = "";
for (int i = 0; i < arrayString.length; i++){
structure[recordNumber].data += arrayString[i] + splitOut[i];
}
recordNumber++;
}
bufferReader.close();
for (int i = 0; i < recordNumber; i++){
System.out.println(structure[i].data);
}
}
}
I modify your given code. It works. Try it and if any query then ask.

Code is only saving one line of a text file to the array

The code I have produced is meant to provide functionality of reading a text file line by line, saving each line into an array. It seems to read in each line correctly but when I use the printProps() method it only displays one...
Code is only saving one line of a text file to the array, what's wrong with my code?
/*reading in each line of text from text file and passing it to the processProperty() method.*/
Public void readProperties(String filename) {
try {
BufferedReader reader = new BufferedReader(new FileReader(filename));
int i = 0;
String line;
line = reader.readLine();
while (line != null && !line.equals("")) {
i++;
processProperty(line);
line = reader.readLine();
}
System.out.println("" + i + " properties read");
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
/*Breaks up the line of text in order to save the value to an array (at this point it only saves one line to the array). org.newProp(newProp) passes the new property to the Organize class where it saves it to an array.
public void processProperty(String line) {
org = new Organize();
int id = nextPropertyID;
nextPropertyID++;
String[] parts = line.split(":");
int propNo = Integer.parseInt(parts[0]);
String postcode = parts[1];
String type = parts[2];
int bedrooms = Integer.parseInt(parts[3]);
int year = Integer.parseInt(parts[4]);
int rental = Integer.parseInt(parts[5]);
Landlord landlord = theLandlord;
Tenant tenant = null;
org.propUniqueCheck(id);
propNoCheck(propNo, postcode);
postcodeCheck(postcode,propNo);
typeCheck(postcode, propNo, type);
bedroomsCheck(bedrooms, postcode, propNo);
yearCheck(propNo, postcode, year);
System.out.println("Creating property " + id);
Property newProp = new Property(id, propNo, postcode, type, bedrooms, year,
rental, landlord, tenant);
org.newProp(newProp);
org.printProps();
}
/*From here down it is the code to save the value to the array*/
public Organize() {
props = new ArrayList<Property>();
PTs = new ArrayList<PotentialTenant>();
waitingList = new LinkedList<String>();
//myList.add(new prop(Property.toString()));
}
public void newProp(Property p)
{
props.add(p);
}
I have actively been seeking help in my seminar with this problem and I can't seem to find a solution, any advice would be very much appreciated!
In processProperty you are instantiating a new Organize object. Therefore, each Property (which you create for each row) is ending up in a different ArrayList (as the first element).
One solution would be to instantiate one Organize object before you start your loop and then pass this into your processProperty method as a parameter.
When one line in your text file is an empty String, your while-loop will break.
This is the right way to implement the loop:
String line = "";
while ((line = reader.readLine()) != null) {
// your code here
}
In processProperty you are instantiating a new Organize object. Therefore, each Property (which you create for each row) is ending up in a different ArrayList (as the first element).
One solution would be to instantiate one Organize object before you start your loop and then pass this into your processProperty method as a parameter.
String line = "";
while ((line = reader.readLine()) != null) {
// your code here
}

Java : Resizing a multidimensional array

I have a multidimensional array built from Strings that is initially created with the size [50][50], this is too big and now the array is full of null values, I am currently trying to remove these said null values, I have managed to resize the array to [requiredSize][50] but cannot shrink it any further, could anyone help me with this? I have scoured the internet for such an answer but cannot find it.
Here is my complete code too (I realise there may be some very unclean parts in my code, I am yet to clean anything up)
import java.io.*;
import java.util.*;
public class FooBar
{
public static String[][] loadCSV()
{
FileInputStream inStream;
InputStreamReader inFile;
BufferedReader br;
String line;
int lineNum, tokNum, ii, jj;
String [][] CSV, TempArray, TempArray2;
lineNum = tokNum = ii = jj = 0;
TempArray = new String[50][50];
try
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please enter the file path of the CSV");
String fileName = in.readLine();
inStream = new FileInputStream(fileName);
inFile = new InputStreamReader(inStream);
br = new BufferedReader(inFile);
StringTokenizer tok,tok2;
lineNum = 0;
line = br.readLine();
tokNum = 0;
tok = new StringTokenizer(line, ",");
while( tok.hasMoreTokens())
{
TempArray[tokNum][0] = tok.nextToken();
tokNum++;
}
tokNum = 0;
lineNum++;
while( line != null)
{
line = br.readLine();
if (line != null)
{
tokNum = 0;
tok2 = new StringTokenizer(line, ",");
while(tok2.hasMoreTokens())
{
TempArray[tokNum][lineNum] = tok2.nextToken();
tokNum++;
}
}
lineNum++;
}
}
catch(IOException e)
{
System.out.println("Error file may not be accessible, check the path and try again");
}
CSV = new String[tokNum][50];
for (ii=0; ii<tokNum-1 ;ii++)
{
System.arraycopy(TempArray[ii],0,CSV[ii],0,TempArray[ii].length);
}
return CSV;
}
public static void main (String args[])
{
String [][] CSV;
CSV = loadCSV();
System.out.println(Arrays.deepToString(CSV));
}
}
The CSV file looks as follows
Height,Weight,Age,TER,Salary
163.9,46.8,37,72.6,53010.68
191.3,91.4,32,92.2,66068.51
166.5,51.1,27,77.6,42724.34
156.3,55.7,21,81.1,50531.91
It can take any size obviously but this is just a sample file.
I just need to resize the array so that it will not contain any null values.
I also understand a list would be a better option here but it is not possible due to outside constraints. It can only be an multi dimensional array.
I think you need 3 changes to your program
After your while loop lineNum will be 1 more than the number of lines in the file so instead of declaring CSV to String[tokNum][50] declare it as CSV = new String[tokNum][lineNum-1];
tokNum will be the number of fields in a row so your for loop condition should be ii<tokNum rather than ii<tokNum-1
The last parameter for your arraycopy should be lineNum-1
i.e. the modified code to build your CSV array is:
CSV = new String[tokNum][lineNum-1];
for (ii=0; ii<tokNum ;ii++)
{
System.arraycopy(TempArray[ii],0,CSV[ii],0,lineNum-1);
}
and the output will then be:
[[Height, 163.9, 191.3, 166.5, 156.3], [Weight, 46.8, 91.4, 51.1, 55.7],
[Age, 37, 32, 27, 21], [TER, 72.6, 92.2, 77.6, 81.1],
[Salary, 53010.68, 66068.51, 42724.34, 50531.91]]
Notice that you don't really need to handle the first line of the file separately from the others but that is something you can cover as part of your cleanup.
10 to 1 this is a homework assignment. However, it looks like you've put somethought into it.
Don't make the TempArray variable. Make a "List of List of Strings". Something like:
List<List<String>> rows = new ArrayList<ArrayList<String>>();
while(file.hasMoreRows()) { //not valid syntax...but you get the jist
String rowIText = file.nextRow(); //not valid syntax...but you get the jist
List<String> rowI = new ArrayList<String>();
//parse rowIText to build rowI --> this is your homework
rows.add(rowI);
}
//now build String[][] using fully constructed rows variable
Here's an observation and a suggestion.
Observation: Working with (multidimensional) arrays is difficult in Java.
Suggestion: Don't use arrays to represent complex data types in Java.
Create classes for your data. Create a List of people:
class Person {
String height; //should eventually be changed to a double probably
String weight; // "
//...
public Person( String height, String weight /*, ... */ ) {
this.height = height;
this.weight = weight;
//...
}
}
List<Person> people = new ArrayList<Person>();
String line;
while ( (line = reader.nextLine()) != null ) {
String[] records = line.split(",");
people.add(new Person (records[0], records[1] /*, ... */));
}

Categories

Resources