I am very new to java and have been trying to get my bearings with it. I've been trying to write an proof of concept employee database. It all works fine until I enter the last employee condition, then I get an ArrayIndexOutOfBoundsException. Here is the code for both of my files. Any help would be appreciated.
import java.util.Scanner;
public class EmployeeInterface
{
public static void main(String[] args)
{
Scanner Input = new Scanner(System.in);
System.out.println("Please enter the number of employees to register.");
int employeeCount = Input.nextInt();
Employee.setEmployeeNumber(employeeCount);
String employeeFullName;
String employeeAddress;
String employeeDateOfHire;
for(int x = 0; x <= employeeCount; x++)
{
System.out.println("Please enter the full name of employee number " + (x + 1));
Input.nextLine();
employeeFullName = Input.nextLine();
System.out.println("Please enter the address of employee number " + (x + 1));
employeeAddress = Input.nextLine();
System.out.println("Please enter the date of hire for employee " + (x + 1));
employeeDateOfHire = Input.nextLine();
Employee.employeeRegister(x, employeeFullName, employeeAddress, employeeDateOfHire);
}
}
}
Here is the second file:
public class Employee
{
private static int employeeCount;
private static String employees[][] = new String[employeeCount][4];
public static void setEmployeeNumber(int x)
{
employeeCount = x;
}
public static void employeeRegister(int employeeNumber, String employeeFullName, String address, String employeeHireDate)
{
employees[employeeNumber][0] = employeeFullName;
employees[employeeNumber][1] = employeeFullName;
employees[employeeNumber][2] = employeeFullName;
employees[employeeNumber][3] = employeeFullName;
}
}
This is the problem:
for(int x = 0; x <= employeeCount; x++)
You're using <= rather than <. So if employeeCount is 3, you'll actually ask for the details of 4 employees, and use indexes 0, 1, 2 and 3 - but 3 is an invalid index for an array of size 3.
Your setEmployeeCount method is also broken - it changes the value of employeeCount, but doesn't reinitialize the array, so you'll always end up with an array of size 0. Given that you've said the code works until the final entry, I suspect this isn't a problem in your real code, as otherwise you'd get an exception on the very first entry.
That said, I would strongly recommend that you create a rather more useful Employee type, with private instance fields for number, name etc... then create a List<Employee>. (There's probably no point in it being stored via a static field in Employee either - what if you want two employee lists?)
Additionally, an employeeHireDate should be in some appropriately chronological type - not a string. (I'd suggest using LocalDate from Joda Time as the built-in Java types for date/time types are awful.)
In addition to other answers:
private static String employees[][] = new String[employeeCount][4];
employeeCount is immediately intialized as 0 and so is the array afterwards.
You need to reintialize your array after setting employeeCount.
your loop is iterating 1 extra time. if employeeCount is 5 then loop iterates 6 times.
Try this instead
for(int x = 0; x < employeeCount; x++)
ArrayIndexOutOfBounds Exception
because you are trying to access the 1 index more which doesn't exist by using <= instead of < only
use for(int x = 0; x < employeeCount; x++)
instead of
for(int x = 0; x <= employeeCount; x++)`
Additionally to other answers:
In the method setEmployeeNumber(int x), you only change the variable employeeCount. What's missing here is to resize the array wherein you store the employees:
employees[][] = new String[employeeCount][4];
Related
I'm trying to create a program that will take a user input, input that data into an dynamic array, and then recursively finds the average. The first part of my code works. This allows the newly created array to be passed to the method.
public static void main(String args[])
{
int i = 0;
int sum = 0;
double runningTotal = 0;
int classSize;
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter the class size: ");
classSize = keyboard.nextInt();
int newClassSize[] = new int[classSize];
for (i=0; i < newClassSize.length; i++)
{
System.out.println("Please enter the grade of the user at: " + (i + 1));
newClassSize[i] = keyboard.nextInt();
}
findAverage();
for (i=0; i < newClassSize.length; i++){
sum = sum + newClassSize[i];
}
System.out.println(Arrays.toString(newClassSize));
keyboard.close();
}
}
This is where I'm getting confused and confusing myself however. How would I pass the newly created array to the findAverage() method? I would then need to also have that be saved to an accumulator and then devided. Is there a better way to do this? This is my current findAverage() method but I'm confusing myself on my implementation.
public double findAverage(int classAverage, int baseCase, double runningAverage)
{
runningAverage = 0;
int sum = 0;
if (newClassSize.length - 1 > baseCase)
runningAverage = newClassSize.length;
return findAverage();
System.out.println("The class average is " + classAverage);
}
Hopefully I understood your question correctly but heres how to do it below.
The basic idea is that when the index reaches the length of the array in the
recursive function that's the base case. So all you have to do is add to the sum at each index point in the array, and just keep passing in the updated index and sum into the recursive function.
class Main {
public static void main(String[] args) {
int newClassSize[] = {1,2,3}; // User Input let say
double average = findAverage(newClassSize);
System.out.println(average);
}
public static double findAverage(int[] arr){
// Avoid division by zero error
if (arr.length==0){
return 0;
}
return findAverageHelper(arr,0,0);
}
public static double findAverageHelper(int[] arr, int index,int sum){
if (index==arr.length){ // Base Case
return (double) sum/arr.length;
}
// Increase index and add current value at index to sum
return findAverageHelper(arr,index+1,sum+=arr[index]);
}
}
Your program must read the id number and gpa and transfer the data into two separate arrays. You can assume there will never be more than 1000 students in the file. Do you know why you must use two separate arrays? You may find it useful in this program to create additional arrays to complete the requirements of the program as described next.
Your program must do two distinctly different things correctly for full credit:
You must create a simple diagram to show how many students fall into each of 8 different categories. This type of diagram is known as a histogram and it is generally useful to show how data is distributed across a range.
For each student in the input file, you must display their S-number, gpa, and class rank. The S-number and gpa will already be in your arrays; however, you must calculate their class rank.
Here is the code I have so far:
public static void main(String[] args) throws Exception
{
Scanner gpadata;
String snum;
double gpa;
int groupNumber;
gpadata = new Scanner(new File("studentdata.txt"));
while (gpadata.hasNext())
{
snum = gpadata.next();
gpa = gpadata.nextDouble();
groupNumber = gpaGroup(gpa);
System.out.println("Student number, GPA, and group number"
+ " is: " + snum +
" " + gpa + " " + groupNumber);
}
}
//Method to categorize students GPA into 1 of 8 groups
public static int gpaGroup(double gpa)
{
//Declare all variables
int gpaGroup;
//Assign GPA a group number
if (gpa >= 0.0 && gpa < 0.5)
gpaGroup = 1;
else if (gpa >= 0.5 && gpa < 1.0)
gpaGroup = 2;
else if (gpa >= 1.0 && gpa < 1.5)
gpaGroup = 3;
else if (gpa >= 1.5 && gpa < 2.0)
gpaGroup = 3;
else if (gpa >= 2.0 && gpa < 2.5)
gpaGroup = 4;
else if (gpa >= 2.5 && gpa < 3.0)
gpaGroup = 5;
else if (gpa >= 3.0 && gpa < 3.5)
gpaGroup = 6;
else
gpaGroup = 7;
//Return int value of group number
return gpaGroup;
}
//Method to find number of students in each group
public static void studentsInGroup(int gpaGroup)
{
//Declare all variables
int gpaGroup1 = 0;
int gpaGroup2 = 0;
int gpaGroup3 = 0;
int gpaGroup4 = 0;
int gpaGroup5 = 0;
int gpaGroup6 = 0;
int gpaGroup7 = 0;
int gpaGroup8 = 0;
//Total students in each GPA group
if (gpaGroup == 1)
gpaGroup1++;
else if (gpaGroup == 2)
gpaGroup2++;
else if (gpaGroup == 3)
gpaGroup3++;
else if (gpaGroup == 4)
gpaGroup4++;
else if (gpaGroup == 5)
gpaGroup5++;
else if (gpaGroup == 6)
gpaGroup6++;
else if (gpaGroup == 7)
gpaGroup7++;
else
gpaGroup8++;
}
Can I modify my method to return more than one variable from a method (in public static void studentsInGroup(int gpaGroup) return values of number of students in each group)? Is this where arrays start to come in? From here I would write another method to round number of students in each category to the nearest ten, then use this to write a method for creating a histogram etc etc.
I have been trying my hardest to understand the concepts, but I have been struggling lately. This is one of my last assignments for the semester and I'd like to keep my A, and also understand what I'm doing.
Can I modify my method to return more than one variable from a method (in public static void studentsInGroup(int gpaGroup) return values of number of students in each group)?
Yes, you can. You can create an object that contains two variables. However, the instructions suggest a different solution.
Inside your loop, read the id and gpa, and immediately stick them in two separate arrays.
Here is a fragment:
snums = [];
gpas = [];
while (gpadata.hasNext())
{
snum = gpadata.next();
gpa = gpadata.nextDouble();
snums.append(snum);
gpas.append(gpa);
}
ensure you are doing the following. I'm not giving away any code here. Also not sure why they want you to use array only!?!
Breakdown your requirement and see what you need to achieve.
Start with reading each line from file
each line is separated by " " and has id_number and gpa
from the requirement, the file will not contain more than 1000 students(1000 lines). You may declare this as a static class level variable static String[] idnum_array = new String[1000]; and another array for gpa which is Double[]
read each line and then separate by using String.split(" ") method. The first variable is your id number and 2nd will be your gpa. you follow ?
maintain a separate counter to increment the array position each time you set these values in the two arrays you created in step 3.
Integer i = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] splitString = line.split(" ");
idnum_array[i] = String.valueOf(splitString[0]);
gpa_array[i] = Double.valueOf(splitString[1]);
i++;
}
Do you agree that if we do idnum_array[7] to return it's corresponding gpa result from gpa_array[7] for that student ?
How you choose to count the number of people in a certain group is upto you.
I would do the following
create a static class level variable static Integer[] group_array = new Integer[]{0,0,0,0,0,0,0,0}; // there are only 8 groups!
loop my gpa_array
have an if/else inside the loop to check which group it falls in
increment the value at that index by 1. group_array[index]++;
In the end I will have an array of 8 elements which will correspond to the 8 groups. [0,200,300,200,0,300,0,0,0]
You should end up with nearly 4 methods similar to this.
1. readDataFromFile(String fileName)
2. groupGPAIntoCategory()
3. drawHistogram()
4. calculateRank()
I would personally create a Student object from the very beginning.
It's just cleaner and readable. Make sure you have your try catch block to print your exceptions and always comment!
I would like to ask how do I do that when the cycle starts and go over again, the string variable name will increase by 1. This program is supposed to ask you how many patients are you going to write. If you write for ex. 10, then the cycle will go for 10 times and it will ask all those information I want and then add them to the array which I have already created called BMI. This whole program is supposed to print you a table which contains Name, Height in meters, weight in Kg, your calculated BMI and then text in what state of BMI are you ATM. The problem is how do I do it? I just started learning arrays and stuff like that and my teacher gave me this homework. I don't think that this homework is hard but just hard to understand what to do.
Things I already tried is creating a for cycle with String called name something like this: String name(); but that obviously did not work.
import java.util.Scanner;
class Pacient {
public static void main(String args[]){
int pole;
Scanner input = new Scanner(System.in);
String pacient;
System.out.print("Zadej kolik bude pacientu: "); //How many patients do you want? For ex. 10
pacient = input.nextLine();
input.nextLine();
pole = Integer.parseInt(pacient);
String[][] bmi = new String[4][pole]; //This is supposed to make an array with my patients.
double vaha; //weight
double vyska; //height
String jmeno; //name
double telo1, telo2; //body for calc.
String vysledek; //result
int i,x=0,j, pa=0, k=0; //some variables
bmi[0][0] = "Jmeno"; //First line of final table NAME
bmi[0][1] = "Vaha"; // WEIGHT
bmi[0][2] = "Vyska"; //HEIGHT
bmi[0][3] = "BMI"; //BMI based on calc.
bmi[0][4] = "Text"; //Final result
for(int y=1;y<pole;y++){
pa++;
x++;
System.out.print("Zadej svoje krestni jmeno: ");
jmeno = input.nextLine();
System.out.print("Zadej svoji vahu v Kg: ");
vaha = input.nextDouble();
System.out.print("Zadej svoji vysku v m: ");
vyska = input.nextDouble();
System.out.println("Vase informace byly uspesne ulozeny! ");
bmi[1][0] = jmeno; //These values should somehow increase but idk
how atm and be assign with the patient which
will be printed at the end.
bmi[1][1] = vaha2;
bmi[1][2] = vyska2;
bmi[1][3] = telo3;
bmi[1][4] = vysledek;
}
// System.out.println("Tisknu tabulku");
// telo1 = vyska * vyska; //Some calc. of BMI
// telo2 = vaha / telo1;
// if (telo2 < 18.5) { //Adding text to the result variable
// vysledek = "mate podvahu";
// } else if (telo2 < 25) {
// vysledek = "Jste v normach";
// } else if (telo2 < 30) {
// vysledek = "Nadvaha";
// } else {
// vysledek = "Obezita";
// }
// String telo3 = String.valueOf(telo2); //Converting to strings
// String vyska2 = String.valueOf(vyska);
// String vaha2 = String.valueOf(vaha);
System.out.println("--------------------------------------------------");
for(i=0;i<pole;i++) {
for(j = 0; j<5; j++) System.out.print(bmi[i][j] + " ");
System.out.println();
}
System.out.println("--------------------------------------------------");
}
}
Atm the program is just printing most of the time NULL NULL NULL NULL, and it does not match with the patient number. How do add all this code to for cycle and make it automatic convert int and double to strings and then print them correctly and assign them to the BMI Array. If you have any further questing, feel free to ask.
I have corrected the issues in code. Everything is explained step-by-step in comments. I have converted variable name in English for my understanding. If you have questions. Please ask.
import java.util.Scanner;
class Pacient {
private static Scanner input;
public static void main(String args[]) {
int numberOfPatients; // Variables that saves number of patient
// Asking user the number of patients
input = new Scanner(System.in);
System.out.print("How many patients do you want?: ");
// I have change this to nextInt
// From javadoc "Scans the next token of the input as an int"
// It is essentially next() + parseInt()
numberOfPatients = input.nextInt();
// nextInt() does not move cursor to next line
// using nextLine() here would move it to next line and close
// previous line otherwise it creates issue when you will use next/nextLine again
input.nextLine();
// String[][] array = new String[Rows][Columns];
// For each patient there is a row. Since in the code there is header
// as well that's why we need numberOfPatients + 1
String[][] bmi = new String[numberOfPatients + 1][5];
// All corresponding columns
bmi[0][0] = "Name"; // First line of final table NAME
bmi[0][1] = "Weight"; // WEIGHT
bmi[0][2] = "Height"; // HEIGHT
bmi[0][3] = "BMI"; // BMI based on calc.
bmi[0][4] = "Result"; // Final result
// Starting from 1. Skipping header
for (int y = 1; y <= numberOfPatients; y++) {
// Using y instead of an int. This way the loop will
// automatically move to next row
// Instead of saving it to variable and then to array
// I am saving it directly
System.out.print("Enter your first name: ");
bmi[y][0] = input.nextLine();
System.out.print("Enter your weight in Kg: ");
bmi[y][1] = input.nextLine();
System.out.print("Enter your height in m: ");
bmi[y][2] = input.nextLine();
// Using the information from above to calculate BMI
// Basically I am storing and calculating at the same time
// parseDouble converts String into double
// Math.pow(a,b) is powber function. a is base and b is exponent
double weight = Double.parseDouble(bmi[y][1]);
double heightSquare = Math.pow(Double.parseDouble(bmi[y][2]), 2);
double bmiCalculated = weight / heightSquare;
// Based on BMI assigning result in result column
bmi[y][3] = bmiCalculated + "";
if (bmiCalculated < 18.5) {
bmi[y][4] = "You are underweight";
} else if (bmiCalculated > 18.5 && bmiCalculated < 25) {
bmi[y][4] = "You are normal";
} else if (bmiCalculated > 25 && bmiCalculated < 30) {
bmi[y][4] = "You are overweight";
} else {
bmi[y][4] = "You are obese";
}
System.out.println("Your information has been saved successfully!");
}
System.out.println("--------------------------------------------------");
// In java 2D arrays are multiple 1D array stacked on each other
// bmi.length gives the number of rows
// Basically you iterate through each row and print each individual row
// like 1D array
for (int i = 0; i < bmi.length; i++) {
// bmi[i] gives ith row. Which is 1D array. So you can print it like normal array
for (int j = 0; j < bmi[i].length; j++)
System.out.print(bmi[i][j] + " ");
System.out.println();
}
System.out.println("--------------------------------------------------");
}
}
Your declaration of array and implementation is conflicting. You've fixed the first dimension and kept the second, variable. But you're using as if the first one is variable and second is fixed.
You should declare your array like
String[][] bmi = new String[pole+1][4];
pole+1 because you're using first row for table headings
Your first loop should look like this
for(int y = 1; y < pole+1; y++){
for(int z = 0; z < 4; z++){
String data="ask user for data";
bmi[y][z] = data; //similar for all
}
}
Your output for loop will also look like above.
this is such a simple problem but for some reason, I cant wrap my head around Array of Objects or Object Arrays. All I have to do is take in 5 user inputs, and create a class called Height, create object array and store user inputs into obj array and print the average. I'm kinda stuck.
class Height{
int total=0;
int count=0;
public Height(int y) {
total=total+y;
count++;
}
public void print() {
System.out.print("The average is: "+total/count);
}
}
public class ObjectArray {
public static void main(String[] args){
Scanner s=new Scanner(System.in);
System.out.println("Enter 5 heights in inches: ");
int[] x=new int[5];
int total=0;
for(int i=0;i<x.length;i++) {
x[i]=s.nextInt();
}
Height[] h=new Height[x.length];
for(int y=0;y<x.length;y++) {
h[y]=new Height(x[y]);
}
h.print();
}
}
Maybe I'm over complicating it. The problem right now is that I cannot invoke h.print();. I've tried different iterations, ex: taking out the print method and doing all the printing after every iteration.
Your approach is wrong. Your Height class appears to be responsible for the evaluation of the mean value. Hence, you should put all values inside a single Height instance, instead of generating a new instance for each user value.
However, h is an array of Heights object, while print() method is defined on a single Height instance. In order to call such method, you have to access one of the objects contained in h, that is h[0].print().
I'm assuming that your goal is simply to print the average of all the heights recieved via user input.
Your code in your main method is a tad confusing, so correct me if I'm wrong in any of the examples I give here. You should, instead of creating the x[] array, simply add the user input for the five values to Height.total in a for loop, and increase the Height.count variable by one each loop through. This should look something like this:
for (int i = 1; i <= 5; i++) {
// System.out.println("Please enter the next height: ");
Height.total += s.nextDouble();
Height.count++;
}
Then, you can run Height.print();.
I would also recommend adding a System.out.print(""); command to let the user know that they should enter the next value. That's the comment I left in the example code I gave above.
You have to design your Height in a way that match your requirement :
you need different Height with for each one a value
you need to know how many instances there is
For that, you need a private value, and a static counter :
class Height {
private int value = 0;
private static int count = 0; // static => nb of instances
public Height(int y) {
value = y;
count++;
}
public static int averageOf(Height... heights) {
return Arrays.stream(heights).mapToInt(h -> h.value).sum() / count;
}
}
To get the average, because it doesn't depend on a particular instance, you can have a static method, that sums all the value of the Height given and divide by the nb of instance
And use like :
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int nb = 5;
System.out.println("Enter " + nb + " heights in inches: ");
Height[] heights = new Height[nb];
for (int i = 0; i < heights.length; i++) {
heights[i] = new Height(Integer.parseInt(s.nextLine()));
}
System.out.println("Average is " + Height.averageOf(heights));
}
I am studying loops and am attempting a sample question here to use only a loop to ask the user to enter in the name of the person, height in feet first, then inches and then to find the tallest. I understand how to do the majority of it.
Could anyone point out where I am going wrong? I began writing the code and realised that I can't declare the persons names without knowing how many people the user will enter. I can't get my head around it.
I want to prompt the user with the questions but also update it to person [2], person [3], person [4] etc. depending on how many people they entered in initially.
Apologies for not wording this correctly. Any help is appreciated. I understand lines 10, 11 and 12 are probably wrong.
class HeightTest
{
public static void main(String[] args)
{
int noOfPeople;
int index;
int feet;
int inches;
String personOne;
String personTwo;
String personThree;
System.out.print("Enter a number of people ");
noOfPeople = EasyIn.getInt();
for (index = 1; index <=noOfPeople; index++)
{
System.out.println("Enter the name of person " + index);
personOne = EasyIn.getString();
System.out.println("Enter feet portion for " + personOne);
feet = EasyIn.getInt();
System.out.println("Enter inches portion for " + personOne);
inches = EasyIn.getInt();
}
}
}
You have a very good start. All you need to do now is keep track of the heights that are entered, and compare them to the largest one input so far. If the height for the current loop iteration is larger than the current largest, store it as the largest.
In pseudocode:
int largestHeightInches = 0;
for( i = 1; i <= noOfPeople; index++ ) {
currentHeightFeet = GetInt();
currentHeightInches = GetInt();
currentHeight = currentHeightInches + currrentHeightFeet * 12;
if( largestHeightInches < currentHeight ) {
largestHeightInches = currentHeight;
}
}
You would have to create an array of Persons to acheive what you want.
Here's a snippet.
Create a class called Person
public class Person
{
int index;
int feet;
int inches;
String name;
}
create a main Test class to contain your main method, and do something like this
public class Main{
public static void main (String[] args)
{
// get the number of people in noOfPeople as you do now.
Person[] pArray= new Person[nOfPeople]
for(Person p: pArray)
{
System.out.println("Enter the name of person " + index);
p.name = EasyIn.getString();
// ...etc
}
}
}