I am attempting to create a list of bank records. Each record consists of a first name, last name, phone number, and balance. In the first class I ask the user for this information, then create a new instance of the records class to add to the list. However, as I add more records it replaces all records with the most recent one, which you can see with my showAllRecords() method. How do I fix this?
The add and showAllRecords method in the main class. These methods are called from a switch statement in the main method:
private static void showAllRecords()
{
if(records.bankRecords.size() == 0)
System.out.println("There are no records.");
else
for (int i = 0; i < records.bankRecords.size(); i++)
{
System.out.println(records.bankRecords.get(i));
}
}
private static void add()
{
Scanner scan = new Scanner(System.in);
System.out.print("Please enter the first name: ");
String firstName = scan.next();
System.out.print("Please enter the last name: ");
String lastName = scan.next();
System.out.print("Please enter the phone number: ");
String phoneNumber = scan.next();
System.out.print("Please enter the balance: ");
int balance = scan.nextInt();
bankRecords.add(new records(firstName, lastName, phoneNumber, balance));
}
The records class
public class records
{
public static String firstName;
public static String lastName;
public static String phoneNumber;
public static int balance;
LinkedList<records> bankRecords = new LinkedList<records>();
public records(String tFirstName, String tLastName, String tPhoneNumber, int tBalance)
{
firstName = tFirstName;
lastName = tLastName;
phoneNumber = tPhoneNumber;
balance = tBalance;
}
}
The problem occurs because all the fields in records class are static. Remove the static keyword from the declarations of fields. As they are static whenever you create a new object of records class you overwrite those static fields.
Static fields belong to the class not to the object.
Remove the LinkedList instance that you have declared in records class. Why are u doing that. Declare it in your main class and try to use ArrayList which I think is better in your case. The reason is that records has static fields
Why your class name starts with small letter. Its a very very bad practice.
You have an inherent planning problem.
There is a difference between the entity "Bank Record", which includes, as you said, a name, balance etc., and the entity "List of Bank Records", which includes, well, a variable number of bank records.
Your "records" class (please use a capital letter in the beginning of a class name) tries to mix both. So you have both a record and a list inside it. You should separate the two entities. You then create a new "Record", and add it to the "ListOfBankRecords" objects.
Also, it seems that you have both a variable and a variable called "records". This is also why a capital letter would have been good. You shouldn't have a variable that has the same name as a class.
Related
I have the class "1". In that class I defined the variables "name" "phone number" and "ID". I defined all the sets and gets methods and the constructor for those variables.
In the class "2" I want to fill from the consol those variables. That will be the fist "option" of my CRUD, so everytime the user selects opcion=1, the system has to let add separately each of those variables. I know I have to use Array List but I haven't been able to do it successfully. This is an example of the code. CAPITAL LETTERS code is where I'm stuck. Thanks.
------First Class---------
package VV;
public class 1
{
private String name;
private String phone_number;
private String id;
public 1(String name, String phone_number, String id)
{this.name=name;
this.phone_number=phone_number;
this.id=id;
}
public String getName()
{ return name;
}
public void setName(String name)
{ this.name = name;
}
public String getPhone_number()
{ return phone_number;
}
public void setPhone_number(String phone_number)
{ this.phone_number = phone_number;
}
public String getId()
{ return id;
}
public void setId(String id)
{ this.id = id;
}
----------Second class------------
package VV;
public class 2
{
public 2()
{"Insert the name of the student:"
A METHOD TO INSERT THE NAME OF THE STUDENT
"Insert the phone number of the student:"
A METHOD TO INSERT THE PHONE NUMBER OF THE STUDENT
"Insert the ID of the student:"
A METHOD TO INSERT THE ID OF THE STUDENT
..And so on, each time user selects the opcion "add new student"
(I didn't put the while-case here with all its options to simply)
}
}
I actually don't know why you need that second class's constructor to take input from user and fill the fields of first class.
What I understood from the whole discussion is, you need to set the variables of the class by taking user input, and you need a dynamic way to take that input and set the values.
First way:
Well, this is a bit dynamic. You can use reflection to access all the variables of a class, and you can set their values dynamically.
First of all, create a default constructor in the first class. Then In the main class/whereever you want to take the input from user, create an object of first class and initialize it with default constructor. Then use reflection to work with individual fields, taking input from users and setting the values in the fields. This way doesn't require to know what fields are there to take input from user explicitly. Remember, you can use this method only if there's no problem to expose the names of the variables to the end user. I used only String input as you have only strings in the first class as variables. You need that field.setAccessible(true) if the variables are private. So, let's see the code in the main class/where you'll call the function to take user input:
Field[] arrayOfFields = Student.class.getDeclaredFields();
Scanner sc = new Scanner(System.in);
Student student = new Student();
for (Field field : arrayOfFields) {
try {
field.setAccessible(true);
System.out.println("Please enter the Student " + field.getName());
field.set(student, sc.nextLine());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
That sets the fields accordingly.
Second Way:
If you know the variables you need to initialize the objects, just use scanner to scan them one by one from the user console input and initialize the object:
Scanner sc = new Scanner(System.in);
String id,name,phone_number;
System.out.println("Please enter the Student ID:");
id = sc.nextLine();
System.out.println("Please enter the Student Name:");
name = sc.nextLine();
System.out.println("Please enter the Student Phone Number:");
phone_number = sc.nextLine();
Student student = new Student(id, name, phone_number);
Simple as that.
Problem:
I'm trying to figure out how to access the Student Array class in order to create four entries for each Student object, but I'm not sure how to do so, while also allowing the program to create more than just one Student.
public class ClassRoster<T> {
public static void main(String[]args) {
ClassRoster<Student> classroster = new ClassRoster<Student>();
Scanner keyboard = new Scanner(System.in);
System.out.println("Add/Drop/Search?");
String action = keyboard.nextLine();
boolean done = false;
Object temp, c, d, e;
int fresh, soph, jun, sen;
Student test = new Student();
while(!done) {
if(action.equalsIgnoreCase("Add"))
{
int counter = 0;
System.out.print("Enter Student ID");
temp = test.setID(keyboard.nextInt());
System.out.println("First name?");
c = test.setFirstName(keyboard.nextLine());
System.out.println("Last name?");
d = test.setLastName(keyboard.nextLine());
System.out.println("Academic Level?");
e = test.setLevel(keyboard.nextLine());
...
}
And I have another class called Student, where there are four different data entries (ID, FirstName, LastName, Academic Level).
I'm not sure how to access the object which I have created in the correct way. It just gives me an error in this Driver class, and I don't know how to correctly access the array bag.
but I'm not sure how to do so while also allowing the program to create more than just one Student
Currently you are only creating one specific instance of student with Student test = new Student(); To actually create more than one student, you will have to iterate the whole process of reading all four data entries (ID, FirstName, LastName, Academic Level). Instead of having to initialize the fields (your four data entries) with specific set methods, I would recommend you letting the Student class initialize them with the class constructor. Meaning the Student class should look something like this:
public class Student{
private final int ID;
private final String firstname;
private final String lastname;
private String level;
public Student(int ID, String firstname, String lastname, String level){
this.ID = ID;
this.firstname = firstname;
this.lastname = lastname;
this.level = level;
}
ID, firstname and lastname are set to final as you foresee them not to change. However the academic level is ought to change and therefore is not set to final. Now that you have set up a constructor for your Student class, we can get to how to allow the program to insert multiple students at once.
public static void main(String[]args) {
ClassRoster<Student> classroster = new ClassRoster<Student>();
Scanner keyboard = new Scanner(System.in);
System.out.println("Add/Drop/Search?");
String action = keyboard.nextLine();
boolean done = false;
while(!done) {
if(action.equalsIgnoreCase("Add")) {
System.out.print("Enter Student ID");
int ID = keyboard.nextInt();
System.out.println("First name?");
String firstname = keyboard.nextLine();
System.out.println("Last name?");
String lastname = keyboard.nextLine();
System.out.println("Academic Level?");
String level = keyboard.nextLine();
Student student = new Student(ID, firstname, lastname, level);
//we have now created a new instance of Student, now we have to save it in your classroster
classroster.add(student);
}
System.out.println("Next action?");
action = keyboard.nextLine();
if(action.equals("done") done = true; //if you write 'done', your loop will finish executing
}
I don't know about your implementation of classroster, but I assume you have implemented it with some kind of list or map, which is why I call the add(Student s) method after creating an instance of Student. To actually then access all students, you will have to implement a method in classroster that returns the saved list of classroster and then iterate through the returned list in the main loop. To actually see what the students look like, you will also have to implement methods for the student instances to for example print out their full names.
I see that you are having a little trouble with arrays, maps and lists as you don't know how to access your students yet. I recommend you reading up on the difference between these three data structure types and simply try to implement them in a small example to see how they work.
First it starts off with the class College tester, it askes the user for a command.
The first command will be to add. what adding does is it askes the user to enter a name ( with at least 2 words by identifying a space) and an address.
Then it creates a student object with it. and I add the student object to a arraylist.
Issue #1: How would i add the collegetester input and create a student object out of it
Issue #2: after how would i add it to the array College
Collegetester (where i get user input)
import java.util.Scanner;
public class CollegeTester {
Scanner input = new Scanner(System. in );
private String command;
public String name;
public static void main(String[] args) {
CollegeTester collegeTester = new CollegeTester(); //creates object
collegeTester.getCommand(); //goes to command
}
//Ask user for a command
public void getCommand() {
System.out.println("Enter a command: ");
command = input.nextLine();
if (command.equals("add"))
addCommand(); //If command is add go to addcommand
}
//Add name and address to student object
public void addCommand() {
String name = "";
do {
System.out.println("Enter a Name: ");
name = input.nextLine();
} while (!(name.contains(Character.toString(' ')))); //To check if the name has at least 2 words
System.out.println("Enter an Address: ");
String address = input.nextLine();
Student student = new Student(name, address);
getCommand(); //repeat to see if user wishes to add another
}
}
Student object (The student object)
public Student(String name, String address) {
if (name == null)
name = "";
if (address == null)
address = "";
this.name = name;
this.address = address;
lastAssignedNumber++;
studentNum = lastAssignedNumber;
}
and the arraylist (In a different file)
import java.util.ArrayList;
public class College {
private ArrayList <College> entries = new ArrayList<College>();
}
Let's do a quick analysis of your code:
Your Student object looks like a constructor for the Student class object type which is most likely in this case an inner class of the CollegeTester class.
So here's the deal, your addCommand() already connects your CollegeTester class with your Student class, by executing this command after you provide the input for name and address it creates a new instance of the Student object.
This means that at this point, you need to add this newly created Student object to your College list.
However if you take a good look at your College list you will see that:
It's marked private (meaning it can be accessed only from within itself)
It is a list of College type objects (but you need a list of Student type objects)
So your options at this point are:
Make the list public
Create a public setter method that will do the adding
You will also need to change the list object type to Student if you wish to store Student objects in the list.
Also unless you want to have multiple colleges you might consider declaring your list as static otherwise you will have to declare an instance of it to add the Student objects to it.
Hopefully this is enough information to get you started in the right direction.
Also an advice is to not look at classes as actual objects, instead look at them as blueprints that can be used to construct those real objects.
The main method should call a constructor in the Object array class that create's the Object CollegeTester ct.
ct = new CollegeTester();
Then a method to insert new students, that calls the Student constructor in the student class to create a new student Object.
ct.insert("input1", "input2");
write an insert method that calls to create a new student and adds that object to College.
Constructor to add values to the new student object:
String studentName;
String studentAddress;
public Student(String name, String address) {
studentName = name;
studentAddress = address;
}
note: with ArrayList you could simply use the method add of ArrayList.
I am fairly new to object oriented programming, so I am still having some trouble grasping some of the basic concepts. So here I am trying to create a basic inventory program to keep track of stocks. Each stock contains couple details: company name, stock rating (AAA, AAa, Aaa, stuff like that), purchase price and numbers of shares. The program will ask user to input these details through command line prompt. And users can only input at most 12 stocks. If the user enters a stock twice, it will print out an error. And if the user has inputted one stock twice, it will also print out an error message.
Here is what I have done so far: Stock object
public class Stock {
private String companyName;
private String stockRating;
private int price;
private int numberOfShares;
public String getCompanyName() {
return companyName;
}
public int getStockRating() {
return stockRating;
}
public String getPrice() {
return price;
}
public int getNumberOfShares() {
return numberOfShares;
}
public Stock(String companyName, String stockRating, int price, int numberOfShares) {
super();
this.companyName = companyName;
this.stockRating = stockRating;
this.price = price;
this.numberOfShares = numberOfShares;
}
Now, I am trying to create stock inventory program
import java.util.*;
public class StockInvetory {
private static final int INVENTORY_SIZE = 12;
private Stock [] stocks;
public StockInvetory() {
stocks = new Stock [INVENTORY_SIZE];
}
private static void StockInventory() {
for (int i = 0; i<INVENTORY_SIZE; i++){
Scanner console = new Scanner(System.in);
System.out.println ("Stock's name:");
String stockName = console.next();
System.out.println ("Stock's rating");
String stockRating= console.next();
System.out.println ("Stock's price:");
int stockPrice = console.nextInt();
System.out.println ("Numbers of shares: ");
int numberShares= console.nextInt();
stocks [i]= new Stock(stockName, stockRatings, stockPrice, numberShares);
}
public static void main (String [] args){
StockInventory();
}
}
So my questions are the following:
The first stock object program should be okay, my problem is the stock inventory program.
With this code, private Stock [] stocks, does it mean that the stock inventory program will store the info into an array? If it is, how do I store all the details associated with a particular stock, company name, price, etcs together. Do I have to create a multi-dimensional array in order of keep track of all the details? Like one row contains all the details about one stock, and second row contains details about another stock. And to determine if the user has entered one stock twice, do I use "equalsIgnoreCase" to do the comparison? I know I probably need to create another method for the stock Inventory.
Thank you very much in advance for your assistance.
Once you read in the name, rating, price, and share count, you need to call the constructor on your class Stock to create an instance of the class and assign it to the next item in your stocks[] array.
Like so:
stocks[0] = new Stock( stockName, stockRating, stockPrice, numberShares);
Then you'll need to put the lines of code that you're using to read from the console, plus my line that creates the new Stock object into a loop so that you can read in all 12 stocks:
for( int i = 0; i < INVENTORY_SIZE; i++ )
{
System.out.println ("Stock's name:");
String stockName = console.next();
System.out.println ("Stock's rating");
String stockRating= console.next();
System.out.println ("Stock's price:");
int stockPrice = console.nextInt();
System.out.println ("Numbers of shares: ");
int numberShares= console.nextInt();
stocks[i] = new Stock( stockName, stockRating, stockPrice, numberShares);
}
Now, this isn't perfect, since it will require users to always enter a full set of 12 stocks, so you'll need to figure out how to let the user abort out of the loop if they're done, and you'll still have to add that error checking you want, to ensure that no duplicates are entered, but it should initialize your individual objects and assign eachh one to the array elements.
private Stock [] stocks, does it mean that the stock inventory program
will store the info into an array? If it is, how do I store all the
details associated with a particular stock, company name, price, etcs
together.
Your array is like a list of stocks. But just because its one object, doesn't mean it only contains one piece of data. It can hold Strings, ints, and other user-defined data types. Therefore, you can store pieces of data relating to the stock inside the Stock object.
public class Stock {
private String companyName;
private String stockRating;
private int price;
private int numberOfShares;
Those are all stored in each Stock object, and can be accessed by the getter methods you defined.
int stockdata = stocks[4].getPrice();
However, to initialize your Stock array, you want to create a new Stock object for each area, like so:
for(int i = 0; i < INVENTORY_SIZE; i++) {
stocks[i] = new Stock(foo, bar, lorem, ipsum);
}
The variables used here are just placeholders, so you can create your parameters by reading from the console like you're doing above.
These design principles for OOP should help you understand the relationship between data and containers.
For the second part of your question, you can look at just comparing one of the data values, like companyName, or implementing an interface like Comparable.
for(Stock s : stocks) {
if(stockName.equals(s.getCompanyName()) {
// ERROR!
}
}
You may want to provide some way to break the loop in certain condition if user does not want to input all 12 information. However, it is totally on your requirements.
In that case, you may have to use other options like List or vector.
Each object can have multiple variables , like in your case rating, price ,name and share which are bound to each object. So when you store an object in an index of array, you are actually storing all those information contained by that object in one single place. So in this case, you do not have to create multidimensional array.
You can override your equals method based on what defines the object as equal and use it to determine if same stock is provided again. This will return true if both object are same, otherwise false.
You can post your updated code and log here so that you can get suggestion regarding your exception
In a real world scenario some questions come to mind:
price shouldn't be an integer because a price is usually an amount in a specific currency. Check this money related question.
Stock rating would be better represented using an Enum. See doc
I'm working on a homework project that requires me to create an object from data entered by a user. I have a class called Person which takes the basic information, a class called Customer which extends the Person class and includes a customer number and a class called Employee which extends the Person class and returns a social security number.
I have pasted the code from my main program below. I'm a little confused on a couple of things. First when I'm collecting the information (first name, last name etc) amd I supposed to be accessing my Person class in there somehow?
Second I guess more plainly, how do I create the object? so far in all of the examples I have read online I find they seem to enter the information already like if I were to have it say
Person firstName = new Person(Jack);
Although I am collecting the information from the user so I don't see how to tell it like
Person firstName = new Person (enter info from user here);
Finally and again this is a really dumb question but I have to create a static method that accepts a Person object.
To create the static method I'm assuming it is
Public Static print()
but how do I tell it to print something from the person class? how does it know?
Most of my examples in the book include a class that contains all of the information instead of making the user enter it which is confusing because now I'm being told the user has the freedom to type what they want and I need to collect that information.
import java.util.Scanner;
public class PersonApp
{
public static void main(String[] args)
{
//welcome user to person tester
System.out.println("Welcome to the Person Tester Application");
System.out.println();
Scanner in = new Scanner(System.in);
//set choice to y
String choice = "y";
while (choice.equalsIgnoreCase("y"))
{
//prompt user to enter customer or employee
System.out.println("Create customer or employee (c/e): ");
String input = in.nextLine();
if (input.equalsIgnoreCase("c"))
{
String firstName = Validator.getString(in, "Enter first name: ");
String lastName = Validator.getString(in, "Enter last name: ");
String email = Validator.getEmail(in, "Enter email address: ");
String custNumber = Validator.getString(in, "Customer number: ");
}
else if(input.equalsIgnoreCase("e"))
{
String firstName = Validator.getString(in, "Enter first name: ");
String lastName = Validator.getString(in, "Enter last name: ");
String email = Validator.getEmail(in, "Enter email address: ");
int empSoc = Validator.getInt(in, "Social security number: ");
}
}
System.out.println("Continue? y/n: ");
choice = in.next();
}
}
First, I observe that there isn't a Person object. I assume you'll get around to creating that, so I'm not going to concern myself too much with it.
Insofar as actually getting the data, you're halfway there. Depending on how you want to frame the Person object, you can create a new Customer or Employee object by passing the values which you received from the user.
Customer customer = new Customer(firstName, lastName, email, custNumber);
or
Employee employee = new Employee(firstName, lastName, email, empSoc);
Here's the snippet of both:
public class Person {
public Person (String first, String last, String email) {
// You'd fill in code here for handling the variables
}
// ...
}
public class Customer extends Person {
public Customer (String first, String last, String email, String custNo) {
super(first, last, email);
// You'd fill in code here for handling the variables
}
// ...
}
public class Employee extends Person {
public Employee (int social) {
super(first, last, email);
// You'd fill in code here for handling the variables
}
// ...
}
To print something from the Person class, using that static method (why? You could override toString() instead), you frame it such that your Person object has accessors to each of the fields relevant to a Person. This would mean you have a getFirstName(), getLastName(), and so forth, relevant to the object if it's an employee or a customer. (I leave that as an exercise to you.)
In that sense, one would then only require calls to those accessors to print the value.
public static void print(Person p) {
System.out.println(p.getFirstName()) + " " + p.getLastName()); // You can get the trend from here.
}
To print the Person object you can just use the System.out.println() if you just want to print it to the command line, but you'll get some unreadable nonsense.
What the println() method does is, if the object is not a String call it's toString() method, because all objects have one, it is defined in java.lang.Object. But that method gives us unreadable things mentioned above, so you have to override it to do something like
public class Person
{
String firstName;
String Lastname;
public Person(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public String toString()
{
// Create a String that represents this object
return "This person is called " + firstName + " " + lastName;
}
}
To create an object you can read the Strings from the commandline and then pass them into the constructor as Makoto suggests.