Introduction
Today’s lab will be reviewing and applying the concepts involved in the usage of Arrays, to store and modify data.
Review
Before we begin let’s review some loops and branching logic.
Here we have a method NumberMeaning which should return a string containing a message about each of the numbers entered by a user. If the user enters a number less than -1 the program should skip this value and go to the next. If the user enters exactly -1 the program should end and return the string “Thanks for playing!”. Otherwise, the appropriate string is printed: if the number is less than 100 it is considered a small number, and if it is greater than or equal to 100 it is considered a large number.
Currently there are 2 problems with this program.
- First, when the user enters a negative number, the program enters an infinite loop.
- Second, when the user enters a -1 the program does not exit (This is in addition to a negative number creating an infinite loop).
Can you help us find these errors? Hint: only two lines should need a fix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.util.Scanner;
public class ReviewLab {
public String numberMeaning(){
Scanner userIn = new Scanner(System.in);
String retString = "";
System.out.print("Welcome to the game! Please enter a number: ");
int userVal = userIn.nextInt();
while(true){
if (userVal <= -1){
retString = "Please enter a Valid Number\n";
}
else if(userVal == -1) {
continue;
}
else {
retString = "User Number is " + userVal + " and is";
if (userVal<100){
retString += " a small number!\n";
}
else {
retString += " a large number!\n";
}
}
System.out.print(retString + "\nEnter a number: ");
userVal = userIn.nextInt();
}
userIn.close();
return "\nThanks for Playing!";
}
}
Once you feel like you have the answer, please copy and paste this code into the Zybooks or any other IDE/Text editor and make the necessary changes. To run this, add a main method public static void main(String[] args) which calls the numberMeaning method. Pay Close Attention Is numberMeaning a static or non-static method? What does this mean?
Arrays Review
Arrays in short are just a form of storage, like a box with dividers. Each section of the box can hold a single value and is numbered for easy access. So, rather than having to declare 20 separate variables to store 20 different values/objects, we can instead use an array of size 20. Also like a box, an array is immutable meaning its size cannot change without making a whole new array.
Arrays prove useful because while items exist in the array, you can reference, use, and modify those items without having to remove them from the array.
Arrays are explicitly typed. Much like our variables, an array has a specific type of item it can store. For example, if you make an Array of Strings, you cannot store an int inside that array. This is because Arrays are statically typed, so every value has to match the type in the array. However just like our variables, any variable that could be held within another data type can be stored inside an array of the larger data type due to java’s implicit casting. Implicit casting means the two data types are compatible, so we can assign the value of a smaller data type to a larger data type. For example: an array of doubles can be filled with bytes, shorts, ints, floats, and of course doubles because all of these values can be implicitly cast to a double.
So if you tried to store a double in an array of type int, java will give you a type Mismatch error, this because a double cannot be implicitly cast to an int.
Declaring Arrays
Declaring an array is much like declaring any other object as we will need a type and the keyword new.
Let’s look at this example and go over the different parts.
dataType[] name = new dataType[size of array];
- dataType can be any primitive variable or object type. This represents what will be stored in the array.
- The first empty square brackets [] tells the program that this is an array.
- The new keyword, just like creating an object, tells the system to create space in memory for the array.
- [size of array] is an integer that determines the total number of items that can be stored in the array.
Accessing Arrays
Accessing an Array is done using the [ ] accessors. Accessing an array is very similar to using the .charAt() method of Strings, the only difference is that the [ ] accessor also allows you to change what value is at that index. Also just like Strings arrays are zero indexed, meaning the first item in the array is at index 0. For example:
int[] practiceArray = new int[10]; //Line 1
practiceArray[4] = 10; //Line 2
System.out.println(practiceArray[4]); //Line 3
- Line 1 Initializes a new array named practiceArray.
- Line 2 Sets the value at index 4 of practiceArray to 10.
- Line 3 Accesses the value stored at index 4 in practiceArray, and prints the value 10.
Arrays and Loops
Arrays and loops go together like peanut butter and jelly, interacting with each other similar to how Strings and loops do.
Arrays, like Strings, have a .length tool. However unlike Strings, whose .length is a method, the array .length is not a method and is a constant variable of the array. NOTE because this is a variable and not a method, there is no parentheses () This is because Arrays lengths are FIXED, which means that once the array’s length is set in construction, the length cannot be modified without creating a new array. Arrays lengths are fixed as that is exactly how many spots you have allocated in memory. If you change that, you would need to allocate more or less memory. Because of this, we are able to use for loops even if the array is empty.
int[] test = new int[20];
for (int i = 0; i < test.length; i++){
test[i] = i*2;
}
The above for loop initializes the array values with the doubles of each of the indexes. Even though no values had been entered into the array initially, the length of the array was determined at declaration, which in our case is length 20. This allows us to loop across the array even if it is empty with the .length capability.
Arrays and Methods
One of the most powerful aspects of Arrays is their ability to function between methods. An array can be passed to a method just like any other variable, however, arrays are passed by reference, this is because the value of the array variable without brackets is a reference to where the array is stored in memory. What this means is that if the contents are changed in one method, those changes will be carried through other methods, as all the methods access the same memory location. This is true for any case of using Arrays and methods, meaning even if you do not intend to change the array, any changes made will stay. This makes it important to specify whether your method will modify the array or not.
Let’s look at an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Cups{
public static void fancy(String[] coffeeSizes){
coffeeSizes[2] = "grande";
}
public static void main(String[] args){
String[] sizes = {"short", "tall", "medium", "venti", "trenta"};
//at this point sizes is the array: {"short", "tall", "medium", "venti", "trenta"}
fancy(sizes);
//after the above method call, sizes is now {"short", "tall", "grande", "venti", "trenta"}
}
}
As you can see from the above, we did not update our array at any point with the assignment operator. Because arrays are pass by reference, whenever the array gets changed in other methods, the changes carry through back to the original. Try messing around with this a bit! Arrays are so cool!
Now let’s get into the lab!
Today you will be working in a class named StudentInfo.java. This class has 3 member variables…
- grades: an array of doubles storing grades
- names: an array of Strings storing names
- maxGrade: a double storing the maximum grade possible.
Because we are using two separate member variable arrays (names and grades), we will be assuming that the indicies match between arrays. This means that a student with name names[0] has a grade of grades[0], a student with name names[1] has a grade of grades[1], etc. So if a students name is found at index 0 of the names array, their grade will then be found at index 0 of the grades array, and so on.
Another class testStudent.java, will be used for testing.
STEP 1
For step one we will be covering some older material, making a constructor and some basic getters and setters.
Constructor
Let’s make a constructor! This constructor will take a double maxGrade, and an int totalStudents as parameters.
Your constructor header should look like this:
public StudentInfo(double maxGrade, int totalStudents)
Inside the constructor, let’s first initialize the member variables grades and names arrays. This is where we want to use the keyword new. The size of both the names and grades arrays will be the parameter variable totalStudents.
Finally initialize the member variable maxGrade to the parameter variable maxGrade. HINT: What keyword needs to be used since our member variable and parameter variable share the same name?
Getters and Setters
All of the below getters and setters will be accessible everyone and need an instance of an object to be created in order to be called. Now, let’s make getters and setters for our grades and names member variables. Because these are arrays, our getters and setters will be used to get and set individual values in these arrays. A precondition for all the below getters and setters, is that the index will be valid.
- getGrade(int index): this getter will take in an int (the index we want to look at) and return the grade at the given index, from the grades array.
- getName(int index): this getter will take in an int (the index we want to look at) and return the name at the given index, from the names array.
- setGrade(int index, double newGrade): this setter will take in an int and a double (an index and a new value) and will set the grades array at the given index to the new value.
- setName(int index, String newName): this setter will take in an int and a String (an index and a new value) and will set the names array at the given index to the new name.
Testing
Use the testStudent.java file to test your work as you go, uncommenting lines after writing the appropriate methods.
STEP 2
Now we will be creating a method getGradeByName(String name) in order to get a grade given a name.
This method will be accessible everyone and need an instance of an object to be created in order to be called. This method looks for the given name, given as a parameter variable, in the names member variable array. If the name is found, return the grade associated with that name (i.e. same index as the name, but in the grades array as explained above). If the name is not found, this means the student does not exist, so return -1.
A precondition for this method is that all names in the array will be unique, meaning if the name is found there will only be one of it in the names array.
Testing
Use the testStudent.java file to test your work as you go, uncommenting lines after writing the appropriate methods.
STEP 3
Now we will be creating a method setGradeByName(double grade, String name) in order to set a grade given a name.
This method will be accessible everyone and need an instance of an object to be created in order to be called. This method looks for the given name, given as a parameter variable, in the names member variable array. If the name is found, the appropriate grade is set to the grade parameter variable (i.e. same index as the name, but in the grades array as explained above). If the name is not found, neither the grades array nor names array is changed.
A precondition for this method is that all names in the array will be unique, meaning if the name is found there will only be one of it in the names array.
Testing
Use the testStudent.java file to test your work as you go, uncommenting lines after writing the appropriate methods.
STEP 4
Next let’s make a method numBestGrades().
This method will be accessible everyone and need an instance of an object to be created in order to be called. This method will be looking through the grades member variable and finding students who fit the below criteria. This method returns the number of students found whose grades fit the below criteria.
Criteria: student has a grade between 50 and maxGrade (inclusive)
Some preconditions for this method are: No grade will be greater than maxGrade, and maxGrade will always be greater than or equal to 50.
Testing
Use the testStudent.java file to test your work as you go, uncommenting lines after writing the appropriate methods.
STEP 5
Finally, let’s finish with the method findBestStudents().
This method will be accessible everyone and need an instance of an object to be created in order to be called. This method will return an array of Strings, which holds the names of all the students who fit the below criteria. Criteria: student has a grade between 50 and maxGrade (inclusive)
This uses the above concept of names and grades indices matching across arrays for each student (i.e. a student named names[0] has a grade of grades[0]). Not all students are guaranteed to qualify, meaning the length of the new qualifying students array may not match the length of the names/grades arrays.
HINT: what method from above may be useful in determining the length of our new qualifying students array?
Testing
Use the testStudent.java file to test your work as you go, uncommenting lines after writing the appropriate methods.