odd output when using multiple classes - java

I am very new with java programming and I am close to finishing a very big project for me. I am trying to make an employee registry that simply relays information back. Whenever I enter the info it just returns stuff like Name#5a965654. My classes are below and any help would be appreciated.
Main:
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner Input = new Scanner(System.in);
System.out.println("Enter the number of employees to enter.");
int employeeCount = Input.nextInt();
Input.nextLine();
Employee employees[] = new Employee[employeeCount];
String firstName;
String lastName;
String street;
String city;
String state;
String zipCode;
String monthHired;
String dateHired;
String yearHired;
int employeeID;
for(int x = 0; x < employeeCount; x++)
{
System.out.println("Please enter the first name of employee " + (x + 1));
firstName = Input.nextLine();
System.out.println("Please enter the last name of employee " + (x + 1));
lastName = Input.nextLine();
System.out.println("Please enter the street of employee " + (x + 1));
street = Input.nextLine();
System.out.println("Please enter the city of employee " + (x + 1));
city = Input.nextLine();
System.out.println("Please enter the state of employee " + (x + 1));
state = Input.nextLine();
System.out.println("Please enter the zip code of employee " + (x + 1));
zipCode = Input.nextLine();
System.out.println("Please enter the month hired for employee " + (x + 1));
monthHired = Input.nextLine();
System.out.println("Please enter the date hired for employee " + (x + 1));
dateHired = Input.nextLine();
System.out.println("Please enter the year hired for employee " + (x + 1));
yearHired = Input.nextLine();
Name name = new Name(firstName, lastName);
name.setName(firstName, lastName);
Address address = new Address(street, city, state, zipCode);
DateOfHire hireDate = new DateOfHire(monthHired, dateHired, yearHired);
employees[x] = new Employee(name, address, hireDate, x);
}
for(int x = 0; x < employeeCount; x++)
{
employees[x].printInfo(x);
}
}
}
Employee class:
public class Employee
{
private Name name;
private Address address;
private DateOfHire hireDate;
int ID;
public Employee()
{
}
public Employee(Name name, Address address, DateOfHire hireDate, int x)
{
this.name = name;
this.address = address;
this.hireDate = hireDate;
this.ID = x;
}
public void printInfo(int x)
{
System.out.println("Employee-" + (x + 1));
System.out.println("Name: " + this.name);
System.out.println("Address: " + this.address);
System.out.println("Date of Hire: " + this.hireDate);
}
}
Format of Name, DateHired, and Address classes:
public class Name
{
private String firstName;
private String lastName;
public Name()
{
}
public Name(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public void setName(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public String getName()
{
return firstName + " " + lastName;
}
}

A Name is not the same as a String, so when you print this.name in Employee.printInfo, it prints Name#[numbers], indicating that what you're printing is a Name object at the location described by the numbers.
Try replacing that line with
System.out.println("Name: " + this.name.getName());
Also, you'll need to do something similar for the Address and DateOfHire, but I don't know what you have implemented for those, so I can't really say what specifically to do. Essentially, though, you'll need a method that gives a string representation of whatever object it is that you want to print.

All classes in Java extend from the java.lang.Object which has a method toString(). This method is implemented as
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
Whenever you call
System.out.println("Name: " + this.name);
String concatenation is done by implicitly calling the toString() method of your instance. If your class doesn't implement (override) the toString() method, then Object's implementation is used.
See the String Conversion rules in the Java Language Specification.
Otherwise, the conversion is performed as if by an invocation of the
toString method of the referenced object with no arguments; but if the
result of invoking the toString method is null, then the string "null"
is used instead.
Since your Name class does not have a toString() method, then its parent class' method is called, ie. Object#toString() and you get the output you see.
You should override the toString() method in all your classes. For example,
public class Name
{
private String firstName;
private String lastName;
public Name()
{
}
public Name(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public void setName(String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public String toString()
{
return firstName + " " + lastName;
}
public String getName()
{
return firstName + " " + lastName;
}
}
It does not matter than toString() and getName() return the same thing in this case. You have to follow the language spec.

You should implement String toString() method if you wanna print an object

Related

Classes and subclass printing

I am trying to print the grade for the student subclass, i feel like i need some type of if statement or array.I am trying to make a code that can be passed a number such as 3 for "Junior" but can also be called through a code such Student.JUNIOR to print the grade level junior. my desired output is:
class Person {
String name;
String campus;
String phone;
String email;
int FRESHMAN = 1;
int SOPHMORE = 2;
int JUNIOR = 3;
int SENIOR = 4;
public Person(String n, String cam, String cell, String mail) {
name = n;
campus = cam;
phone = cell;
email = mail;
}
public String toString() {
return "Name:" + name + "; Campus:" + campus + "; Phone:" + phone + "; Email:" + email + " ";
}
}
class Student extends Person {
int grade;
public Student(String n, String cam, String cell, String mail, int grade) {
super(n, cam, cell, mail);
}
public String toString() {
return super.toString() + "\nClass:";
}
}
class Employee extends Person {
private String title;
public Employee(String n, String cam, String cell, String mail, String position) {
super(n, cam, cell, mail);
title = position;
}
public String toString() {
return super.toString() + "\nTitle:" + title;
}
}
public class Exam3c {
public static void main(String[] args) {
String name = "David";
String campus = "Terry";
String phone = "302-573-3254";
String email = "Genos#edu";
Person P1 = new Person(name, campus, phone, email);
System.out.println("P1: \n" + P1);
Student S1 = new Student(name, campus, phone, email, 1);
System.out.println("S1: \n" + S1);
Student S2 = new Student("Bill While", "Nowhere", "012-345-6789", "bw#nowhere.edu", 3);
System.out.println("S2: \n" + S2);
Employee E1 = new Employee(name, campus, phone, email, "Faculty");
System.out.println("E1: \n" + E1);
}
}
I think you're looking for enums. They have a lot of very useful features; in addition to being nicely type safe in a way that "Magic Ints" are not, you can also fairly fluidly treat them as Strings for debugging.

stack overflow error when using constructor with 2D dynamic graphic [duplicate]

Please excuse what is probably a very basic question, but I am writing a program to store employee info and it works fine until it tries to set the info inside my employee class. It gives a stackoverflow error and I cannot figure out why. Thanks for any help.
Main class:
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner Input = new Scanner(System.in);
System.out.println("Enter the number of employees to enter.");
int employeeCount = Input.nextInt();
Input.nextLine();
Employee employee[] = new Employee[employeeCount];
String namesTemp;
String streetTemp;
String cityTemp;
String stateTemp;
String zipCodeTemp;
String address;
String dateOfHireTemp;
for(int x = 0; x < employeeCount; x++)
{
System.out.println("Please enter the name of Employee " + (x + 1));
namesTemp = Input.nextLine();
System.out.println("Please enter the street for Employee " + (x + 1));
streetTemp = Input.nextLine();
System.out.println("Please enter the city of Employee " + (x + 1));
cityTemp = Input.nextLine();
System.out.println("Please enter the state of Employee " + (x + 1));
stateTemp = Input.nextLine();
System.out.println("Please enter the zip code of Employee " + (x + 1));
zipCodeTemp = Input.nextLine();
address = streetTemp + ", " + cityTemp + ", " + stateTemp + ", " + zipCodeTemp;
System.out.println("Please enter the date of hire for Employee " + (x + 1));
dateOfHireTemp = Input.nextLine();
System.out.println("The employee ID for employee " + (x + 1) + " is " + (x + 1));
employee[x] = new Employee(x, namesTemp, address, dateOfHireTemp);
}
}
}
Employee class:
public class Employee
{
private int employeeID;
private Name name;
private Address address;
private DateOfHire hireDate;
public Employee()
{
}
public Employee(int employeeID, String name, String address, String hireDate)
{
String temp;
Name employeeName = new Name(name);
this.employeeID = employeeID;
}
}
Name class:
public class Name
{
public Name name;
public Name(String name)
{
Name employeeName = new Name(name);
this.name = employeeName;
}
}
The most common cause of StackoverflowExceptions is to unknowingly have recursion, and is that happening here? ...
public Name(String name)
{
Name employeeName = new Name(name); // **** YIKES!! ***
this.name = employeeName;
}
Bingo: recursion!
This constructor will create a new Name object whose constructor will create a new Name object whose constructor will... and thus you will keep creating new Name objects ad infinitum or until stack memory runs out. Solution: don't do this. Assign name to a String:
class Name {
String name; // ***** String field!
public Name(String name)
{
this.name = name; // this.name is a String field
}
Typically a class is used to group data together with functionality. It appears that the Name class is simply a wrapper for a String without adding any functionality. At this point in your Java career, it is probably better to declare String name; in the Employee class and remove the Name class all together. (Note that this would remove the error from your code that Hovercraft Full of Eels described.)

How to call on a field from a new object

I created a class called "Person" here it is: (ignore the toString. I haven't done anything with that yet)
public class Person {
public String firstName;
public String middleName;
public String lastName;
public Person() {
firstName = "first";
middleName = "middle";
lastName = "last";
}
public Person(String first, String middle, String last) {
firstName = first;
middleName = middle;
lastName = last;
}
public String toString() {
return (firstName + " " + middleName + " " + lastName);
}
public String getFirstName() {
return firstName;
}
public String getMiddleName() {
return middleName;
}
public String getLastName() {
return lastName;
}
}
And then I created an implementation class in a new file, this is it:
import java.util.*;
public class TestProgPerson
{
static Scanner console = new Scanner(System.in);
public static void main(String[] args)
{
String first;
String middle;
String last;
Person name = new Person("Joe", "Smith", "Blow");
System.out.println("Name: " + name);
System.out.println("Please enter a last name, to check if it corresponds with the persons last name: " );
last = console.nextLine();
if (last == (objectReference.lastName))
System.out.println("The last name you entered matches the persons last name");
else
System.out.println("The last name you entered does not match the persons last name");
}
}
So what I want it to do is this: Have an object with the first name, middle name, and last name. Output that name. (The program works this far). Then I want to have the user enter a last name, and the program checks to see if the entered last name is the same as the last name in the object. How do I go about calling just an individual string from that object?
Here you are calling the name object of the class but not any field of that class.
System.out.println("Name: " + name);
You can call fields here by using the object of the class and the dot operator.
For Example.
System.out.println("Name: " + name.firstName + " " + name.middleName + " " + name.lastName);
Moreover because strings are Objects and should be compared with the equals method.

How to I print out a specific item from an arraylist based on a string entered

I have an ArrayList that holds contacts. Each contact is assigned an ID by the user when created. How do I reference that ID to print out the details of the contact. For example:
Contact ID = 1. I want to call 1 from the arrayList and print Jone Smith, 123 West St etc..
Here is how I am creating the ArrayList:
Main Class:
import java.util.ArrayList;
import java.util.Scanner;
public class ContactList {
public static void main(String[] args) {
ArrayList<Contact> contacts = new ArrayList<Contact>();
Scanner input1 = new Scanner(System.in);
int type = 0;
while(type != 4){
System.out.println("Please select an option:");
System.out.println("Add a Personal Contact: Enter 1");
System.out.println("Add a Business Contact: Enter 2");
System.out.println("Display Contacts List: Enter 3");
System.out.println("4 to quit");
type = input1.nextInt();
if(type == 4){
System.out.println("Goodbye");
break;
}
if (type==1 || type==2){
Contact contact = null;
//ArrayList<Contact> contacts = new ArrayList<Contact>();
Scanner input = new Scanner(System.in);
System.out.println("Please enter ContactId : ");
String contactId = input.nextLine();
System.out.println("Please enter First Name : ");
String firstName = input.nextLine();
System.out.println("Please enter Last Name : ");
String lastName = input.nextLine();
System.out.println("Please enter Address : ");
String address = input.nextLine();
System.out.println("Please enter Phone Number : ");
String phoneNumber = input.nextLine();
System.out.println("Please enter Email Address : ");
String emailAddress = input.nextLine();
if(type == 1){
System.out.println("Please enter Birthday: ");
String dateofBirth = input.nextLine();
Contact pcontact = new PersonalContact(contactId, firstName, lastName, address, phoneNumber, emailAddress, dateofBirth);
contacts.add(pcontact);
for (Contact showcontact: contacts){
System.out.println(showcontact.displayContact());}
}
else if(type == 2){
System.out.println("Please enter Job Title: ");
String jobTitle = input.nextLine();
System.out.println("Please enter Organization: ");
String organization = input.nextLine();
Contact bcontact = new BusinessContact(contactId, firstName, lastName, address, phoneNumber, emailAddress, jobTitle, organization);
contacts.add(bcontact);
for (Contact showcontact: contacts){
System.out.println(showcontact.displayContact());}
}
}
if(type == 3){
//System.out.println(contacts);
for (Contact showcontact: contacts){
System.out.println(showcontact.displayFullName());}
}
}
}
}
Parent Class:
public abstract class Contact {
String contactId;
String firstName;
String lastName;
String address;
String phoneNumber;
String emailAddress;
public Contact(String contactId,String firstName,String lastName, String address, String phoneNumber, String emailAddress)
{
this.contactId = contactId;
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.phoneNumber = phoneNumber;
this.emailAddress = emailAddress;
}
public void setContactId(String input){
this.contactId = input;
}
public String getContactId(){
return contactId;
}
public void setFirstName(String input){
this.firstName = input;
}
public String getFirstName(){
return firstName;
}
public void setLastName(String input){
this.lastName = input;
}
public String getLastName(){
return lastName;
}
public void setAddress(String input){
this.address = input;
}
public String getAddress(){
return address;
}
public void setPhoneNumber(String input){
this.phoneNumber = input;
}
public String getPhoneNumber(){
return phoneNumber;
}
public void setEmailAddress(String input){
this.emailAddress = input;
}
public String getEmailAddress(){
return emailAddress;
}
#Override
public String toString(){
return ("ContactID: " + this.getContactId() + "\nFirst Name: " + this.getFirstName() + "\nLast Name: " + this.getLastName() + "\nAddress: " + this.getAddress() + "\nPhone Number: " + this.getPhoneNumber() + "\nEmail Address " + this.getEmailAddress());
}
public String displayFullName(){
System.out.println("Contact List:");
return ("ContactID: " + this.getContactId() + "\nFirst Name: " + this.getFirstName() + "\nLast Name: " + this.getLastName());
}
public String displayContact(){
return ("ContactID: " + this.getContactId() + "\nFirst Name: " + this.getFirstName() + "\nLast Name: " + this.getLastName() + "\nAddress :" + this.getAddress() + "\nPhone Number :" + this.getPhoneNumber() + "\nEmail Address " + this.getEmailAddress());
}
}
Subclasses are Personal and Business they just override some of the parent class so don't know that they are of interest to this issue. If wanted I can post them though.
I think it might be easier to use a Map here. This is a datastructure that consists of key-value pairs. You can use your id as a key and the contact as a value. An example:
Map<String, Contact> contacts = new HashMap<String, Contact>();
contacts.put("anId", aContact);
contacts.put("anotherId", anotherContact);
...
contacts.get("anId"); // returns aContact
Iterating over it to print can be done like this:
for(String contactId : contacts.keySet(){
System.out.println(contacts.get(contactId).displayFullName());}
}
I would also recommend using a Map<String, Contact>, but just in case you don't want to do that, here is how to do it with your code:
System.out.println("Please enter ID of contact: ");
String soughtId = input.nextLine();
for (Contact showcontact: contacts)
{
if (showcontact.getContactId().equals(soughtId))
System.out.println(showcontact.displayContact());
}

NullPointerException when using class constructor to set array value

I am extremely new to java and am very close to finishing a project I have been trying to finish for a long time. Whenever I try to run the code. It gives a null pointer exception as soon as the constructer is called. My code is listed below and any help would be appreciated.
Main class:
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner Input = new Scanner(System.in);
System.out.println("Enter the number of employees to register.");
int arraySize = Input.nextInt();
Input.nextLine();
Employee employee = new Employee(arraySize);
String namesTemp;
String streetTemp;
String cityTemp;
String stateTemp;
String zipCodeTemp;
String dateOfHireTemp;
for(int x = 0; x < arraySize; x++)
{
System.out.println("Please enter the name of Employee " + (x + 1));
namesTemp = Input.nextLine();
System.out.println("Please enter the street for Employee " + (x + 1));
streetTemp = Input.nextLine();
System.out.println("Please enter the city of Employee " + (x + 1));
cityTemp = Input.nextLine();
System.out.println("Please enter the state of Employee " + (x + 1));
stateTemp = Input.nextLine();
System.out.println("Please enter the zip code of Employee " + (x + 1));
zipCodeTemp = Input.nextLine();
System.out.println("Please enter the date of hire for Employee " + (x + 1));
dateOfHireTemp = Input.nextLine();
employee.addEmployee(x, namesTemp, streetTemp, cityTemp, stateTemp, zipCodeTemp, dateOfHireTemp);
System.out.println("The employee ID for employee " + (x + 1) + " is " + (x + 1));
}
for(int x = 0; x < arraySize; x++)
{
String info[] = employee.getEmployeeInfo(x);
System.out.println("Employee ID: " + (x + 1));
System.out.println("Name: " + info[0]);
System.out.println("Address: " + info[1]);
System.out.println("Date of Hire: " + info[2]);
}
}
}
Employee class:
public class Employee
{
private EmployeeName name;
private EmployeeAddress address;
private EmployeeDateOfHire hireDate;
public Employee(int arraySize)
{
}
public void addEmployee(int x, String name, String street, String city, String state, String zipCode, String hireDate)
{
this.name.setName(x, name);
this.address.setAddress(x, street, city, state, zipCode);
this.hireDate.addDateOfHire(x, hireDate);
}
public String[] getEmployeeInfo(int x)
{
String info[] = new String[3];
info[0] = name.getName(x);
info[1] = address.getAddress(x);
info[2] = hireDate.getDateOfHire(x);
return info;
}
}
EDIT--
Here is how I wrote my data classes. They are all written in the same format.
Name Class:
public class EmployeeName
{
private String names[];
public void setArray(int x)
{
String array[] = new String[x];
this.names = array;
}
public void setName(int x, String name)
{
this.names[x] = name;
}
public String getName(int x)
{
return this.names[x];
}
}
In the addEmployee() method
public void addEmployee(int x, String name, String street, String city, String state, String zipCode, String hireDate)
this.name.setName(x, name);
this.address.setAddress(x, street, city, state, zipCode);
this.hireDate.addDateOfHire(x, hireDate);
}
you haven't initialized name or the other fields. By default, instance fields will be initialized to null. Trying to dereference null will cause a NullPointerException.
You should initialize those fields, for example in your Constructor
public Employee(int arraySize)
{
this.name = new EmployeeName();
this.address = new EmployeeAddress();
this.hireDate = new EmployeeDateOfHire();
}
I don't know what those classes look like.
Seeing
private String names[];
public void setArray(int x)
{
String array[] = new String[x];
this.names = array;
}
public void setName(int x, String name)
{
this.names[x] = name;
}
You call setName() which would also throw a NullPointerException because you're trying to dereference names but it's null. You would have to call setArray() first but then that would fail too because if x is 0, you will create an array of size 0 but then try to access the element at index 0, which would not exist. If x was 1, you would create array of size 1 but try to access the element at index 1 (second element), which would throw an IndexOutOfBoundsException.
Seriously rethink your design. Why is this EmployeeName class so complicated? Why don't you just have a String field name. Or two fields, firstName and lastName?

Categories