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
Related
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 am trying to make an program to determine averages for school. I am going to have all the files saved to the computer so its easy to access them for multiple uses. I stated to create multiple methods and discovered a problem. I have the user input for a subject in the startup method but in the main method, sub (the subject string) is used and its says "sub cannot be resolved to a variable" I understand why it say this but I am unsure how to fix.
Here is my code:
public class Calculator {
static int x;
static int b;
public static void startup() {
System.out.println("**Receiving User**");
String user = System.getProperty("user.home");
System.out.println("**Checking Directories**");
boolean dir = new File(user + "/Library/Application Support/Average_Calculator/Settings/").mkdirs();
if (dir) {
System.out.println("**Directory Created at:" + user + "/Library/Application Support/Average_Calculator/**");
} else {
System.out.println("**Directory Has Already Been Created at:" + user
+ "/Library/Application Support/Average_Calculator/**");
}
System.out.println("Welcome to the Average Calculator");
System.out.println("Please input the subject average you want to calculate(no caps)");
Scanner scan = new Scanner(System.in);
String sub = scan.nextLine();
// System.out.println(sub);
try {
// System.out.println("It Does!");
FileOutputStream saveFile = new FileOutputStream(
user + "/Library/Application Support/Average_Calculator/" + sub + ".sav");
ObjectOutputStream save = new ObjectOutputStream(saveFile);
FileOutputStream SetsaveFile = new FileOutputStream(
user + "/Library/Application Support/Average_Calculator/Settings/" + "Setting" + sub + ".sav");
ObjectOutputStream setsave = new ObjectOutputStream(SetsaveFile);
// Create an ObjectOutputStream to put objects into save file.
// Close the file.
save.close();
setsave.close();// This also closes saveFile.
} catch (Exception exc) {
exc.printStackTrace(); // If there was an error, print the info.
}
}
public static void main(String[] args) {
startup();
System.out.println(sub);
try {
// Open file to read from, named SavedObj.sav.
FileInputStream saveFile = new FileInputStream(sub + ".sav");
// Create an ObjectInputStream to get objects from save file.
ObjectInputStream save = new ObjectInputStream(saveFile);
x = (Integer) save.readObject();
b = (Integer) save.readObject();
// Close the file.
save.close(); // This also closes saveFile.
} catch (Exception exc) {
// exc.printStackTrace(); // If there was an error, print the info.
}
// Print the values, to see that they've been recovered.
System.out.println(x);
System.out.println(b);
// All done.
}
}
Thanks for the help!
PS I am new to methods and classes, an explanation would be greatly appreciated!
sub is currently a local variable of startup(), so main() does not have access to it.
One solution is to have startup() return the value of sub, and to have main() use that returned value.
A second solution would be to declare sub (and any other shared variables) as a static variable of the Calculator class, which would place it within the scope of both static methods. In this case, you must no longer declare sub locally within startup(), since that would cause the method to ignore the static variable with the same name.
You are declaring sub in your startup method but trying to access it in your main method. The scope of variables declared in methods is limited to that method; that means that once you leave the method, the variable is no longer accessible. If you want to access a variable both methods one option is to make it a property of the class like you did for x and b. Another option is to return the value of sub at the end of your startup method then simply print your call to the method in main.
Here is a good explanation about classes.
Here is a good explanation about methods (you can ignore the part about functions; the explanation for methods is still good).
Your startup function is returning a void. Change this line:
public static void startup() {
to this:
public static String startup() {
and this line:
startup();
to this:
String sub = startup();
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.
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