I am writing a program that will read a file and extract the data for each student. I did this successfully with a while loop and input.next(). However, I need to pass the variables into a collection to record each students data, so for each loop I want to add the 4 variables (id, first, last, year) to the collection again. I should note that the collection has to be in a different class and that I will have to be able to search through this collection to find, for example, all students graduating this year.
If anyone could point me in the right direct in regard to storing the variables in a collection, which is in a different class, for each loop.
I know this is a basic question but I am very new to Java so I appreciate everyone’s help!
The first class is
import java.util.*;
import java.io.*;
import java.lang.*;
public class ProcessRecords {
public static void AskUser()
throws Exception {
Scanner preference = new Scanner(System.in);
//Creating a new scanner will allow us to gather user input
boolean flag=true;
//I will use this for my while loop
while (flag) {
System.out.println("What type of Search would you like to run?\n 1)Search for all students\n 2) Search for students graduating in a specific year\n 3)Search for students whose last name begins with a certain string\n");
int searchType=preference.nextInt();
//This variable will store what type of query the user would like to run
switch(searchType) {
case 1:
System.out.println("Gathering Records for all students\n");
//Call Query Method in the Query Class to return all students in the colletion
case 2
System.out.println("What graduation year would you like to search for? \n");
String yearsearch=preference.next();
//Call Query Method to return students who are graduating in the specified year
//Pass the "yearsearch" variable to the Query class to run the search
case 3:
System.out.println("What string would you like to search for? \n");
String lstsearch=preference.next();
//Call Query Method in the Query Class to return students who have the string in their last name
//I need to pass the "lstsearch" variable to the Query class to search through last names
}
}
}
public static void main(String[] args)
throws Exception
{
Scanner input = new Scanner(new File("students.txt"));
//This will import the file
input.nextLine();
//This will skip the headers in the file
System.out.println("Processing file now...");
//Let the user know that the file is being processed
int id;
String last;
String first;
int year;
int i=1;
// Declare variables that we will extract from the file
//Now we will being processing the file with a while loop
List<StudentRecord> studentRecords = new ArrayList<StudentRecord>();
while(input.hasNext())
{
id=input.nextInt();
last=input.next();
first=input.next();
year=input.nextInt();
StudentRecord record = new StudentRecord(id, last, first, year);
studentRecords.add(record);
System.out.println(id + " " + last + " " + first + " " + year + "\n");
}
System.out.println(" You have successfully read and printed from the file!");
for (StudentRecord s : studentRecords)
System.out.println(s.toString());
}
}
The next Class is
public class StudentRecord{
public int id;
public String last;
public String first;
public int year;
public StudentRecord(int d, String lt, String ft, int yr){
id=d;
last=lt;
first=ft;
year=yr;
}
public String toString()
{
return id + " " + last + " " + first + " " + year;
}
}
Thanks!
Change the second class:
public class StudentRecord
{
public int id;
public String last;
public String first;
public int year;
public StudentRecord(int d, String lt, String ft, int yr)
{
id=d;
last=lt;
first=ft;
year=yr;
}
public string toString()
{
return id + " " + last + " " + first + " " + year;
}
}
The method is called constructor and you can create instances of this class using it.
In your second class, while running through the loop, you can create new StudentRecord object with actual values for each entry by passing parameters to the constructor:
List<StudentRecord> studentRecords = new ArrayList<StudentRecord>();
while(input.hasNext())
{
id=input.nextInt();
last=input.next();
first=input.next();
year=input.nextInt();
StudentRecord record = new StudentRecord(id, last, first, year);
studentRecords.Add(record);
System.out.println(id + " " + last + " " + first + " " + year + "\n");
}
The ArrayList will serve you as a storage of all StudentRecord objects.
If you override the toString method of your StudentRecord object (as I did above), you can print all student records to the console in a loop:
for (StudentRecord s : studentRecords)
System.out.println(s.toString());
Is there anything wrong with making an ArrayList of StudentRecord objects?
public class StudentRecord {
public int id;
public String last;
public String first;
public int year;
public StudentRecord(int id, String last, String first, int year) {
this.id = id;
this.last = last;
this.first = first;
this.year = year;
}
}
Then right after you grab the values from a file:
ArrayList<StudentRecord> studentRecords = new ArrayList<StudentRecord>();
//...
id = input.nextInt();
last = input.next();
first = input.next();
year = input.nextInt();
studentRecords.add(new StudentRecord(id, last, first, year));
//...
Related
I've created a class that includes people data named "Datiutente" and an object based on that class named "du". Every person has a name and a surname (with the set/get methods).
I want to create a system that can provide the user information on a specific person based on the position which they are stored in the array.
I tried using a variable named vd to ask the user which person wanted to visualize based on the position that a person gained in the array (inserted in the for cycle), but when I try to print with vd it just prints "Name: null". Same if I change "vd" to "1". It always prints "Null".
(Yes, I tested this when I already inserted some data.)
Here's the full code:
package appartamento;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Appartamento {
public static void main(String[] args) throws IOException {
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader keyb = new BufferedReader(input);
boolean attiva = true;
do {
System.out.println("what do you want to do?");
System.out.println("1 - check for a person");
System.out.println("2 - Add person");
int choice = Integer.parseInt(keyb.readLine());
Datiutente du[] = new Datiutente[10];
if (choice == 2){
System.out.println("How many people?");
int hm = Integer.parseInt(keyb.readLine());
for (int i=0;i<hm;i++){
du[i] = new Datiutente();
System.out.println("insert name:");
du[i].setName(keyb.readLine());
System.out.println("insert surname");
du[i].setSurname(keyb.readLine());
}
}
if (choice == 1){
System.out.println("which person are you searching?");
int vd = Integer.parseInt(keyb.readLine());
System.out.println("position: " + i);
System.out.println("Name: "+ du[i]);
System.out.println("Surname: " + du[i]);
}
} while (attiva = true);
}
}
and the class "Datiutente":
package appartamento;
public class Datiutente {
private String name;
private String surname;
private String codfis;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setSurname(String surname){
this.surname = surname;
}
public String getSurname(){
return surname;
}
}
In every iteration you define the Datiutente du[] = new Datiutente[10];, so du is reset to {null,...,null} and the data saved in the previous iteration are replaced;
Try to define the array before the loop statement.
I found a way here:
You need to insert values on object creation, you can also use hashmaps
hashmap will benefit you more I think.
Code sample to fix your stuff.
class GFG {
public static void main(String args[]){
// Declaring an array of student
Student[] arr;
// Allocating memory for 2 objects
// of type student
arr = new Student[2];
// Initializing the first element
// of the array
arr[0] = new Student(1701289270, "Satyabrata");
// Initializing the second element
// of the array
arr[1] = new Student(1701289219, "Omm Prasad");
// Displaying the student data
System.out.println(
"Student data in student arr 0: ");
arr[0].display();
System.out.println(
"Student data in student arr 1: ");
arr[1].display();
}
}
class Student {
public int id;
public String name;
// Student class constructor
Student(int id, String name)
{
this.id = id;
this.name = name;
}
// display() method to display
// the student data
public void display()
{
System.out.println("Student id is: " + id + " "
+ "and Student name is: "
+ name);
System.out.println();
}
}
I'm trying to use menu loop than when I finish the first choice an I want to get data in choice 2.
It can't get, this is an error.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:373)
at java.base/java.util.ArrayList.get(ArrayList.java:425)
at craitid_19.main(craitid-19.java:38)
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class craitid_19{
public static void main(String [] args){
while(true){
System.out.println("1 - Insert");
System.out.println("2 - Edit");
System.out.println("3 - View");
System.out.println("4 - Exit");
Scanner input = new Scanner(System.in);
int choice = input.nextInt();
infected patient = new infected();
switch (choice){
case 1:
System.out.print("ID = ");
int id = input.nextInt();
System.out.print("name = ");
String name = input.next();
System.out.print("age = ");
String age = input.next();
System.out.print("gender = ");
String gender = input.next();
System.out.print("date = ");
String date = input.next();
System.out.print("province = ");
String province = input.next();
System.out.print("infectby = ");
String infectby = input.next();
patient.children.add(new normal(id, name, age, gender, date, province, infectby));
System.out.print(patient.toString());
continue;
case 2:
System.out.println("Insert ID");
System.out.print(patient.children.get(0));
case 4:
System.out.println("Exiting Program...");
System.exit(0);
break;
default :
System.out.println("This is not a valid Menu Option! Please Select Another");
break;
}
}
}
}
class infected {
public int id;
public String name;
public String age;
public String gender;
public String date;
public String province;
public String infectby;
public String type;
public List<infected> children = new ArrayList<>();
public infected(){
}
#Override
public String toString()
{
String returnString = id + (",") + name + (",") + age + (",") + gender + (",") + date + (",") + province + (",") + infectby + (",") + type + System.lineSeparator();
for (infected child : children)
returnString = child.toString() + System.lineSeparator();
return returnString;
}
}
class normal extends infected{
public normal(int id, String name, String age, String gender, String date, String province, String infectby){
type = "1";
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.date = date;
this.province = province;
this.infectby = infectby;
}
}
Your problem is that you create infected patient inside of while loop. This means you override the data you created every time when you answer the menu. The error actually says that you patient.children List is empty, while you are trying to get the 0 element. So I recommend:
Move initialization of patient object out of while loop (just put it before while).
Check if the list is not empty before you try to read data from it.
Use Java naming convention for classes (they should start from uppercase letter - Infected instead of infected an so on) - this will make your code much more readable.
First you have to replace continue; by break; Then, between line 4 and 5 you have to add this:
infected patient = new infected();
This will call just once the class and the class' constructor, if you want to call the constructor of the class each time the loop repeats you just add
infected patient,
And in the line 13 you replace what you have for:
patient = new infected();
What's the difference between calling the constructor just once or each time the loop repeats?
In the first case, when you add a patient it will remain until you close the program,
In the second case, each time the loop repeats, the patient you added before will be lost.
Choose wisely.
You also should use the Java name convention, the first letter of the classes' name must be uppercase.
In my Main class I have this piece of code:
UUID uniqueID;
public void createEmployee(){
uniqueID = UUID.randomUUID();
// ...
}
In my class Corporation there's a method called promoteEmployee, which should receive the uniqueID as parameter. Is that possible, and when yes, how?
public void promoteEmployee(uniqueID){
// it doesn't recognize uniqueID as argument
}
I also have the method sortEmployees, which sorts the ArrayList alphabetically, and if two names are equal, the employee with a higher salary should be printed out first. It sorts the List alphabetically, but doesn't check if the salary is bigger. What do I need to change?
ArrayList<Employee> employees = new ArrayList<Employee>();
public void sortEmployees(){
Collections.sort(employees, (p1, p2) -> p1.name.compareTo(p2.name));
for(Employee employee: employees){
Comparator.comparing(object -> employee.name).thenComparingDouble(object -> employee.grossSalary);
System.out.println("ID: " + employee.ID + END_OF_LINE + "Name: "+employee.name + END_OF_LINE + "Salary: " + employee.grossSalary);
System.out.println(""); // just an empty line
}
}
Change the method to be valid java code
public void promoteEmployee(UUID uniqueID){
but as it even seems to be a field, why pass the value at all?
As for sorting see
Implementing Java Comparator
one passes variables from one class to another's methods by using the classname.method(arg) syntax.
public class JavaTeachMe2018
{
//variable in other class to be passed as a method argument
public static int startID = 0;
public static void main(String[] args)
{
// we are passing startID to anouther class's method
String[] currentEmployees = Corporation.createEmployee(startID);
System.out.println("Welcome " + currentEmployees[1] + " to the company as employee number " + currentEmployees[0]);
}
}// end class teachme
here is the second class
import java.util.Scanner;
public class Corporation
{
public static int createId(int startID)
{
// create unique id
int uniqueID = startID + 1;
return uniqueID;
}
public static String[] createEmployee(int startID)
{
// assign a variable to the return of the createId call
int employeeNumber = createId(startID);
System.out.println("Your assigned employee number is " + employeeNumber);
// get employee name
Scanner stdin = new Scanner(System.in);
System.out.print(" Enter Your Name : ");
String employeeName = stdin.nextLine();
String employees[] = {Integer.toString(employeeNumber), employeeName};
return employees;
}
}
Hi I'm very new to programming and I'm trying to write a programme in eclipse that does the following.
Create a Student class with 4 attributes: name, mark, course and phone number which are entered by the user.
Have a constructor which initialises those four attributes to the parameters passed in, and a display() method which displays the details of the Student.
Declares an empty array of 5 Student objects.
Create a Student object at the current position of the array using these variables.
Make a loop which calls the display() method of each Student in the array.
So far I've got the programme working to the point that it creates the array of 5 students and reads in the four different attributes from the user. But I can not figure out how to create a loop which calls the display method for each of the students.
This is my code so far..
import java.util.Scanner;
public class Student {
private String name, course;
private int mark, number;
public Student(String nameIn, String courseIn, int markIn, int numberIn)
{
this.name = nameIn;
this.course = courseIn;
this.mark = markIn;
this.number = numberIn;
}
public void display()
{
System.out.println("Name: " + this.name + " Course " + this.course + " mark: " + this.mark + " Number " + this.number);
}
public static void main (String[] args)
{
String[] Student = new String[5];
Scanner scanner = new Scanner(System.in);
for (int counter=0; counter< 5; counter++)
{
System.out.println("Enter name for student " + counter);
Student[counter] = scanner.nextLine();
System.out.println("Enter course for student " + counter);
Student[counter] = scanner.nextLine();
System.out.println("Enter mark for student " + counter);
Student[counter] = scanner.nextLine();
System.out.println("Enter number for student " + counter);
Student[counter] = scanner.nextLine();
}
for (int counter=0; counter< 5; counter++)
{
System.out.println(Student[counter].display());
}
}
}
PS sorry in advance if I have posted this question wrong. Its my first post and I couldn't find a similar question else where.
Thanks in advance.
Your current code doesn't create an array of Student, nor populate it correctly (each loop overwrites the former data) .
Also, the way you were calling display was wrong :
System.out.println(Student[counter].display());
First, you want to call display on an instance of Student, not on the class.
Second, you don't have to call System.out.println, because displayalready does this work (and calling System.out.println with the void parameter, because the display method returns nothing, will get you nowhere)
Try this way :
Student[] students = new Student[5];
for (int counter=0; counter< 5; counter++)
{
System.out.println("Enter name for student " + counter);
String name = scanner.nextLine();
System.out.println("Enter course for student " + counter);
String course = scanner.nextLine();
System.out.println("Enter mark for student " + counter);
String mark = scanner.nextLine();
System.out.println("Enter number for student " + counter);
String number = scanner.nextLine();
Student student = new Student(name, course, mark, number);
students[counter] = student;
}
for (int counter=0; counter< students.length; counter++)
{
students[counter].display();
}
i am currently using inheritance and as you can see below, i have two classes, the person and the passenger. In the person i have the main toString() method and in the passenger i call a super.toString() and add the new info, priority booking/noOfBags and the ID. The problem i have is, when the user adds a new passenger to the array, when you print the array the data isn't in the same format as entered. I am pretty sure that i have called everything correctly and im not 100% sure why just the name aspect of the toString messes up (notice that the DOB/ID/noOfBags and priority booking all formatted correctly). If anyone can point me as to why just the name is printing incorrectly it would be greatly appreciated.
Code
This is the constructor in the main class Person
public Person()
{
name = new Name();
dateOfBirth = new Date();
}
public Person(String titleIn, String firstNameIn, String surNameIn, int day, int month, int year)
{
name = new Name(titleIn, firstNameIn, surNameIn);
dateOfBirth = new Date(day, month, year);
}
Here is the method i use to get the Name and DOB details of the new passenger
public void read()
{
try
{
Scanner kbInt = new Scanner(System.in);
Scanner kbString = new Scanner(System.in);
System.out.println("***Passenger Details: ***");
System.out.print("Title : ");titleRead=kbInt.nextLine();
System.out.print("First Name : ");FNameRead=kbString.nextLine();
System.out.print("Surname : ");SNameRead=kbString.nextLine();
name = new Name(titleRead, FNameRead, SNameRead);
System.out.println("\n");
System.out.println("***Date of Birth: ***");
System.out.print("Day : ");dayRead=kbInt.nextInt();
System.out.print("Month : ");monthRead=kbInt.nextInt();
System.out.print("Year : ");yearRead=kbString.nextInt();
dateOfBirth = new Date(dayRead, monthRead, yearRead);
}
catch (InputMismatchException e)
{
System.out.print("Incorrect input, please input data in the correct format!");
}
}
And finally for the person class, here is the toString
public String toString()
{
String nameAndAge = "Name = " + name + ", DOB = " + dateOfBirth;
return nameAndAge;
}
In the passenger class which inherits from Person, here is the arraylist being made and the constructor
private ArrayList<Passenger> passengers = new ArrayList<Passenger>();
//Constructor
public Passenger()
{
noOfBags = 0;
priorityBoarding = false;
id = nextid++;
}
//Initiliaze constructor
public Passenger(String titleIn, String firstNameIn, String surnameIn, int day, int month, int year, int bag, boolean pb)
{
super(titleIn, firstNameIn, surnameIn, day, month, year);
noOfBags = bag;
priorityBoarding = pb;
}
Here i add the reading of the noOfBags and priority boarding and add it to the read method in person
public void bagsPriorityRead()
{
Scanner kbInt = new Scanner(System.in);
Scanner kbString = new Scanner(System.in);
super.read();
System.out.print("Number of bags : ");bagsRead=kbString.nextInt();
System.out.print("Priority boarding (Y/N) : ");priorityRead=kbString.next().charAt(0);
}
Finally, here is the toString method in passenger
//ToString Method
public String toString()
{
return " ID: " +id + " - " + super.toString() + " \tNo of Bags: " +bagsRead + "\tDo they have priority boarding? : " +priorityRead;
}
//Added images of the adding in action and the way it is improperly formatted when printing
//Improper formatting when printing
As stated above, if anyone could point to where im going wrong/how to fix my error it would be greatly appreciated. If any more code may be needed to find the source of the problem just let me know.
Thanks in advance,
Jason
Looks like the problem, if anywhere, would be in Name::toString() or that the order of the parameters are wrong in new Name(x, y, z)
String nameAndAge = "Name = " + name + ", DOB = " + dateOfBirth;
But you haven't posted the Name class.