Lecture 5: Loops and 1D Arrays
Objectives
- Read and write loops
- Understand one dimensional arrays
- Be able to use a loop to traverse an array
Why is looping useful in computation?
A loop is similar to an if statement, in that one needs to decide when to exit the loop (most of the time). Looping is useful for:
- Being able to process a batch of survey results to do a study
- Searching through a list of webpages to find the ones that match a keyword
- Creating a countdown for a timer for a shopping cart
- Other examples?
Right now, if we want to repeat code, we have to copy and paste it.
public class Countdown {
public static void main(String[] args) {
// Set up an initial count value
int count = 10;
// Now print and decrease it one by one
System.out.println(count--); // "--" acts AFTER we resolve the value, so it prints a 10
System.out.println(count--); // it prints a 9
System.out.println(count--); // it prints a 8
System.out.println(count--); // it prints a 7
System.out.println(count--); // it prints a 6
System.out.println(count--); // it prints a 5
System.out.println(count--); // it prints a 4
System.out.println(count--); // it prints a 3
System.out.println(count--); // it prints a 2
System.out.println(count--); // it prints a 1
System.out.println("Blastoff!");
}
}
The loop above prints out a countdown from 10 down to 1, and then Blastoff!
. In addition to using the unary subtraction operator in a potentially confusing way, you can see there is a lot of duplicate code, which, in general, is extremely undesirable.
It turns out, we can use a loop to reduce the duplicate code above while maintaining its functionality.
The while
loop
Java has two looping structures, one of them being the while
loop. This loop will run while a condition is true
; it is just like an if
statement, except when you reach the curly block, the computer will jump back up to the conditional check:
public class Countdown {
public static void main(String[] args) {
// Set up an initial count value
int count = 10;
while (count > 0){
System.out.println(count--); // "--" acts AFTER we resolve the value, so it prints a 10 initially
}
System.out.println("Blastoff!");
}
}
You can immediately see the reduction in code. Let’s run this in the visualizer.
A while loop uses the reserved word while
to start, followed by parentheses, like an if
statement, for a conditional check.
The for
loop
While loops are great, but they’re typically meant to be used when one doesn’t know in advance how many times the loop should be executed – perhaps you want to keep prompting a user to re-enter a password until they pick a valid one:
String password = getPasswordFromForm(); // this is an imaginary method that returns a password from a web form
boolean isValid = check(password); // another imaginary method that checks whether or not the password is valid
while (!isValid){
System.out.println("Sorry, your password was not valid; please try again.");
= askUserToReEnter();
password = check(password);
isValid }
System.out.println("Thank you for entering a valid password!");
Java has an alternative to the while
loop for cases when you know in advance how many times you want the loop to execute: the for
loop. You can see its elegance for our countdown timer above, where we know in advance exactly how many times we want to run the loop body:
public class Countdown {
public static void main(String[] args) {
for(int count = 10; count > 0; count--){
System.out.println(count);
}
System.out.println("Blastoff!");
}
}
Here we have moved count
inside the loop declaration, where we first initialize it. Then, we have the same conditional check as before, count > 0
. And finally, we’ve moved the count--
also into the loop declaration: we will visit this piece of code only after the loop is done (so we don’t need the decrement inside the loop body anymore). Let’s run this code in the visualizer to make sure we understand the three steps above.
Arrays in Java
Now that we know how to loop, we can dream up some interesting use cases. What if we wanted to go through a list of resumes and see who we want to interview? How can we store these job applicants?
In Java (and other languages) you can store a sequential list of elements in something called an array. It’s basically an ordered list, and best explained with an example:
public class ArrayExample
{
public static void main(String args[])
{
int[] array1 = {2, 4, 5, 22, 3};
System.out.println(array1.length);
double[] array2 = new double[4];
[0] = 23.2;
array2[1] = 7.1;
array2[2] = array2[0];
array2[3] = 4;
array2
//array1[0] = 1.5; <--- not allowed, why?
//array2[4] = 8; <--- not allowed, why?
System.out.println(array2.length);
}
}
Above, we are storing the ordered list of integers 2
, 4
, 5
, 22
, 3
in a variable called array1
. You can see the type of this variable is int[]
, where the brackets are new and indicate this is an array (of integers in this case). In Java an array can only store one type of value which it must declare; above we see both an int[]
array and a double[]
array.
Note the curly braces around the ordered list in array1
. You can also declare an array by only specifying its length; Java will fill up the array with zeroes (if it’s numeric). The syntax is shown above on the third line with the new
keyword.
Brackets, with an index, can be used to read and write values, and you can get the size of an array using the length
field. Array indices start at index 0. The length of an array is always specified either explicitly or implicitly, as seen above.
Arrays in memory
Let’s run the code above to make sure we understand it.
One of the things you’ll notice is that arrays are not stored on the stack; the array itself is stored in a separate part of memory in Java called the heap. Now it makes sense why we’ve been drawing memory this way all semester; the visualizer does it too. Java uses the heap to store objects where the size can be large (like an array), while the stack is used to store variables (which always fit in a small, known space). In the stack, an array variable stores the memory address to the contents of the array on the heap. Right now, this just seems like extra work, but it will be extremely important for tracing code in Quiz5 and beyond.
When assigning any two variables of matching type with =
, remember that we always just “copy the box.” This is also true for arrays, as long as we understand that in terms of what an array “stores in the box,” this is not a list of values (even though it looks like it), but is actually a memory address of the start of the entire array.
Consider the following program:
public class ArrayExample
{
public static void main(String args[])
{
int num1 = 4;
int num2 = 5;
= num2;
num1 = 3;
num2
int[] array1 = {2, 4, 5, 22, 3};
[0] = 3;
array1[1] = array1[1] -7;
array1int[] array2 = array1;
[2] = 3333;
array2[3] = -1000;
array1}
}
Let’s trace this through in the visualizer first, and then dive deeper on paper to understand what is going on with memory and how arrays are stored.
Note the difference between how primitive types like integer, double, and boolean are all stored on the stack directly (see num1
above). By contrast, complex types like arrays, string, and objects (later) are always stored with a memory address on the stack, while the actual contents are in the heap.
Arrays and for loops
Now that we understand arrays, we can use for
loops to traverse them:
public class ArrayExample
{
public static void main(String args[])
{
int[] array1 = {2, 4, 5, 22, 3};
for(int i = 0; i < array1.length; i++){
System.out.println(array1[i]);
}
}
}
Let’s trace this code together in the visualizer.
Next class
We’ll start HW4 to get more practice with loops and arrays.