Objects in Linked Lists - java

I try to write a code which will have a basic menu with some options. These options are the following methods: AddStudent, changeName, setGrade and so on. I have created an object called Student which has a name, a grade and an age. I want to add Students in an linked list but when I use the method add it does not work. Here is my code:
import java.util.*;
class Student {
int age;
int grade;
String name;
static LinkedList ll = new LinkedList();
public Student (String n) { //we create here a student with a name and an age
name=n;
age=0;
grade=0;
}
//-------------------------------------------------------------------------
public void p(String x) {
System.out.println(x);
}
public void addStudent() {
Scanner s = new Scanner(System.in);
p("Enter the name that you want");
String f = s.nextLine();
Student a = new Student(f);
ll.add(a);
}
public void changeName() { //this method is to change the name of a student
Scanner s = new Scanner(System.in);
p("Enter whose name you want to change");
String c = s.nextLine();
p("Enter the name that you want");
String b = s.nextLine();
}
public void setGrade(Student a) { //this method is to put the student's grade
Scanner s = new Scanner(System.in);
p("Enter the grade that you want");
int g = s.nextInt();
a.grade=g;
}
public void setAge(Student a) { //This method is to put the student's grade
Scanner s = new Scanner(System.in);
p("Enter the age that you want");
int h = s.nextInt();
a.age=h;
}
public String getName(Student a) {
return a.name;
}
public int getAge(Student a) {
return a.age;
}
public int getGrade(Student a) {
return a.grade;
}
}
The problem is at the method of addStudent. Is there any other ways,as well, with which I can make the same project?

Think about this logically. You have a Student class that represents a single Student. Why would a Student have a List of Student's? That makes no sense.
Wouldn't you have a program like Course or something that would hold the list of Students? That is where your List belongs. And don't use static unless you have a compelling reason (rare).
Here is a start for the Course class, that uses the Student to store student information and stores it in your LinkedList within the Course. You still need to implement the findStudent method and probably a method to print the List:
Class Course:
import java.util.LinkedList;
import java.util.Scanner;
public class Course {
LinkedList ll = new LinkedList();
Scanner s = new Scanner(System.in);
public void addStudent() {
p("Enter the name that you want");
String f = s.nextLine();
Student a = new Student(f);
ll.add(a);
}
public void changeName() { //this method is to change the name of a student
Student student = findStudent();
p("Enter the name that you want");
String newName = s.nextLine();
//student.setName(newName);
}
public void setGrade() { //this method is to put the student's grade
Student student = findStudent();
p("Enter the grade that you want");
int grade = s.nextInt();
//student.setGrade(grade);
}
public void setAge() { //This method is to put the student's grade
Student student = findStudent();
p("Enter the age that you want");
int age = s.nextInt();
student.setAge(age);
}
public Student findStudent(){
p("Which student did you want to change? Please enter their name:");
String name = s.nextLine();
//Find student in the list - left for the author
Student student = null;
return student;
}
//-------------------------------------------------------------------------
public void p(String x) {
System.out.println(x);
}
public static void main(String[] args) {
Course course = new Course();
course.addStudent();
course.addStudent();
course.changeName();
course.setGrade();
}
}
And the modified Student class:
import java.util.*;
public class Student {
int age;
int grade;
String name;
public Student (String n) { //we create here a student with a name and an age
name=n;
age=0;
grade=0;
}
public void setName(String name) {
this.name = name;
}
public void setGrade(int grade) {
this.grade = grade;
}
public void setAge(int age) {
this.age = age;
}
public String getName(Student a) {
return a.name;
}
public int getAge(Student a) {
return a.age;
}
public int getGrade(Student a) {
return a.grade;
}
#Override
public String toString(){
return "Student(name:" + name + ", age:" + age + ", grade:" + grade + ")";
}
}

This code is kind of messy because you include some code that shouldn't appear in Student class. For example, the addStudent method is not static and in order to call it, you need to first instantiate an instance of Student and call the method on it. However, the method is trying to ask user to input the information of a new Student instance, which is a bad design.
So, keep the Student class only do what it should do. For your case, Student only need to store its age, grade and name fields and define constructors to initialize these fields, and optional getter and setter methods to set and retrieve these fields upon your needs.
You will need a 'manager' class which manages your application. This class will keeps track of a list of students, and asks users to input information of a new student and then initialize the student instance and put it in the list. This Manager class can even manage an UI which you need to take user input or display information to the user. So, it will be this class's responsibility to provide a addStudent method.
Student class itself should know nothing about your application's logic like it may be a course selection program or something else. It only manages its own information while some manager class will take care of the application's logic.

Related

3 subclass and 1 main class inheritance, but shows null in output in java?

I'm starting to get into coding. My formats are bad, but I wanna see first if my idea for the program works then correct it later on. This is program consists of the main class (Employee), then two subclasses that inherit from the main class (Part-Time and Full-Time employees) The code works but I encountered null in my employee's name output in this code or maybe I missed something. Any help, correction, or advice would be great! Thank you
Main Class
class Employee {
public String Name;
public void setName(String Name)
{
this.Name = Name;
}
public String getName()
{
return Name;
}
public void emp()
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter Name: ");
Name = scan.nextLine();
}
}
Subclass FullTimeEmployee
class FullTimeEmployee extends Employee {
private double monthlySalary;
Scanner scan = new Scanner(System.in);
public void setMonthSalary(double monthlySalary) {
this.monthlySalary = monthlySalary;
}
public double getMonthlySalary() {
return monthlySalary;
}
#Override
public void emp() {
System.out.println("Enter monthly salary: ");
monthlySalary = scan.nextDouble();
System.out.println("Name: " + getName());
System.out.println();
System.out.println("Monthly Salary: " + monthlySalary);
}
}
subclass PartTimeEmployee
public class PartTimeEmployee extends Employee {
Scanner scan = new Scanner(System.in);
private double ratePerHour;
private int hoursWorked;
private double wage;
public void setWage(double wage) {
this.wage = wage;
}
public double getWage() {
return wage;
}
#Override
public void emp() {
System.out.println("Enter rate per hour and no of hours worked separated by space: ");
ratePerHour = scan.nextDouble();
hoursWorked = scan.nextInt();
System.out.println("Name: " + getName());
wage = ratePerHour * hoursWorked;
System.out.println("Wage: " + wage);
}
}
RunEmployee
public class RunEmployee {
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
Employee emp1 = new Employee();
FullTimeEmployee fte = new FullTimeEmployee();
PartTimeEmployee pte = new PartTimeEmployee();
emp1.emp();
System.out.println("Press F for Full Time or P for Part Time: ");
char select = scan.nextLine().charAt(0);
if(select == 'F') {
fte.emp();
} else if (select =='P') {
pte.emp();
}
}
}
OUTPUT OF BOTH
Enter monthly salary:
500
Name: null
You only set name in the Employee parent class in the emp() method here:
public void emp() {
Scanner scan = new Scanner(System.in);
System.out.println("Enter Name: ");
Name = scan.nextLine(); // here!
}
And yes, you give your child classes the same method and override and call it, but you never call the parent's version of the method, the super.emp() method, and so the name field never gets set.
A solution would be to call the super.emp() in your overrides, but this isn't good as it breaks the "single responsibility principle". And Employee should be responsible for Employee data and behaviors, but shouldn't be also responsible for handling a Scanner object and getting direct input from the user. Also, there are potential dangers from creating multiple Scanner objects based on System.in.
Much better, get all I/O, all use of Scanner, out of the Employee class and its children. The I/O should be in the main method (for this code) and instead, set name in the Employee constructor, and by calling the super constructor in the child classes, or by directly calling .setName(...) on any instances created.
e.g.,
class Employee {
public String name;
public Employee(String name) {
this.name = name;
}
public Employee() {
this(null);
}
public void setName(String Name) {
this.Name = Name;
}
public String getName() {
return Name;
}
// get rid of this
/*
public void emp() {
Scanner scan = new Scanner(System.in);
System.out.println("Enter Name: ");
Name = scan.nextLine();
}
*/
}
public class FullTimeEmployee extends Employee {
private double monthlySalary;
// Scanner scan = new Scanner(System.in); // *** get rid of this!
public FullTimeEmployee(String name) {
super(name);
}
public FullTimeEmployee() {
super();
}
public void setMonthSalary(double monthlySalary) {
this.monthlySalary = monthlySalary;
}
public double getMonthlySalary() {
return monthlySalary;
}
/* // get rid of this!
#Override
public void emp() {
System.out.println("Enter monthly salary: ");
monthlySalary = scan.nextDouble();
System.out.println("Name: " + getName());
System.out.println();
System.out.println("Monthly Salary: " + monthlySalary);
}
*/
}
and then again, put all Scanner code in the main method.
Regarding variable public String Name;
As an aside, you will want to learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
Also, avoid using public fields unless absolutely necessary. Better to make this field protected, or even better yet, make it private.

Calling an object's method defined in List

I'm trying to call addContact method from main method using ArrayList called phone but its not working.
Here's the code:
import java.util.ArrayList;
import java.util.Scanner;
class A {
String name;
int num;
Scanner sc = new Scanner(System.in);
public A(String name, int num) {
this.name= name;
this.num= num;
}
public void addContact() {
sc.nextLine();
System.out.println("Enter name:");
name = sc.nextLine();
System.out.println("Enter number:");
num = sc.nextInt();
}
}
public class Main {
static void menu() {
System.out.println("1. add");
System.out.println("2. break");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList <A> phone;
while(true) {
menu();
int c = sc.nextInt();
if(c==1) {
phone.add().addContact();
//I'm trying to call addContact()
} else if(c==2) {
break;
}
}
}
}
Why I can't just call phone.add().addContact()?
import java.util.ArrayList;
import java.util.Scanner;
class A {
String name;
int num;
Scanner sc = new Scanner(System.in);
public A(String name, int num) {
this.name= name;
this.num= num;
}
}
public class Main {
static void menu()
{
System.out.println("1. add");
System.out.println("2. break");
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList <A> phone = new Arraylist<A>();
while(true)
{
menu();
int c = sc.nextInt();
if(c==1)
{
System.out.println("Enter name:");
String name = sc.nextLine();
System.out.println("Enter number:");
int num = sc.nextInt();
phone.add(new A(name,num));
}
else if(c==2)
{
break;
}
}
}
}
Just removed you addContact and placed in in the while. Now i create a new Instance of A and add it to the list. This should work now. Please post more precise Questions in the future.
You need to create an instance of your list:
ArrayList<A> phone = new ArrayList<>();
ArrayList <A> phone;
Should be:
ArrayList phone = new ArrayList();
Also, the add() method in this line
phone.add().addContact();
should contain an A object to add to the ArrayList.
you need to return object of A
public A addContact() {
sc.nextLine();
System.out.println("Enter name:");
name = sc.nextLine();
System.out.println("Enter number:");
num = sc.nextInt();
return new A(name,num);
}
and
if(c==1)
{
phone.add(addContact);
}
Your problem starts here:
ArrayList <A> phone;
only declares that list; but doesnt define it. Thus you run into a NullPointerException when you try to run your code.
You need
ArrayList <A> contacts = new ArrayList<>();
instead. I took the freedom to give that variable a reasonable name, too. (this list is about storing contents, it is not storing phones; and it is also not a single phone ... just a list of contact information)
But there is more. You see, you are getting your abstractions wrong. Your Contact class (A is just a terrible name for that class) should not be dealing with a scanner to fetch its data.
Instead, you want to do something like:
class Contact {
private final String name;
private final int number;
Contact(String name, int number) {
this.name = name;
this.number = number;
}
and then, within your main method, you do something like:
boolean loop = true;
while (loop) {
... have user enter a name and a number
if (name.equals("STOP")) {
loop = false;
} else {
Contact contact = new Contact(name, number);
phones.add(contact);
}
}
I can't give the working code. Just check below points to make your program better.
Why you are creating constructor with arguments when you using add contact method.
Where you are created object for class A in class Main.
Try to check how to use ArrayList class. Because you are not using add() properly.

Creating a testing class

I am extremely new to Java so forgive me if I am not asking this question correctly. I have an assignment that is asking me:
"Test your accessors and mutators in a class called Student_Testing.
First create the Student object, then set the value using your
mutator, and then print the value to the screen. Repeat for each of
the variables. Copy and paste the entire Student_Testing class."
So I currently have a Main class that is this:
public class Main {
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student("Joe", 123);
int id = student1.getStudentID();
String name = student1.getName();
System.out.println("ID 1: " + id);
System.out.println("Name 1: " + name);
int id2 = student2.getStudentID();
String name2 = student2.getName();
System.out.println("ID 2: " + id2);
System.out.println("Name 2: " + name2);
}
}
And I have have a class called Student which is this:
public class Student {
private String name;
private int student_id;
private double balance;
public Student() {
name = "";
student_id = 0;
balance = 0.0;
}
public Student(String input_name, int id) {
name = input_name;
student_id = id;
}
public String getName() {
return name;
}
public int getStudentID() {
return student_id;
}
public void setStudentID(int number) {
student_id = number;
}
public void deposit(double amount) {
balance = balance + amount;
}
}
I have no clue how I am supposed to make the Student_Testing class and to create the object Student. I get errors every time.
Is the Student_Testing class created just like the other classes I have? And how am I supposed to create a new object Student when I already have a Student class in a different class?
Like I said I am a complete beginner when it come to Java, so if this could be explained in the simplest terms possible that would be great! Thanks!
public class Main {
public static void main(String[] args) {
Student_Testing.test();
}
}
public class Student_Testing {
public static void test(){
Student student1 = new Student();
Student student2 = new Student("Joe", 123);
int id = student1.getStudentID();
String name = student1.getName();
System.out.println("ID 1: " + id);
System.out.println("Name 1: " + name);
int id2 = student2.getStudentID();
String name2 = student2.getName();
System.out.println("ID 2: " + id2);
System.out.println("Name 2: " + name2);
}
}
public class Student {
//student class stuff...
}
Here we created a new class called Student_Testing. In this class, we created a static method called test(). The stuff inside the test() function is exactly the same as it was in your original code.
Note the similarity between Student_Testing and your Main class?
We can now call this test method from your main function by simply doing Student_Testing.test();
Since you are still a beginner, it's important that you ask any follow up questions.
I highly encourage you to read through this and understand it thoroughly

how to access arraylist belonging to an object inside an arraylist

I have been stuck on the same problem for days and have googled everything I can think of and I give up. I am trying to write a program where you're supposed to first create a person object, and afterwards be able to give that person different types of belongings. I'm putting each created person in an arraylist and every person is supposed to have their own inventory which is also an arraylist. I just don't understand how to add items to a specific persons arraylist and how to print that arraylist. Do I have to create a new instance of the arraylist 'belongings' every time I create a new person? and how do I access a certain persons arraylist? Appreciate any sort of feedback because I am super noob.
import java.util.ArrayList;
public class Sakregister extends Programskelett{
public static ArrayList<Person> personList = new ArrayList<Person>();
protected boolean nextCommand(){
String command = readString("> ").toLowerCase();
switch(command){
case "print list":
printAll();
System.out.println("Program is running");
break;
case "print person":
printUser();
System.out.println("Program is running");
break;
case "create item":
newItem();
break;
case "create user":
newUser();
break;
case "print richest":
printRichest();
System.out.println("Program is running");
break;
case "crash":
initCrash();
break;
case "quit":
System.out.println("Program has terminated");
return true;
default:
System.out.println("Not a valid command");
}
return false;
}
private void printAll() {
}
private void initCrash() {
for (Person thisPerson : personList) {
for (Item thisItem : thisPerson.belongings)
if (thisItem.name == "Stock"){
((Stock) thisItem).setStockCrash(0);
}
}
}
private void printRichest() {
}
private void newUser() {
System.out.println("enter name: ");
String name = keyboard.nextLine();
Person newPerson = new Person(name);
personList.add(newPerson);
System.out.println("Person added to list");
}
private boolean newItem() {
System.out.println("enter item type: ");
String itemType = readString("> ").toLowerCase();
switch(itemType){
case "trinket":
addTrinket();
break;
case "stock":
addStock();
break;
case "appliance":
addAppliance();
return true;
default:
System.out.println("Not a valid item type");
}
return false;
}
private void addAppliance() {
System.out.println("Enter name of appliance: ");
String appName = keyboard.nextLine();
System.out.println("Enter initial price: ");
int appInitialPrice = keyboard.nextInt();
System.out.println("Enter level of wear: ");
int appWear = keyboard.nextInt();
Appliance newAppliance = new Appliance(appName, appInitialPrice, appWear);
System.out.println("Enter name of owner: ");
Object owner = keyboard.nextLine();
for(Person entry : personList)
if(entry.equals(owner))
entry.belongings.add(newAppliance);
}
private void addStock() {
System.out.println("Enter name of stock entry: ");
String stockName = keyboard.nextLine();
System.out.println("Enter amount: ");
int stockAmount = keyboard.nextInt();
System.out.println("Enter price: ");
int stockPrice = keyboard.nextInt();
Stock newStock = new Stock(stockName, stockAmount, stockPrice);
System.out.println("Enter name of owner: ");
String owner = keyboard.nextLine();
keyboard.nextLine();
for(Person entry : personList) {
if(entry.equals(owner)) {
entry.belongings.add(newStock);
}
}
}
private void addTrinket() {
System.out.println("Enter name of trinket: ");
String trinketName = keyboard.nextLine();
System.out.println("Enter number of gems: ");
int trinketGems = keyboard.nextInt();
System.out.println("Choose gold or silver: ");
String trinketMineral = keyboard.nextLine();
keyboard.nextLine();
Trinket newTrinket = new Trinket(trinketName, trinketGems, trinketMineral);
System.out.println("Enter name of owner: ");
String owner = keyboard.nextLine();
for(Person entry : personList)
if(entry.equals(owner))
entry.belongings.add(newTrinket);
}
private void printUser() {
// TODO Auto-generated method stub
}
protected void printMainMenu(){
System.out.println("Choose a command: ");
System.out.println("start");
System.out.println("quit");
}
public static void main(String[] args) {
Sakregister registerProgram = new Sakregister();
registerProgram.run();
}
}
public class Item{
protected String name;
public Item(String name){
this.name = name;
}
public String getItemName() {
return name;
}
import java.util.ArrayList;
public class Person{
public String name;
public String items;
public ArrayList<Item> belongings = new ArrayList<Item>();
public Person(String name){
this.name = name;
}
public String getName(){
return name;
}
public String toString() {
return "Name: " + name;
}
}
" I just don't understand how to add items to a specific persons arraylist and how to print that arraylist"
Your persons are in the personList, so i would use personList.get(n) to get the nth Person.
To add items to the belongings you can use personList.get(n).belongings.add(item).
To print an arraylist you can use a normal foreach loop:
for(Item i:personList.get(n).belongings){
System.out.println(i.getItemName());
}
Do I have to create a new instance of the arraylist 'belongings' every time I create a new person?
The ArrayList belongings is a field inside the Person class. When you create a person with the constructor all of its fields and variables are created in the memory. This happens every time you create a person, so every object (in your case person in the personList) has its own fields like the belongings list.
The new instance of the ArrayList<Item> belongings is already being created each time you create a new Person object, so you don't need to create it again anywhere. However, there is currently no getter for belongings, so you need to write one to access a given person's belongings. You want something like this:
public ArrayList<Item> getBelongings() {
return belongings;
}
You'll need to write a public method that accepts an Item object and adds it to the belongings of that Person. You shouldn't need help with writing another public method that calls System.out.println() on the belongings directly or iterates through them and prints them out.

Creating multiple objects with different names in a loop to store in an array list

I am trying to create mutliple objects of a type of class I made. I then want to transfer these values into the array list. How can I create objects using a while loop that have different names. For example here is my code now, but it would only make an object of one name.
Customer cust = new Customer("bob", 20.0);
and my constructor if you want to see:
public Customer(String customerName, double amount)
{
String name=customerName;
double sale=amount;
}
StoreTest class (with main method):
import java.util.ArrayList;
import java.util.Scanner;
public class StoreTest {
ArrayList<Customer> store = new ArrayList<Customer>();
public static void main (String[] args)
{
double sale=1.0; //so the loop goes the first time
//switch to dowhile
Scanner input = new Scanner(System.in);
System.out.println("If at anytime you wish to exit" +
", please press 0 when asked to give " +
"sale amount.");
while(sale!=0)
{
System.out.println("Please enter the " +
"customer's name.");
String theirName = input.nextLine();
System.out.println("Please enter the " +
"the amount of the sale.");
double theirSale = input.nextDouble();
store.addSale(theirName, theirSale);
}
store.nameOfBestCustomer();
}
}
Customer class:
public class Customer {
private String name;
private double sale;
public Customer()
{
}
public Customer(String customerName, double amount)
{
name=customerName;
sale=amount;
}
}
Store class (has methods for messing with arraylist:
import java.util.ArrayList;
public class Store {
//creates Customer object and adds it to the array list
public void addSale(String customerName, double amount)
{
this.add(new Customer(customerName, amount));
}
//displays name of the customer with the highest sale
public String nameOfBestCustomer()
{
for(int i=0; i<this.size(); i++)
{
}
}
}
ArrayList<Customer> custArr = new ArrayList<Customer>();
while(youWantToContinue) {
//get a customerName
//get an amount
custArr.add(new Customer(customerName, amount);
}
For this to work... you'll have to fix your constructor...
Assuming your Customer class has variables called name and sale, your constructor should look like this:
public Customer(String customerName, double amount) {
name = customerName;
sale = amount;
}
Change your Store class to something more like this:
public class Store {
private ArrayList<Customer> custArr;
public new Store() {
custArr = new ArrayList<Customer>();
}
public void addSale(String customerName, double amount) {
custArr.add(new Customer(customerName, amount));
}
public Customer getSaleAtIndex(int index) {
return custArr.get(index);
}
//or if you want the entire ArrayList:
public ArrayList getCustArr() {
return custArr;
}
}
You can use this code...
public class Main {
public static void main(String args[]) {
String[] names = {"First", "Second", "Third"};//You Can Add More Names
double[] amount = {20.0, 30.0, 40.0};//You Can Add More Amount
List<Customer> customers = new ArrayList<Customer>();
int i = 0;
while (i < names.length) {
customers.add(new Customer(names[i], amount[i]));
i++;
}
}
}

Categories

Resources