java - read file and create array - java

I have to follow a specific format and use scanner. I know there are better methods, but this is a requirement and I am new to java and trying to figure this out. There is a file with customer name, birth date, and other information. I need to count the number of entries in the file, then the file needs to create an array based on the number of file entries and convert the array to a string array. There is more code I need to do, but I am stuck on this part. The try/catch has to be used.
public class Customers {
//////// MAIN ////////
public static void main(String[] args) {
File file = new File("customers.txt");
int numEntries = countCustomers(file);
Person[] customers = readIntoArray(file, numCustomers);
int min = locateBirthdate(customers);
System.out.println("Birthdays this month: " + customer[mon].getBirthdate());
}
//* Counts customers in the file.//
public static int countCustomers(File f) {
int i = 0;
try {
Scanner scan = new Scanner(f);
while (scan.hasNextLine()) {
i++;
scan.nextLine();
}
} catch (Exception e) {
System.out.println("Check filename.");
}
return i;
}
//read data into array and convert into string array
public static Customer[] readIntoArray(File f, int num) {
//num = countCustomers(f);
num = 0;
try {
Scanner input = new Scanner(f);
Customer[] birth = new Customer[num];
String[] strBirth = new String[num];
while (num < countCustomers(f)) {
strBirth[num] = input.nextLine();
birth[num] = makeCustomer(strBirth[num]);
num++;
System.out.println(num);
}
} catch (Exception e) {
System.out.println("Error");
}
return null;

Ok. I have several comments.
First - do you really need 'strBirth' array? Looks like you only write elements but not read from the array.
Second - 'readIntoArray' method always returns null.
Also, you count customers twice, but only one is enough.
Then, do you really need an array with customers? Since you use an array, you need to know exactly the count of customers and therefore you need to scan the file twice. If you use ArrayList, you need to scan file only one time.
I have fixed the issues in the code below.
public class Customers {
//////// MAIN ////////
public static void main(String[] args) {
File file = new File("customers.txt");
Person[] customers = readIntoArray(file, numCustomers);
int numEntries = customers.length;
int min = locateBirthdate(customers);
System.out.println("Birthdays this month: " + customer[mon].getBirthdate());
}
public static Person[] readIntoArray(File f, int num) {
List<Customer> customers = new ArraList<>();
try {
Scanner input = new Scanner(f);
String[] strBirth = new String[num];
while (scan.hasNextLine()) {
customers.add(makeCustomer(scan.nextLine()));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return customers.toArray(Person[]::new);
}

Related

Sorting objects aplhabetically in an Array

import java.io.File;
import java.util.Scanner;
public class MainClass {
public static Winner [] listOfWinners;
public static void loadFromFile()
{
try{
//Create instance of Scanner and provide instance of File pointing to the txt file
Scanner input = new Scanner(new File("WorldSeriesWinners.txt"));
//Get the number of teams
int years = input.nextInt();
input.nextLine();//move to the next line
//Create the array
listOfWinners = new Winner[years];
//for every year in the text file
for(int index = 0; index<years; index++)
{
//Get the year
int year = input.nextInt();
input.skip(" ");
//Get the team
String team = input.nextLine();
//Create an instance of Winner and add it to the next spot in the array
listOfWinners[index] = new Winner(team,year);
}
}catch(Exception e)
{
System.out.println("Something went wrong when loading the file!");
System.out.println(e.toString());
System.exit(0);
}
}
public static void sortByTeamName()
{
}
I've been searching online for a few hours but cannot figure out a way to properly sort the array alphabetically
You could use the following snippet for sorting by Team name, by taking advantage of the comparator feature of the Arrays.sort(arr[],comparator)
Arrays.sort(listOfWinners, new Comparator<Winner>() {
#Override
public int compare(Winner o1, Winner o2) {
return o1.team.compareTo(o2.team);
}
});

How do I read and process a file in a separate method and call it in the main method in Java?

I have this code i'm working on to compute the ARI of a given text read from the a .txt file. This code works perfectly but I want to put in fewer things in my main method. How is it able to put my try and catch block in a new method and then call it to my main method instead of having everything mashed together? I have tried some few ways but i'm not getting the usual output.
Here is my main class:
public class MyClass {
public static void main(String[] args){
String EachSentence;
int wordCount;
List<Sentence> sentences = new ArrayList<>();
List<Integer> EachWordCount = new ArrayList<>();
List<Integer> EachLetterCounted= new ArrayList<>();
try{
File file = new File("a2b.txt");
Scanner scanner = new Scanner(file);
scanner.useDelimiter("[.?!]");
int SentenceCount =0;
while(scanner.hasNext()){
SentenceCount++;
EachSentence = scanner.next();
EachSentence = EachSentence.replaceAll("\\r?\\n", " ");
EachSentence = EachSentence.trim();
if (sentences.add(new Sentence(EachSentence)) && sentences.size() > 1){
System.out.println("(" + SentenceCount + ") " + EachSentence);
}
StringTokenizer tokenizer = new StringTokenizer(EachSentence, " ");
wordCount = tokenizer.countTokens();
if(EachWordCount.add(wordCount)&& EachWordCount.size() > 1){
//I removed the element at position 0 so as to correlate with EachSentence then added the counts to the arrayList
//to prepare them for addition
EachWordCount.remove(0);
EachWordCount.add(wordCount);
}
int LetterCount=1;
for(int i=1; i<EachSentence.length(); i++){
char currentChar = EachSentence.charAt(i);
if(currentChar != ' '&& currentChar!='('&&currentChar!=')'&&currentChar!=','&& currentChar!='.'){
EachLetterCounted.add(LetterCount);
LetterCount++;
}
}
}
scanner.close();
}catch (IOException ex){
System.out.println(ex.getMessage());
}
//Computes the ARI of the total sentences
double lettersCounted = (double) lettersCounted(EachLetterCounted);
double wordsCounted = (double) sum(EachWordCount);
double sentencesCounted = (double) SentencesCounted(EachWordCount);
double AutomatedReadabilityIndex= 4.71*(lettersCounted/wordsCounted) + 0.5 * (wordsCounted/sentencesCounted) -21.43;
System.out.println("\nSummary statistics: ");
System.out.println("Letters: "+lettersCounted(EachLetterCounted));
System.out.println("Words: "+ sum(EachWordCount));
System.out.println("Sentences: " + SentencesCounted(EachWordCount));
DecimalFormat df = new DecimalFormat("#.##");
System.out.println("readability: "+ df.format(AutomatedReadabilityIndex));
}
contributions would be great!
Second time answering my question.(For anyone having the same problem) I achieved this by simply putting everything I had in the main method in a ...static void ReadFile() method and calling only `ReadFile in the main method. It may not be the best way but it was what I was looking for :)
public static void main(String[] args) {
ReadFile();
}
public static void ReadFile() {
//insert all what is in main method, the exceptions were handled
//here also. So there was no need for the throws IOException that
//should've followed.
}
OR
public static void main(String[] args) {
ReadFile(//insert name of file to be read here);
}
public static void ReadFile(String filename) {
//insert all what is in main method, the exceptions were handled
//here also. So there was no need for the throws IOException that
//should've followed.
}

Rewriting .txt to array by scanner

class Materials implements Runnable {
String path;
public Materials(String path) {
this.path = path;
}
public int checkSize() throws FileNotFoundException {
Scanner sc = new Scanner(new File(path));
int size = 0;
while(sc.hasNextLine()) size++;
sc.close();
return size;
}
public void run() {
try {
Scanner sc = new Scanner (new File(path));
int[][] materialsTab = new int[1][checkSize()];
int x=0, count=0;
while(sc.hasNext()){
count++;
materialsTab[x][0] = sc.nextInt();
materialsTab[x][1] = sc.nextInt();
x++;
System.out.println("Im working!");
if(count%200 == 0) System.out.println("Creat " + count + " objects");
}
sc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
My problem is that I have to rewrite .txt file into an array by thread, then comes the next thread, but I got stuck at the first part of the task.
public int checkSize () is responsible for counting the size of the array, because the text file consists of about 10 000 lines. The whole will look exactly like this:
[Product ID] [Weight]
So I decided to count the number of lines and create just such a table, one place where I keep ID, and next to the weight, because later I will have to count a few things.
In addition, every 200 records must appear in the message. The problem is that after starting this part... nothing happens.
Instead of
int[][] materialsTab ...
consider using something roughly like:
List<Point> materialsTab = new ArrayList<Point>();
Point mat = new Point();
mat.x = sc.nextInt();
if (!sc.hasNext())
break;
mat.y = sc.nextInt();
materialsTab.add(mat);
If I'm understanding your problem correctly, try changing Runnable to Callable<int[]> and public void run() to public int[] call() and adding return materialsTab; at the end.

Reading a text file line by line and storing an object in the array

The code I've currently created stores the first line of the text file, creates a new Vehicle object and puts it in the array at the first position of null, and stores the same line in every null value in the array. I need it to be able to:
Store the contents of the first line, then store a new Vehicle object in the first place in the array that is null. Then repeat until there are no more lines.
I believe it is a problem with my for loop.
Note - I am required to use Array instead of ArrayList
public void addVehicle(Vehicle[] Honda) throws FileNotFoundException
{
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length; i++)
{
if(vehicles[i] == null)
{
Scanner reader = new Scanner(file);
Honda[i] = new Vehicle();
Honda[i].readRecord(reader);
vehicles[i] = Honda[i];
reader.close();
}
}
System.out.println("Vehicle Added!");
}
else
{
System.out.println("You can not add more than 4 vehicles.");
}
}
Vehicle class:
public void readRecord(Scanner reader)
{
setMake(reader.next());
setModel(reader.next());
setYear(reader.nextInt());
setvin(reader.next());
setValue(reader.nextDouble());
setMilesDriven(reader.nextInt());
setLastOilChange(reader.nextInt());
}
Data file:
Hyundai Sonata 2010 ABC236347NM2N2NW2 18455.34 8765 7567
Chevy Blazer 1998 1234H32343LMN3423 29556.65 38559 38559
//EDIT\
Constraits: I cannot create any new public methods or constructors, and I cannot have any additional class level data
You're looping within the readRecord method, even though that's meant to only store one object, isn't it?
It's possible that you can just remove the while loop - although that then relies on the addVehicle caller knowing how many entries are in the file.
It seems more likely that you should have a method to read everything from a file, populating a List<Vehicle> and returning it. For example:
public List<Vehicle> readVehicles(String file)
{
Scanner reader = new Scanner(file);
List<Vehicle> vehicles = new ArrayList<Vehicle>();
try
{
while (reader.hasNextLine())
{
vehicles.add(Vehicle.readFromScanner(reader));
}
}
finally
{
reader.close();
}
return vehicles;
}
// In vehicle
public static Vehicle readFromScanner(Scanner scanner)
{
String make = reader.next();
String model = reader.next();
int year = reader.nextInt();
String vin = reader.next();
// Don't use double for currency values
BigDecimal value = reader.nextBigDecimal();
int milesDriven = reader.nextInt();
// Shouldn't this be some sort of date type?
int lastOilChange = reader.nextInt();
// I'll assume you have a constructor like this
return new Vehicle(make, model, year, vin, value, milesDriven,
lastOilChange);
}
Found my solution!
public boolean addVehicle(Vehicle[] Honda) throws FileNotFoundException
{
boolean found = false;
int position = 0;
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length && !found; i++)
{
if(vehicles[i] == null)
{
position = i;
found = true;
}
}
Scanner reader = new Scanner(file);
while(reader.hasNext())
{
Honda[position] = new Vehicle();
Honda[position].readRecord(reader);
vehicles[position] = Honda[position];
position++;
}
reader.close();
return true;
}
return false;
}

java array passing, I keep getting the last array everywhere

I am having a problem in this code. what i am trying to do is read a file and store a studentID and score into an array of scores into the scores property of a student object, but I keep getting the last scores only when I print. Here is the code. can you tell me if my setter property is a correct way of assigning an array in the student class? the problem is the last line of the score file is stored in every array even though when I debug it I see the score array being passed and the studentID array works fine.
import lab6.*;//importing the necessary classes
public class Main
{
public static void main(String[] args)
{
Student lab6 [] = new Student[40];
//Populate the student array
lab6 = Util.readFile("studentScores.txt", lab6);
lab6[4].printStudent();
}
}
The student class------------------------------------
package lab6;
public class Student
{
private int SID;
private int scores[] = new int[5];
//write public get and set methods for SID and scores
public int getSID()
{
return SID;
}
public void setSID(int SID)
{
this.SID = SID;
}
public int[] getScores()
{
return scores;
}
public void setScores(int scores[])
{
this.scores = scores;
}
//add methods to print values of instance variables.
public void printStudent()
{
System.out.print(SID);
System.out.printf("\t");
for(int i = 0; i < scores.length; i++)
{
System.out.printf("%d\t", scores[i]);
}
}
}
the util class --------------------------------------------------------------------
import java.io.*;
import java.util.StringTokenizer;
//Reads the file and builds student array.
//Open the file using FileReader Object.
//In a loop read a line using readLine method.
//Tokenize each line using StringTokenizer Object
//Each token is converted from String to Integer using parseInt method
//Value is then saved in the right property of Student Object.
public class Util
{
public static Student [] readFile(String filename, Student [] stu)
{
try {
String line[] = new String[40];//one line of the file to be stored in here
StringTokenizer stringToken;
int studentID;//for storing the student id
int[] studentScoreArray = new int[5];//for storing the student score
FileReader file = new FileReader(filename);
BufferedReader buff = new BufferedReader(file);
boolean eof = false;
int i = 0;
buff.readLine();//used this to skip the first line
while (!eof) //operation of one line
{
line[i] = buff.readLine();
if (line[i] == null)
eof = true;
else //tokenize and store
{
stringToken = new StringTokenizer(line[i]);
String tokenID = stringToken.nextToken().toString();//for storing the student id
studentID = Integer.parseInt(tokenID);
stu[i] = new Student();//creating student objects
stu[i].setSID(studentID);//stored in student object
//now storing the score-------------------------------------------------
int quizNumberCounter = 0;
while (stringToken.hasMoreTokens())
{
String tokens = stringToken.nextToken().toString();
studentScoreArray[quizNumberCounter] = Integer.parseInt(tokens);//converting and storing the scores in an array
quizNumberCounter++;//array progression
}
stu[i].setScores(studentScoreArray);//setting the score(passing it as an array)
//-----------------------------------------------------------------------
}
i++;
}
buff.close();
} catch (IOException e) {
System.out.println("Error -- " + e.toString());
}
return stu;
}
/*
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
//How to convert a String to an Integer
int x = Integer.parseInt(String) ;*/
}
Sample file Structure -------------------------------------------------------
4532 011 017 081 032 077
The issue lies within the line
int[] studentScoreArray = new int[5];
You'll have to move this one inside your student loop and initialize the array per student. Otherwise you are reusing the same array (i.e. memory) for all students and you are overwriting scores over and over again.
// int[] studentScoreArray = new int[5]; // <= line removed here!!!
...
while (!eof) //operation of one line
{
line[i] = buff.readLine();
if (line[i] == null)
eof = true;
else //tokenize and store
{
int[] studentScoreArray = new int[5]; // <= line moved over to here!!!
...
}
}
I havent tested the code with my suggestion, but take a look at:
int[] studentScoreArray = new int[5];
You create this once and once only for the whole file.
A simple and easy fix is to do it for every new line read instead.
like this :
int[] studentScoreArray = new int[5];
int quizNumberCounter = 0;
while(..) { ...}
One reason you may only being seeing one line of results is that you are only printing one line of results:
lab6[4].printStudent();
You will need to change this to loop through the array if you want to see all the results:
foreach (Student student : lab6)
{
student.printStudent();
}
On a side note, your array should probably be called something like students instead of lab6. Also it is idiomatic in java to declare arrays using Type[] identifier rather than Type identifier [].
DISCLAIMER: There may be other stuff wrong, I didn't read all the hundreds of lines posted!

Categories

Resources