Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Okay so I am building a program that will sort grades and records of students. It is a command-line program and when run it will start by asking for user input. there are several commands such as exit(exits program), load [file name](loads a file name), student [student name] (loads student records), etc. the others are not important. Well basically what I am wondering and what I am stuck on is all those functions will be in separate classes and will be called when the user inputs a specific command, but if I put the "load" command in its own class, then how do I get it to share its information with the other classes? I know I have to use BufferReader to read in the files, but how would I go implementing my load class, or if there is a better way feel free to say so. here is my code so far. there isn't much on my other classes because I feel like I need to figure out how to read in and share the file with the other classes first.
import java.util.*;
import java.io.*;
public class program7
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Grade Stats by ");
System.out.print(">");
while(scan.hasNextLine())
{
String input = scan.nextLine();
if(input.equals("exit"))
{
System.exit(0);
}
else if(input.equals("help"))
{
System.out.println("exit - program closes.");
System.out.println("load [filename] - loads a class database specified in [filename].");
System.out.println("students - prints out a list of students from the class, along ");
System.out.println(" with total points, and final grades for each student.");
System.out.println("assignments - prints out a list of assignments from the file, along with points possible");
System.out.println("student [student name] - Prints report for the student");
System.out.print(">");
}
else if(input.contains("load"))
{
String[] split = input.split(" ");
LoadStudents loadStudents = new LoadStudents(split[1]);
loadStudents.getFromFile();
System.out.print(">");
}
else if(input.equals("students"))
{
Students students = new Students();
students.printer();
System.out.print(">");
}
else if(input.equals("assignments"))
{
System.out.print(">");
}
else if(input.contains("student"))
{
String[] split = input.split(" ");
Student student = new Student(split[1]);
System.out.print(">");
}
else if(input.contains("assignment"))
{
}
else if(input.equals("grades"))
{
}
else
{
System.out.println("exit - program closes.");
System.out.println("load [filename] - loads a class database specified in [filename].");
System.out.println("students - prints out a list of students from the class, along ");
System.out.println(" with total points, and final grades for each student.");
System.out.println("assignments - prints out a list of assignments from the file, along with points possible");
System.out.println("student [student name] - Prints report for the student");
System.out.print(">");
}
}
}
}
That is my main class, but here is my Load and Students class.
import java.util.*;
import java.io.*;
public class LoadStudents
{
public String inputFile;
public List<Object> info = new ArrayList<Object>();
public LoadStudents(String inputFile)
{
this.inputFile = inputFile;
}
public List<Object> getFromFile()
{
try
{
BufferedReader in = new BufferedReader(new FileReader(inputFile));
try
{
String line = "";
while(in.readLine() != null)
{
line = in.readLine();
info.add(line);
}
}
catch(IOException e)
{
System.err.println("Exception, man");
}
finally
{
in.close();
}
}
catch(FileNotFoundException e)
{
System.err.println("File wasnt found ");
}
catch(IOException e)
{
System.err.println("Exception, man");
}
return info;
}
}
import java.util.*;
public class Students
{
public Students()
{
}
public void printer()
{
List<Object> info = (new LoadStudents()).getFromFile();
for (int x = 0; x<info.size(); x++)
{
System.out.println(info.get(x));
}
}
}
the Students class isnt finished but I am trying to figure out how to read the list from other classes. I have done research and have seen 3 similar problems, but they there is still something I'm missing because I keep getting the error
.\Students.java:11: error: constructor Load in class Load cannot be applied to g
iven types;
List<Object> info = (new LoadStudents()).getFromFile();
^
required: String
found: no arguments
reason: actual and formal argument lists differ in length
1 error
I understand it wants input, but I want it to use the previous input the user gives it when he inputs the command "input [whateverfile]".
Can anyone tell me how I can call that list my Load class produces to any other class?
There are many ways to do this. My suggestion is that your Load class should be a factory that actually creates a list of Student from the file, and not a list of strings.
Here are more suggestions:
Load class could have all methods statics and it could be non-instantiable. The fields you have in this class are useless after the file is read, you can just pass them to the static method as parameters.
Load is not a nice name for that class. LoadStudents is more meaningful, or even better StudentFactory.
Load and Student probably don't need to be public, package-private are be enough. Same for all the methods in these classes. Always use the lowest visibility possible.
data() is not a nice name for that method either. Something like getStudents(), or if you follow above advice, getFromFile(), is more meaningful.
Always print/log the stacktrace of the exceptions, otherwise you won't even know what/where it happened.
Instead of making the user type the whole commands, put a number on each option and let user select by number, that's faster to type and you avoid typo errors as well.
Only import the classes you're actually working with and not the whole package, that will make the compilation faster (unless you're importing a lot of classes from that package, which is not the case here).
EDIT: since you still don't understand what I mean, here's an example:
class StudentFactory {
private static List<Student> listCache = new ArrayList<>();
static List<Student> getStudents(final String filePath) {
if (listCache.isEmpty() {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader(filePath));
String line;
while((line = in.readLine()) != null) {
// Parse the line and create a Student instance from it, then add it to the list
listCache.add(student);
}
} catch(IOException e) {
System.err.println("Exception, man");
e.printStackTrace();
} catch(FileNotFoundException e) {
System.err.println("File wasnt found ");
e.printStackTrace();
} finally {
if (in != null) in.close();
}
}
return listCache;
}
private StudentFactory() {
// Avoid instantiation
}
}
Then you can just do
final List<Student> listOfStudents = StudentFactory.getStudents(filePath);
from anywhere in your code to get a list of students. filePath can be null if you already passed it previously.
Related
I have a java problem I need to do and i'm not sure how to do it. This is the problem:
Your task is to complete the given program by writing a method named readData and a class named Person.
The readData method is written inside the Customers class. The purpose of the program is to read customer
information from a file called customers.txt, make a new object out of each customer and finally print the information of all customers on the screen.
In the file, each customer is stored on its own line. The file contains the name and social security number of each customer. The Person class has one String-type attribute that stores the person's information (name and social security number).
A toString method must be written inside the Person class, which returns the person's information. The readData method gets an array as a parameter in which the created persons are placed. The purpose of the method is to create an object out of each customer in the file and place it into the array. The method returns the number of people in the file.
That's the instruction (above) and below is the pre-made code that I can't edit (except after the "your code here" part):
import java.io.*;
import java.util.*;
import java.util.Scanner;
public class Customers {
public static void main(String[] args) throws IOException {
Person[] people = new Person[100];
int peopleAmount = readData(people);
for(int i = 0; i < peopleAmount; i++) {
System.out.println(people[i]);
}
}
// Your code here
Example output:
James 030377-2651
John 111177-1731
Robert 161280-1822
Michael 121160-1362
William 141075-16
If too busy to give a full answer, some info on how to make it is fine too. The instruction text wasn't in english originally so sorry if it has weird grammar.
Assuming that the contents of file customers.txt is the same as the example output in your question, here is my implementation. I'm guessing that you can only use classes that you have learned about and I'm also guessing that you have not yet learned about the stream API in java so hopefully the below code is acceptable within the limitations of your assignment.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Customers {
private static int readData(Person[] people) throws IOException {
int count = 0;
if (people != null && people.length > 0) {
try (FileReader fr = new FileReader("customers.txt");
BufferedReader br = new BufferedReader(fr)) {
String line = br.readLine();
while (line != null) {
String[] parts = line.split(" ");
Person p = new Person(parts[0], parts[1]);
people[count] = p;
count++;
if (count >= people.length) {
break;
}
line = br.readLine();
}
}
}
return count;
}
public static void main(String[] args) throws IOException {
Person[] people = new Person[100];
int peopleAmount = readData(people);
for(int i = 0; i < peopleAmount; i++) {
System.out.println(people[i]);
}
}
}
class Person {
String name;
String ssn;
public Person(String name, String ssn) {
this.name = name;
this.ssn = ssn;
}
public String toString() {
return name + " " + ssn;
}
}
Method readData must be a static method since it is called from method main which is a static method.
Method readData reads file customers.txt line by line. Each line contains a name followed by a single space and followed by a social security number. According to your example output both name and social security number contain no spaces. If that is not the case, then the above code will not work.
Method split will create a two element array from a line of the file. The first array element is the name and the second is the social security number. Then I create a Person object and place it in the people array.
I am writing a command line app whereby my main function creates an array list, populates it by user input, and then proceeds to add that content into a txt file. However, every time I run the main function the Array List naturally starts out empty and the data is lost from it.
The user should be able to filter their content by a specific detail(e.g all first names "jane") and have it printed to the terminal/command line. I'd like to keep the data within the file and array list constantly since I am using my getter methods to do this.
My train of thought has been to take the data stored in the file and parse it back into the array list every time the main function has been run. Given that it's a personalized list, I've had trouble doing this. Any help on an approach to help me with this task would be appreciated.
public void writeToFile(String fileName, List<Student> students) {
try {
BufferedWriter printToFile = new BufferedWriter(new FileWriter(fileName, true));
for (Student student: students) {
printToFile.write(student.toString() + "\n");
}
System.out.println("Successfully Written To File!");
printToFile.close();
}
catch (IOException Exception) {
System.out.println("Error: File Not Found");
}
}
public void openFile(String fileName) {
try{
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;
while ((line=reader.readLine())!=null)
{
System.out.println(lin);
}
}
catch (IOException fileNotFound) {
System.out.println("File Not Found.");
}
}
What would have been quite helpful is if you also provided the Students Class code within your Posted Question but in any case.....
Apparently, earlier in your main() method you took User input to fill a List Interface of Student and then I presume you successfully wrote the contents of that List to a Text file. Keep this thought.....
The application closes. Now you restart it and now you want to refill the the List. Well, basically you just need to do pretty much exactly what you did within the main() method.
How you might do this (Not Tested!):
Make sure List<Student> students; is declared as a Class Member variable within the very same Class your main() method is located. This will make the students variable global to the entire Class (among all other things possible). Now add the following method to your main class. This method will fill the students List:
public static int loadStudentData(String fileName) {
// Create a List to hold file data;
List<String> dataList = new ArrayList<>();
// Fill The Data List.
// Use 'Try With Resources' to auto-close the BufferedReader.
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = reader.readLine()) != null) {
// Skip blank lines (if any);
if (line.trim().equals("")) {
continue;
}
dataList.add(line);
}
}
catch (IOException fileNotFound) {
System.out.println("File Not Found.");
}
/*
Now that you have all the Student Data from file you can
Fill in Student instance objects and add them to the students
List Object
Keep in mind, I have no idea what constructor(s) or
what Getters and Setters you have in your Student
Class OR what is contained within the data file so
we'll keep this real basic.
*/
// Declare an instance of Student.
Student student;
// Number of students to process
int studentCount = dataList.size();
// Just in case...clear the students List if it contains anything.
if (students != null || students.size() > 0) {
students.clear();
}
// Iterate through the list holding file data (dataList)
for (int i = 0; i < studentCount; i++) {
student = new Student(); // initialize a new Student
// Assuming each data line is a comma delimited string of Student data
String[] studentData = dataList.get(i).split(",|,\\s+");
student.setStudentID(studentData[0]); // String
student.setStudentName(studentData[1]); // String
student.setStudentAge(Integer.parseInt(studentData[2])); // Integer
student.setStudentGrade(studentData[3]); // String
// Add this instance of Student to the students List.
students.add(student);
}
// Return the number of students processed (just in case you want it).
return studentCount;
// DONE.
}
Note: Don't forget to close your BufferedWriter in your other *writeToFile()** method.
I know this has been asked before, but not in a way I understood, because I am dumb.
So.
I need to take some variables into a class, compare them against something, and then return the higher of the two. In the long run, I need to compare against a running total, but for my problem, I think the issue is considerably more fundamental. I'm not understanding how to pass a variable BACK to my main class.
import java.io.*;
public class testing123 {
public static void main(String[] args) {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
Integer a;
Integer b;
Integer numbersCombined;
try {
System.out.println("Please enter a number");
a = Integer.parseInt(reader.readLine());
System.out.println("Please enter a number");
b = Integer.parseInt(reader.readLine());
numbersCombined = (a + b);
testClass Check = new testClass();
System.out.println("Your numbers combined is " +numbersCombined);
System.out.println(Check);
} catch (IOException e){
System.out.println("Error reading from user");
}
}
}
class testClass {
public static Integer testClass (Integer numbersCombined) {
if (numbersCombined > 100) {
numbersCombined = numbersCombined;
}
else {
numbersCombined = 100;
}
System.out.println(numbersCombined);
return numbersCombined;
}
}
If I remove the return, this will print the numbersCombined, but that's all it does. With the return in place, it doesn't execute the print line above the return, and first prints the original numbersCombined (which it shouldn't if you use, say, 10 and 20, since that's less than 100), and then prints testClass#76046e53 rather than the actual value. I know there's a way to override it, but the answers I've found don't work for me.
I know this answer: http://www.google.com/url?q=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F29140402%2Fhow-do-i-print-my-java-object-without-getting-sometype2f92e0f4&sa=D&sntz=1&usg=AFQjCNGIzxlBSH8xIS7hurKe6_Euc7B8RQ
is the basic problem I'm encountering, but the overrides listed aren't really working for me, and I want integer anyway, rather than string.
In the end, what I'm "really" doing is taking a series of 4 numbers from a user, then using this function to compare whether THIS series of numbers is higher than the previous maximum, and if it is, that's the new maximum moving forward, with a loop until the user is done entering serieses of 4 numbers, and then finally printing the maximum.
I was able to write this without ANY functions, all inline, easy as pie. But once I send the comparison to a function, I don't understand how to send it back, and I've spent all day trying to understand the concept. ALL DAY. So, while I know it's going to be a stupid answer, that's because I'm stupid, but not because I didn't try (sorry, kind of defensive. Frustrated).
Fundamentally, I want to send two (this example is just one) variables to a class, compare them, change ONE of them, and return it to the main class. In this example, I'm just trying to send ONE variable, compare it, and the send it back.
You need to call the method within TestClass. Your code is already returning an integer from that method.
Once you instantiate the class run testClass.testClass(numbers)
The way you're throwing around pseudo-global variables between classes is probably the problem. Pass them through the calls like above, rather than implicitly.
Try to do something like this:
import java.io.*;
public class HelloWorld{
public static void main(String []args){
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(input);
Integer a;
Integer b;
Integer numbersCombined;
try {
System.out.println("Please enter a number");
a = Integer.parseInt(reader.readLine());
System.out.println("Please enter a number");
b = Integer.parseInt(reader.readLine());
numbersCombined = (a + b);
testClass Check = new testClass(numbersCombined); // constructor should be like this
System.out.println("Your numbers combined is " + numbersCombined);
System.out.println(Check);
} catch (IOException e){
System.out.println("Error reading from user");
}
}
}
class testClass {
Integer numbersCombined;
// This is a constructor
public testClass (Integer numbersCombined) {
if (numbersCombined > 100) {
this.numbersCombined = numbersCombined; // use this to represent the object
} else {
this.numbersCombined = 100;
}
System.out.println(numbersCombined);
}
// Add method toString()
public String toString() {
return this.numbersCombined.toString();
}
}
I'm a complete Java novice just starting to learn about collections. I'm attempting to write a program that can take a text file and create a list of objects from the contents of that file. Specifically, I have a class Students in which each student has a first name, last name, and a graduation year. The text file I'm using is of this format:
Tom Blue 2007
Richard Green 1996
Robert Black 2003
Beth White 2005
except with new lines between each student. The problem I'm getting is when I go to create my list, it appears to create a list with multiple instances of whatever the last student is in my list. For example, if I used a file with the four students above, my program creates a list with 4 copies of Beth White 2005. I'm not entirely sure what I'm doing wrong here... I don't think it's a problem with my Scanner, and I'm certain it's not a problem with my print method because I've used the default print method and the same results happen. Here's my code:
import java.io.IOException;
import java.lang.IllegalStateException;
import java.nio.file.*;
import java.util.*;
public class StudentList
{
private static Scanner input;
public static void main(String[] args)
{
Scanner keyInput = new Scanner(System.in);
System.out.println("Please enter the name of the file containing the students.");
String fileName = keyInput.next();
List<Student> studentList = new ArrayList<>(openAndReadFile(fileName));
printList(studentList);
}
private static List<Student> openAndReadFile(String fileName)
{
try
{
input = new Scanner(Paths.get(fileName));
}
catch (IOException ioException)
{
System.err.println("Error opening file. Terminating.");
System.exit(1);
}
List<Student> studentList = new ArrayList<>();
try
{
while (input.hasNext())
{
studentList.add(new Student(input.next(), input.next(), input.nextInt()));
}
}
catch (NoSuchElementException ee)
{
System.err.println("File improperly formed. Terminating.");
}
catch (IllegalStateException se)
{
System.err.println("Error reading from file. Terminating.");
}
if (input != null)
input.close();
return studentList;
}
private static void printList(List<Student> list)
{
for (Student student : list)
System.out.printf("%s%n", student);
}
}
Does the class Student use static fields by any chance?
Using static fields will cause just a single possible value to be assigned per field for all instances of the class, namely the last one assigned. If this is the case remove the static keyword so that the class fields correspond to each instance of Student
In my Java class, we're just now learning about recursion and this is the problem that I'm asked to do. In a text file, there are several lines of employees in this format: Name,Hours,Wage,Boss.
I have a scanner set up and everything works well, except the thing is there is one main boss ("N/A" is what is under his boss field) and then it trees off into different people (in the text file they are not in order.) The task is to print them in order of ranking, ie:
BossName : Wage
--2nd Employee : Wage
----3rd Employee : Wage
-- 4th Employee : Wage
This has to be done recursively, and I'm completely stumped. I just can't find out what to put as the "base case" or how to even start it.
Thanks for any help, it's greatly appreciated.
You need to write a method which finds all employees with a given boss. Then write another method which, given a boss name and a level, finds the boss and pretty prints him/her, then finds all its employees (by calling the 1st method) and recursively calls itself for each employee.
Call this second method from main with "N/A" as the boss name and 1 as level.
well check this simple source code, maybe it will get you started...
import java.io.*;
class test
{
//main method
public static void main (String[] args) throws java.io.IOException
{
String filename = "input.txt";
// Initialize the reader
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filename));
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
//recursive call
myRecursion(reader);
} //end main
//method using recursion to read a file
static void myRecursion(BufferedReader br)
{
String s1 = "";
try {
s1 = br.readLine();
}
catch (IOException e) {
e.printStackTrace();
}
if(s1 == null)
return;
else
{
System.out.println (s1);
myRecursion(br);
return;
}
} //end method
} //end class
The input.txt is:
one
two
three