Storing Objects in Linked List - java

I am creating a simple program which reads data from a text file and displays it in the console. The data that I am displaying is information regarding a student - name, id, subject, marks etc
The program reads the text file, and creates a student object for each user found. I am running into a problem when trying to store these students in a linked list. It seems to create a new list each time and overrides the previous one, so I always just end up with one student in the list.
How can I get it store them without overriding previous lists? Here is some of my code below:
public static boolean readFile(String filename) {
File file = new File(filename);
try {
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()){
String[] words = scanner.nextLine().split(",");
int id = Integer.parseInt(words[0]);
String firstName = words[1];
String lastName = words[2];
int mathMark1 = Integer.parseInt(words[3]);
int mathMark2 = Integer.parseInt(words[4]);
int mathMark3 = Integer.parseInt(words[5]);
int englishMark1 = Integer.parseInt(words[6]);
int englishMark2 = Integer.parseInt(words[7]);
int englishMark3 = Integer.parseInt(words[8]);
addStudent(id,firstName,lastName,mathMark1,mathMark2,mathMark3,englishMark1,englishMark2,englishMark3);
}
scanner.close();
} catch (FileNotFoundException e) {
System.out.println("Failed to read file");
}
return true;
}
private static void addStudent(int id, String firstName, String lastName,int
mathsMark1, int mathsMark2, int mathsMark3, int englishMark1, int englishMark2,
int englishMark3) {
LinkedList<Student> student = new LinkedList<>();
student.add(new Student(id,firstName,lastName));
LinkedList<AssignmentMarks> mathematicsMarks = new LinkedList<>();
mathematicsMarks.add(new AssignmentMarks("Mathematics",mathsMark1,mathsMark2,mathsMark3));
LinkedList<AssignmentMarks> englishMarks = new LinkedList<>();
englishMarks.add(new AssignmentMarks("English",englishMark1,englishMark2,englishMark3));
}
This code above is in my Main class. The code below is from my Student class:
public class Student {
private int id;
private String firstName;
private String lastName;
private AssignmentMarks mathMarks;
private AssignmentMarks englishMarks;
public Student(int id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public String getFullName() {
return firstName;
}
}
Any help would be appreciated thanks guys!

This variable
LinkedList<Student> student = new LinkedList<>();
needs to declared outside of the method, as a field, or within readFile and passed in as a parameter, otherwise it will be created everytime that you call addStudent

Declare your LinkedList as a member of the class, because here every time you call addStudent() you are creating a new list.
You should instead do something like :
public class Test {
private LinkedList<Student> student = new LinkedList<>();
public static boolean readFile(String filename) {
// ...
addStudent(id,firstName,lastName,mathMark1,mathMark2,mathMark3,
englishMark1,englishMark2,englishMark3);
}
private static void addStudent(int id, String firstName, String lastName,int
mathsMark1, int mathsMark2, int mathsMark3, int englishMark1, int englishMark2,
int englishMark3) {
// ...
// this will now add it to the only instance of the list
student.add(new Student(id,firstName,lastName));
}
}

Related

Java reading CSV file that contains Strings and Integers adding them to arraylist and then instantiating arraylist

SO, here goes my choppy explanation of my choppy title.
I have a csv file, and it contains, at the moment
id,name,hp,atk,def,desc
1,Man,10,5,5,A man
2,Woman,10,5,5,A woman
3,Goblin,15,7,3,A goblin ack!
I am trying to take the information from this csv file, send it to an ArrayList, instantiate the ArrayList using the Constructor I have for NPCs so that later on I can use these NPCs as objects -- if that makes sense.
I think I have like some of this done already, I just don't know how to read integers from the CSV file.
public class NPCLoader {
private static final String dir = "./data/npcs.csv";
public static ArrayList<NPCHandler> npcs = new ArrayList<NPCHandler>();
public static void main(String args[]) {
loadNpcs();
}
private static void loadNpcs() {
BufferedReader br = new BufferedReader(new FileReader(new File(dir)));
String line = null;
while((line = br.readLine()) != null) {
String[] n = line.split(",");
NPCHandler npc = new NPCHandler(n[0], n[1], n[2], n[3], n[4], n[5]);//issue is here, it wants me to change my constructor to String String String String String when it needs to be int String int int int String
npcs.add(npc);
}
}
}
Here is my constructor for the NPCHandler if you need to see it
public class NPCHandler {
private int id;
private String name;
private int hp;
private int atk;
private int def;
private String desc;
public NPCHandler(int id, String name, int hp, int atk, int def, String desc) {
this.id = id;
this.name = name;
this.hp = hp;
this.atk = atk;
this.def = def;
this.desc = desc;
}
//Get setters below
I think that since you're loading a csv file, every variables are considered strings.
The solution could be to parse some of them to Integer, something like that:
NPCHandler npc = new NPCHandler(Integer.parseInt(n[0]),
n[1],
Integer.parseInt(n[2]),
Integer.parseInt(n[3]),
Integer.parseInt(n[4]),
n[5]);
Reference for string conversion

The constructor is undefined error when trying to make new object

just check out my code, why is this not working? just trying to create new student object using the Student method.
public class Student {
public String id, first_name,last_name;
//assuming it was subject grades
public String[] subject_grades;
public void Student(String id, String first_name, String last_name, String[] subject_grades) {
this.id = id;
this.first_name = first_name;
this.last_name = last_name;
this.subject_grades = subject_grades;
}
public static boolean readFile(String filename) { File file = new File(filename);
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
List<Student> list = new ArrayList<>();
String[] words = scanner.nextLine().split(",");
new Student(words[0], words[1], words[2],
new String[] {words[3], words[4], words[5], words[6], words[7], words[8]}
));
}
} catch (FileNotFoundException e) {
System.out.println("Failed to read file");
}
return true;
}
}
the constructor is undefined.
public void Student(String id,String first_name,String last_name,String[] subject_grades) {
This is not a constructor. It is a void method called Student.
Change it to
public Student(String id,String first_name,String last_name,String[] subject_grades) {

Displaying Group Name with Group Members

I am trying to solve an assignment in my Java class. I am stuck and need a little help.
I am trying to create a method in my Group class that will display the group name and the 4 students in the group. My code currently displays the group name and the memory location of my student inside my array.
public class Group {
/**-------Declaring attributes----*/
String groupName;
int newStudentCount;
/**----------------------------*/
/**--------Constructor------------*/
public Group(String givenGroupName) {
groupName = givenGroupName;
}
Student[] students = new Student[4];
/**----------------------------*/
/**--------Method------------*/
void addStudent(Student st) {
students[newStudentCount] = st;
++newStudentCount;
System.out.println("New student: " +st.getName());
}
public String getGroup() {
return "Group = " + groupName;
}
public Student getStudent(){
return students[0];
}
}
In my App class I have this:
public class App {
public static void main(String[] args) {
Group g1 = new Group("Pink Pony Princesses");
Student st1 = new Student("Joshua Mathews");
st1.getName();
g1.addStudent(st1);
Student st2 = new Student("Jame Brooks");
g1.addStudent(st2);
Student st3 = new Student("Mike Myers");
g1.addStudent(st3);
Student st4 = new Student("Christie Richie");
g1.addStudent(st4);
System.out.println(g1.getGroup()+ " " + g1.getStudent());
}
This is my Student class:
public class Student {
/**-------Declaring attributes----*/
String name;
String degree;
int age;
/**----------------------------*/
/**--------Constructor------------*/
Student(String givenName){
name = givenName;
}
Student(String givenName, String givenDegree, int givenAge) {
name = givenName;
degree = givenDegree;
age = givenAge;
}
/**--------- METHODS --------*/
//Array
public final String [] activities = {
"Working on Homework", "Playing a Game", "Taking a Nap"
};
String getInfo(){
return name + age + degree;
}
String getName() {
return name;
}
int getAge(){
return age;
}
String getDegree() {
return degree;
}
String whatsUp(){
Random rand = new Random();
int randomIndex = rand.nextInt(activities.length);
String returnActivity = activities[randomIndex];
return returnActivity;
}
I'm not sure how to call my array to display the 4 names, and not the memory location of them. Any help would be greatly appreciated.
I can deduce a couple of things from your question.
First, you are returning only the student at index 0 of the Student array held within your Group object. If you want to return all students your method signature should have a Student[] as the return type rather than a Student object.
If you follow the above prompt then you will have to iterate through the returned array printing each Student object.
Regardless of which implementation you choose the reason you print out a memory reference rather than a String object is that you have not overridden toString within your Student class.
Something like this will print out Student data when passed to a System.out call:
#Override
public String toString() {
return someStudentData;
}
You can go with what andrewdleach said by implementing toString(). OR
To print all student names your method should be something like:
public String getStudent(){
String studentNames = "";
for(Student stu: students){
studentNames+= stu.getName() + ",";
}
return studentNames;
}

How to create a search method for an array

My code is as follows:
import java.io.*;
import java.util.*;
public class readStudents extends Object
{
private String SName = "";
private String DoB = "";
private String Gender = "";
private String Address = "";
Student [] students = new Student[20];
public void fillStudentArray()
{
// properties
int size; // total number of Students in collection
File file = new File("StudentDetails.txt");
try
{
Scanner in = new Scanner(file);
while(in.hasNextLine())
{
String SName = in.next();
String DoB = in.next();
String Gender = in.next();
String Address = in.next();
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
public String getName()
{
return this.SName;
}
public void printname()
{
System.out.println("hello");
}
public Student search(String name)
{
System.out.print("Enter the name you wish to search: ");
for (int i = 0; i < this.students.length; i++)
{
Student s = this.students[i];
if (s.getName().equalsIgnoreCase(name))
{
return s;
}
}
return null;
}
} //end class students
However I am trying to create a well refined program that I can call on these methods from another main file with as minimal code as possible in that file.
The search method at the bottom is tripping me up as I am assuming I need to put something to do with the array in my getName() method but I can't figure it out.
Since I am doing this as a class for another main method, with the placement of my array initialization and declaration it allows the other methods to access it but it leaves me with no way to create this array from the main method unless I am missing something?
This is the error jCreator is throwing:
F:\University\Ass2\readStudents.java:62: error: cannot find symbol
if (s.getName().equalsIgnoreCase(name))
^
symbol: method getName()
location: variable s of type Student
You never populated the Student students[] array... You retrieved the values you would populate them with here:
while(in.hasNextLine())
{
String SName = in.next();
String DoB = in.next();
String Gender = in.next();
String Address = in.next();
}
But you never actually set those values into a Student object in the students[] array
Do something like this:
int i = 0;
while(in.hasNextLine())
{
String name = in.next();
String dateOfBirth = in.next();
String gender = in.next();
String address = in.next();
students[i] = new Student(name, dateOfBirth, gender, address);
i++
}
Also, you might consider ditching the array and using some sort of List or Hash object... If your file contains more than 20 lines, the array will be out of index when you try to define the 21st value.. With an arraylist or a List you wouldn't have that problem
I took a liberty to tweak your code as previous answer mentioned, it's better to use array list in your case. You could make a small student container class within your reader. The get name method is also kinda redundant ;s
package test;
import java.io.*;
import java.util.*;
public class readStudents{
ArrayList<Student> students = new ArrayList<Student>();
class Student {
private String name;
private String dob;
private String gender;
private String address;
public Student(String name, String dob, String gender, String address) {
this.name = name;
this.dob = dob;
this.gender = gender;
this.address = address;
}
public void fillStudentArray() {
// properties
int size; // total number of Students in collection
File file = new File("StudentDetails.txt");
try {
Scanner in = new Scanner(file);
while (in.hasNextLine()) {
String SName = in.next();
String DoB = in.next();
String Gender = in.next();
String Address = in.next();
students.add(new Student(SName, DoB, Gender, Address));
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public String getName(Student student) {
return student.name;
}
public void printname() {
System.out.println("hello");
}
public Student search(String name) {
System.out.print("Enter the name you wish to search: ");
for (Student student : students) {
if (student.name.equalsIgnoreCase(name))
;
return student;
}
return null;
}
}
}
If you're not forced by your teacher to use for or for-each cycle in the search function - this is how to do a full scan the Java 8 way
public Optional<Student> findFirstByName(final String name) {
return Arrays.stream(students)
.filter(s -> s.getName().equalsIgnoreCase(name))
.findFirst();
}

conflict b/w string and string[]

Basically I have a class that has methods which use String arrays and i'm writing a method in the application class to read a file and update an array of object of class Customer. I get errors like:
Line 83: set_address(java.lang.String[]) in Customer cannot be applied to (java.lang.String)
at the line review[i].set_address(st[1]). I understand that it is looking for a string[] and it is receiving a string but is there any way to fix this? Here's the code I'm working with.
import java.io.*;
import java.util.*;
class Customer {
int account_id;
char[] ch1 = new char[20];
String name = new String (ch1);
char[] ch2 = new char[80];
String address = new String (ch2);
char[] ch3 = new char[10];
String phone_number = new String (ch3);
char[] ch4 = new char[8];
String date_of_birth = new String (ch4);
double account_balance;
public int get_accountid(){
return account_id;
}
public String get_address(){
return address;
}
public String get_phone_number(){
return phone_number;
}
public String get_date_of_birth(){
return date_of_birth;
}
public double get_balance(){
return account_balance;
}
public void set_account_id(int num){
account_id = num;
}
public void set_address(String add){
address = add;
}
public void set_phone_number(String phone){
phone_number = phone;
}
public void set_date_of_birth(String dob){
date_of_birth = dob;
}
public void set_balance(double bal){
account_balance = bal;
}
Customer(){ // default constructor
}
// parametrized constructor
Customer(int id, String name, String add, String dob, String num, double bal){
this.account_id = id;
this.name = name;
this.address = add;
this.date_of_birth = dob;
this.phone_number = num;
this.account_balance = bal;
}
}
public class lab2{
public static void main(String args[]){
System.out.println("testing this shit");
}
public static void readFile(String filename){
Customer[] review = new Customer[30];
int i=0;
Scanner scan = new Scanner (new File (filename));
while (scan.hasNext()){
while(i<30){
review[i].set_account_id(scan.nextInt());
String[] st = scan.nextLine().split("=");
review[i].set_address(st[1]);
st = scan.nextLine().spilt("=");
review[i].set_phone_number(st[1]);
st = scan.nextLine().split("=");
review[i].set_date_of_birth(st[1]);
//st = scan.nextLine().split("=");
review[i].set_balance(scan.nextDouble());
scan.nextLine();
i=i+1;
}
}
}
}
Your class Customer looks like a Java bean. I find these declaration suspicious:
String[] name = new String [20];
String[] address = new String [80];
String[] phone_number = new String [10];
String[] date_of_birth = new String [8];
Why do you want a Customer to have 20 names, 80 addresses, 10 phone numbers, and 8 date of birth? I suspect that your intention is saying that a Customer name is at most 20 characters long, his/her address is at most 80 characters long, etc. If this is the case, than you don't want a String[], you may want a char[]!
However, think about making those fields simply String: it seems more natural. I don't see reason why you may want to limit their size.
Just change your method signature:
public void set_address(String add){
address = add;
}
Or other choice: You create a new String[] object based on your String object an pass this:

Categories