Copy Constructor Test not Working (Java) - java

I'm working on CS homework and have run into a problem. The end of the homework asks about using a copy constructor. The goal is to "make one Payroll object, instantiate it, make a second one, then print them both. Then, change values in the second Payroll object, and show that the changed values only appear in one and not both (that is, print out the original and the copy with slightly changed values)." I tried changing the values in the second Payroll object, but it also changes it in the first. I've listed my code below:
import java.util.Random;
public class Payroll {
private int[] employeeId;
private int[] hours;
private double[] payRate;
public Payroll(){
this.employeeId = new int[0];
this.hours = new int[0];
this.payRate = new double[0];
}
public Payroll(Payroll obj){
this.employeeId = obj.employeeId;
this.hours = obj.hours;
this.payRate = obj.payRate;
}
public Payroll(int i){
this.employeeId = new int[i];
this.hours = new int[i];
this.payRate = new double[i];
}
public int getEmployeeIdAt(int index){
return employeeId[index];
}
public int getHoursAt(int index){
return hours[index];
}
public double getPayRateAt(int index){
return payRate[index];
}
public double getGrossPay(int index){
double grossPay = hours[index] * payRate[index];
grossPay = Math.round(grossPay * 100);
return grossPay/100;
}
public void setEmployeeIdAt(int index, int id){
this.employeeId[index] = id;
}
public void setHoursAt(int index, int hrs){
this.hours[index] = hrs;
}
public void setPayRateAt(int index, double pr){
this.payRate[index] = pr;
}
public void setHoursAt(int i){
Random rand = new Random();
int randHours = rand.nextInt((50 - 15) + 1) + 15;
this.hours[i] = randHours;
}
}
import java.util.Scanner;
public class PayrollDriver {
public static void main(String[] args) {
Payroll pr = new Payroll(5);
Scanner scan = new Scanner(System.in);
int empID = 1001;
for(int i = 0; i < 5; i++){
pr.setEmployeeIdAt(i, empID);
empID++;
}
for(int i = 0; i < 5; i++){
System.out.println("Enter the hourly pay rate for employee number " + pr.getEmployeeIdAt(i) + ": ");
double payRate = scan.nextDouble();
if(payRate < 7.50){
do{
System.out.println("ERROR: Enter 7.50 or greater for pay rate: ");
payRate = scan.nextDouble();
} while(payRate < 7.50);
}
pr.setPayRateAt(i, payRate);
pr.setHoursAt(i);
}
System.out.println("PAYROLL DATA");
System.out.println("======================");
for(int i = 0; i < 5; i++){
System.out.println("Employee ID: " + pr.getEmployeeIdAt(i) + " Hours: " + pr.getHoursAt(i) + " Rate: " + pr.getPayRateAt(i) +
" Gross Pay: $" + pr.getGrossPay(i));
}
System.out.println("Would you like to run the Copy Constructor Test? Enter 'y' (lowercase) if yes, enter any other letter if no: ");
char copyTestVerify = scan.next().charAt(0);
if(copyTestVerify == 'y'){
CopyConstructorTest ct = new CopyConstructorTest();
ct.CopyTest();
}
scan.close();
}
}
The following is my CopyConstructorTest class, the one that tests whether or not the copy constructor will change the original object's values:
public class CopyConstructorTest {
public void CopyTest(){
Payroll pay = new Payroll(5);
pay.setEmployeeIdAt(0, 1001);
Payroll payCopy = new Payroll(pay);
System.out.println("Original: " + pay.getEmployeeIdAt(0));
System.out.println("Copy: " + payCopy.getEmployeeIdAt(0));
payCopy.setEmployeeIdAt(0, 5000);
System.out.println("Original after changes: " + pay.getEmployeeIdAt(0));
System.out.println("Copy after changes: " + payCopy.getEmployeeIdAt(0));
}
}
I'm not positive on what I'm doing wrong. Any help or guidance is much appreciated.

You are just copying the references to the arrays, not the actual data. Therefore whenever you change the data in one of your objects, the changes are seen in both, since they point to the same array.
The easiest way to copy the data is probably using System.arraycopy():
public Payroll(Payroll obj) {
this.employeeId = new int[obj.employeeId.length];
System.arraycopy(obj.employeeId, 0, this.employeeId, 0, obj.employeeId.length);
...

Related

Trying to figure out how to pass array object data to a separate method

I wanted to write a program that records bar inventory as I'm a bartender. I can't figure out how to pass the liquorCost and liquorCount data to the GetCostTotal() method below the main() method. I'm absolutely sure it's something fairly straightforward that I'm doing incorrectly but I just can't figure it out. Any help is appreciated.
My Liquor class is separate and I can post that if necessary but I don't think it's the class that's giving me the problem, it's retrieving the data input from the array to the separate method.
package inventory;
import java.util.Scanner;
public class Inventory {
public static void main(String[] args) {
System.out.println("How many bottles are you taking inventory of?: ");
Scanner keyboard = new Scanner(System.in);
int size = keyboard.nextInt();
Liquor[] inv = new Liquor[size];
for (int i = 0; i < inv.length; i++) {
inv[i] = new Liquor();
System.out.println("Enter product name: ");
inv[i].setLiquorName(keyboard.next());
System.out.println("Enter the count for the product: ");
inv[i].setLiquorCount(keyboard.nextDouble());
System.out.println("Enter the cost for the product: ");
inv[i].setLiquorCost(keyboard.nextDouble());
}
System.out.println("The sitting inventory cost of these products is: ");
//double totalCost = 0
for (Liquor inv1 : inv) {
System.out.println(inv1.getLiquorName() + ": $" + inv1.getLiquorCost() * inv1.getLiquorCount());
}
double costTotal = GetCostTotal(Liquor[] inv, double liquorCost, double liquorCount);
System.out.println("The total cost of the inventory is: "
+ costTotal);
System.exit(0);
}
public static double GetCostTotal(Liquor[] inv, double liquorCost, double liquorCount) {
double costTotal = 0;
for ( int i = 0; i < inv.length; i++) {
costTotal += (liquorCost * liquorCount);
}
return costTotal;
}
}
try this
public static void main(String[] args) {
System.out.println("How many bottles are you taking inventory of?: ");
Scanner keyboard = new Scanner(System.in);
int size = keyboard.nextInt();
Liquor[] inv = new Liquor[size];
for (int i = 0; i < inv.length; i++) {
inv[i] = new Liquor();
System.out.println("Enter product name: ");
inv[i].setLiquorName(keyboard.next());
System.out.println("Enter the count for the product: ");
inv[i].setLiquorCount(keyboard.nextDouble());
System.out.println("Enter the cost for the product: ");
inv[i].setLiquorCost(keyboard.nextDouble());
}
System.out.println("The sitting inventory cost of these products is: ");
//double totalCost = 0
for (Liquor inv1 : inv) {
System.out.println(inv1.getLiquorName() + ": $" + inv1.getLiquorCost() * inv1.getLiquorCount());
}
double costTotal = GetCostTotal(inv);
System.out.println("The total cost of the inventory is: "
+ costTotal);
System.exit(0);
}
public static double GetCostTotal(Liquor[] inv) {
double costTotal = 0;
for ( int i = 0; i < inv.length; i++) {
costTotal += (inv[i].getLiquorCost() * inv[i].getLiquorCount());
}
return costTotal;
}
Lets understand what went wrong here.Take a look at how you are trying to call the GetCostTotal() method.
double costTotal = GetCostTotal(Liquor[] inv, double liquorCost, double liquorCount);
This is incorrect. The syntax/way you are calling the method is actually used when we what to define a method. Like you did:
public static double GetCostTotal(Liquor[] inv, double liquorCost, double liquorCount) {}
Your call should be like:
double costTotal = GetCostTotal(inv);
Here, we are passing only inv because the data for liquorCost and liquorCount is available inside "each" element of array inv.
Now you can accept this argument in GetCostTotal method. Here as you are iterating using a for loop, you can read the data you needed as inv[i].getLiquorCost() and inv[i].getLiquorCount().
I suggest you can read more on defining a method and calling a method in java.

Encountered Issues Using Multiple Methods on the Same Code

I am a fairly new programmer in Java and am currently learning about how to incorporate multiple methods in one code. The goal of this practice activity is to use several different methods to:
-Create two arrays (one for employee names and another for how much that employee sold)
-Find the average of total sales
-Find the highest sale number
-Find the name of the Employee(s) with the highest sale count (and print "hooray" for every employee that had the highest sale count)
import java.util.*;
public class MethodActivity{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String[] names={"Employee A", "Employee B", "Employee C", "Employee D", "Employee E", "Employee F", "Employee G", "Employee H", "Employee I", "Employee J"};
System.out.print("Enter the sales numbers, in dollars, for each employee: ");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int num3 = sc.nextInt();
int num4 = sc.nextInt();
int num5 = sc.nextInt();
int num6 = sc.nextInt();
int num7 = sc.nextInt();
int num8 = sc.nextInt();
int num9 = sc.nextInt();
int num10 = sc.nextInt();
double[] sales={num1, num2, num3, num4, num5, num6, num7, num8, num9, num10};
return double[] sales;
return String[] names;
}
public static double getAverage(double[] sales){
double average=(num1+num2+num3+num4+num5+num6+num7+num8+num9+num10)/10;
return average;
}
public static int getHighestSale(double[] sales){
double highest = sales[0];
int locationOfHighest=0;
if(sales[1]>highest){
highest=sales[1];
locationOfHighest=1;
}else if(sales[2]>highest){
highest=sales[2];
locationOfHighest=2;
}else if(sales[3]>highest){
highest=sales[3];
locationOfHighest=3;
}else if(sales[4]>highest){
highest=sales[4];
locationOfHighest=4;
}else if(sales[5]>highest){
highest=sales[5];
locationOfHighest=5;
}else if(sales[6]>highest){
highest=sales[6];
locationOfHighest=6;
}else if(sales[7]>highest){
highest=sales[7];
locationOfHighest=7;
}else if(sales[8]>highest){
highest=sales[8];
locationOfHighest=8;
}else{
highest=sales[9];
locationOfHighest=9;
}
return highest;
}
public static String showName(String[] names){
String nameOfHighest = "";
String hooray = "";
for (int i = 0; i<names.length; i++){
if (i=locationOfHighest){
nameOfHighest=nameOfHighest+names[i]+", ";
hooray = ""+"hooray ";
}else{
nameOfHighest=nameOfHighest;
}
}
return nameOfHighest;
}
public static void (String[] args){
System.out.println("The average sales for today was: "+average);
System.out.println(nameOfHighest+" made the highest sales of "+highest);
System.out.println(hooray);
}
}
However, when I run the program, I got these errors. The thing is, I don't really understand what they mean:
MethodActivity.java:20: error: '.class' expected
return double[] sales;
^
MethodActivity.java:21: error: '.class' expected
return String[] names;
^
MethodActivity.java:75: error: <identifier> expected
public static void (String[] args){
I would really appreciate if someone could clarify what these mean, since I'm still quite confused by the concept of a multi method code. And, if you could, maybe point out any other issues or fixable elements in my code (since I know my code might look pretty sloppy to someone with programming experience and I could really use some pointers). Thank you for your time.
You need to remove this both returns.
There are two problem in your code:
1) java method can have only one return statement.
2) it is main method and because of it returns void type. void means no return type.
Rather using separate method for printing "public static void (String[] args), print those in main method itself.
Also refer answer by iMBMT.
import java.util.Scanner;
public class MethodActivity {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter Number of employees : ");
int totalEmployeeCount = sc.nextInt();
System.out.println("## totalEmployeeCount : " + totalEmployeeCount);
String[] employeeNames = new String[totalEmployeeCount];
int[] employeeSoldCount = new int[totalEmployeeCount];
String name;
int count;
for (int index = 0; index < totalEmployeeCount; index++) {
System.out.print("Enter employee name : ");
name = sc.next();
System.out.print("Enter employee sale count : ");
count = sc.nextInt();
employeeNames[index] = name;
employeeSoldCount[index] = count;
}
System.out.println("---------------- Pringting all info ----------------");
for (int i = 0; i < employeeNames.length; i++) {
System.out.println("name : " + employeeNames[i] + " & sale count : " + employeeSoldCount[i]);
}
findTheAverageOfTotalSales(employeeSoldCount);
findTheHighestSaleNumber(employeeSoldCount);
}
private static void findTheAverageOfTotalSales(int[] employeeSoldCount) {
for (int saleCount : employeeSoldCount) {
System.out.println("Write your own code ...");
}
}
private static void findTheHighestSaleNumber(int[] employeeSoldCount) {
for (int saleCount : employeeSoldCount) {
System.out.println("Write your own code ...");
}
}
}

how to transverse arraylist

I need to know how to transverse my average function into this result function if u are getting ?
This is the main class:
import java.util.ArrayList;
import java.util.Scanner;
public class main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
ArrayList < Calculations > students = new ArrayList < Calculations > ();
for (int i = 0; i < 5; ++i) {
Calculations s = new Calculations();
System.out.print("Enter name : ");
s.name = scan.next();
System.out.print("Eter percentage : ");
s.percetage = scan.nextDouble();
students.add(s);
System.out.println("Enter Mrks Obtained");
}
for (Calculations s: students) {
s.result();
for (Calculations i: students) {
s.Average();
}
}
}
}
This is result class:
import java.util.Scanner;
public class Calculations {
public String name;
public double percetage;
public int integer;
public void result() {
System.out.println((percetage >= 35.0 f ? (name + " Pass") : (name + " Fail")));
}
public void Average() {
// TODO Auto-generated method stub
int mark[] = new int[5];
int i;
float sum = 0;
float avg, perc;
Scanner scan = new Scanner(System.in);
System.out.print("Enter marks Obtained in 5 Subjects : ");
for (i = 0; i < 5; i++) {
mark[i] = scan.nextInt();
sum = sum + mark[i];
}
avg = sum / 5;
perc = (sum / 500) * 100;
System.out.print("Average Marks = " + avg);
System.out.print("\nPercentage = " + perc + "%");
}
}
for(Calculations s : students){
s.result();
//for(Calculations i : students){s.Average(); }
s.Average();
}
you dont have to loop your arraylist twice. try changing your code.
It was so hard to follow through your incomplete question, which is not specific either. Your program works fine in my eclipse. I would suggest following:
1) Check the name of the fields/ spelling in you Calculations class to match exactly as it's been used in the main class.
2) Since you're inputting String Scanner, try to read lines as follows:
s.name = scan.nextLine();
I hope it helped.

Cannot figure out how to print toString

package homeWork;
public class ShoppingBag {
private int items;
private float totalRetailCost;
private float taxRate;
public ShoppingBag(float taxRate){
this.taxRate = taxRate;
items = 0;
totalRetailCost = 0.0f;
}
// Transformer
public void place(int numItems, float theCost){
items = items += numItems;
totalRetailCost += (numItems * theCost);
}
public int getItems(){
return items;
}
public float getRetailCost(){
return totalRetailCost;
}
public float getTotalCost(){
return totalRetailCost + (1 + taxRate);
}
public String toString(){
String result = "The bag contains " + items + " items";
result += "The retail cost of items is" + totalRetailCost;
result += "The total cost = " + getTotalCost();
return result;
}
}
package homeWork;
import java.util.*;
public class MainClass {
public static void main(String[] args){
Scanner conIn = new Scanner(System.in);
ShoppingBag sb = new ShoppingBag(0.06f);
int count = 0;
float cost = 0.0f;
System.out.print("Enter count (0 to stop):");
count = conIn.nextInt();
while(count != 0){
System.out.print("Enter cost: ");
cost = conIn.nextFloat();
sb.place(count, cost);
System.out.print("Enter count (0 to stop):");
count = conIn.nextInt();
}
}
}
I have tried all that I have found on here to return result after completion of input. Ive done what my book has shown me to do but I am not getting a result. Just a nudge in the right direction would be helpful.
You are no printing the object anywhere. Print the object
System.out.print(sb);

Using default and non default constructors in my application

I'm new to java and have a question about default and non default constructors. My professor wants us to use the default constructor for creation of object BOOK1, and then use the non default constructor for BOOK2, BOOK3 and BOOK4. I know a constructor is used with the creation of an object, but I guess I don't understand how i'm supposed to differentiate between the two. My class code is as follows, where I have both a default and non default constructor:
import java.text.DecimalFormat;
public final class BOOKItem {
DecimalFormat intFormat = new DecimalFormat("000");
DecimalFormat doubleFormat = new DecimalFormat("$#,##0.00");
private int bookID;
private int numberInStock;
private double price;
private double totalValueOfStock;
private int code;
private String genre = "";
public BOOKItem() {
bookID = 0;
numberInStock = 0;
price = 0;
code = 0;
}
public BOOKItem(int newID, int newStock, double newPrice, int newCode) {
setID(newID);
setStock(newStock);
setCode(newCode);
setPrice(newPrice);
}
public void setStock (int newStock) {
if (newStock >= 1 && newStock <=5000) {
numberInStock = newStock;
}
else {
numberInStock = 0;
}
}
public void setCode (int newCode) {
if (newCode > 0) {
code = newCode;
}
}
public void setID (int newID) {
if (newID >=11 && newID <= 111111) {
bookID = newID;
}
else {
bookID = 0;
}
}
public void setPrice (double newPrice) {
if (newPrice >= 1.0 && newPrice <=150.0) {
price = newPrice;
}
else {
price = 0;
}
}
public int getID () {
return bookID;
}
public int getNumberInStock () {
return numberInStock;
}
public int getCode () {
return code;
}
public double getPrice () {
return price;
}
public double calcTotalValue () {
totalValueOfStock = numberInStock * price;
return totalValueOfStock;
}
public double getTotalValue () {
return totalValueOfStock;
}
public void display() {
switch (code)
{
case 1:
genre = "Romance";
break;
case 2:
genre = "Adventure";
break;
case 3:
genre = "Sci-Fi";
break;
case 4:
genre = "Mystery";
break;
}
System.out.println("Display:");
System.out.println("Book ID: " + bookID + " NumInStock: " + numberInStock + " Code: " + genre + " Price: " +
price + " TotalStockValue: " + calcTotalValue());
}
}
Here is my application that uses the constructors(sorry about the break in the class code, i dunno why its doing that):
import java.util.Scanner;
public class Project7 {
public static void main(String[] args) {
int bookID;
int numberInStock;
double price;
int code;
Scanner keyboard = new Scanner(System.in);
BOOKItem BOOK1, BOOK2, BOOK3, BOOK4;
BOOK1 = new BOOKItem();
BOOK2 = new BOOKItem();
BOOK3 = new BOOKItem();
BOOK4 = new BOOKItem();
System.out.println("Enter in a blank separated list: ID, number in stock, quality, price" +
"- use a BAD ID(<11 or >111111)");
bookID = keyboard.nextInt();
numberInStock = keyboard.nextInt();
code = keyboard.nextInt();
price = keyboard.nextDouble();
BOOK1.setID(bookID);
BOOK1.setStock(numberInStock);
BOOK1.setCode(code);
BOOK1.setPrice(price);
BOOK1.display();
System.out.println("Enter in a blank separated list: ID, number in stock, quality, price" +
"- use a BAD STOCK(>5000)");
bookID = keyboard.nextInt();
numberInStock = keyboard.nextInt();
code = keyboard.nextInt();
price = keyboard.nextDouble();
BOOK2.setID(bookID);
BOOK2.setStock(numberInStock);
BOOK2.setCode(code);
BOOK2.setPrice(price);
BOOK2.display();
System.out.println("Enter in a blank separated list: ID, number in stock, quality, price" +
"- use a BAD PRICE(>150.0)");
bookID = keyboard.nextInt();
numberInStock = keyboard.nextInt();
code = keyboard.nextInt();
price = keyboard.nextDouble();
BOOK3.setID(bookID);
BOOK3.setStock(numberInStock);
BOOK3.setCode(code);
BOOK3.setPrice(price);
BOOK3.display();
System.out.println("Enter in a blank separated list: ID, number in stock, quality, price" +
"- use ALL GOOD DATA");
bookID = keyboard.nextInt();
numberInStock = keyboard.nextInt();
code = keyboard.nextInt();
price = keyboard.nextDouble();
BOOK4.setID(bookID);
BOOK4.setStock(numberInStock);
BOOK4.setCode(code);
BOOK4.setPrice(price);
BOOK4.display();
}
}
Am I doing something incorrect with the creation of my objects? How do I use the non default constructor for BOOK2, BOOK3 and BOOK4? I created it, but perhaps i'm using it incorrectly. Any feedback would be greatly appreciated.
When you use
BOOK1 = new BOOKItem();
You are calling the default constructor (Construction without having any arguments)
After taking user input you would call the Non Default Constructor
bookID = keyboard.nextInt();
numberInStock = keyboard.nextInt();
code = keyboard.nextInt();
price = keyboard.nextDouble();
BOOK2 = new BOOKItem(bookID, numberInStock, price, code);
Use the above code to use the Parameterized Constructor (Non Default constructor)
This is called constructor overloading.
So for the objects you want to assign default values you call the default constructor
For the object you have information available with variables you sent them in the constructor that you have defined with parameters, To assign that value

Categories