Arrays¶
Like ArrayLists
s, arrays are used to store multiple values of the same
type. For example, here is an array containing four temperature measurements:
float[] temps = { 2.4, -1.5, 3.0, 2.7 };
Notice the []
bracket in the type for temps
— that’s what tells
Processing this is an array. We can access individual elements of an array
using []-bracket notation like this:
println(temps[0]); // 2.4
println(temps[1]); // -1.5
println(temps[2]); // 3.0
println(temps[3]); // 2.7
If you try to access at value a position before the beginning of an array, or past the end, you get a run-time error:
println(temps[-1]); // oops: ArrayIndexOutOfBoundsException
println(temps[4]); // oops: ArrayIndexOutOfBoundsException
All Processing (and Java) arrays have a couple of important properties:
Once created, their size can never change. This is the major difference between arrays and
ArrayList
s. Recall that anArrayList
s can grow (and also shrink) in size as necessary.So, for example, if you want to add one more temperature reading to
temps
, you can’t —temps
can only ever store 4 numbers. You will need to a create a new, larger array to store more numbers.The items in an array are store contiguously, i.e. they are right beside each other in memory. Thus, arrays don’t use any excess memory, and individual elements can be accessed very quickly using []-notation.
Creating Arrays with New¶
The temps
array above was created using array initializer notation, i.e.
we directly assigned it a list of numbers.
Another way to create an array is to use new
, e.g.:
String[] label = new String[3];
label
is a String[]
array of size 3, with each element initially set
to null
. You use =
to assign individual values:
label[0] = "active";
label[1] = "done";
label[2] = "pending";
println(label[0]);
println(label[1]);
println(label[2]);
You use new
to create arrays when you know how big an array should be, but
you don’t yet know what the elements are.
Processing Each Element of an Array¶
Suppose you want to print each element of an array to the console. The usual way to do that is with a loop, e.g.:
float[] temps = { 2.4, -1.5, 3.0, 2.7 };
for(int i = 0; i < temps.length; ++i) {
println(temps[i]);
}
temps.length
is the number of elements in the array. The index variable
i
starts at 0 because all Processing (Java) arrays start at 0. The
condition is i < temps.length
(not i < temps.length
!) because the
last index position of an array is always temps.length - 1
.
Here’s how you can sum the values of temps
, and calculate its average:
float sum = 0.0;
for(int i = 0; i < temps.length; ++i) {
sum += temps[i];
}
println(sum); // 6.6000004
float average = sum / temps.length;
println(average); // 1.6500001
Processing’s pixels Array¶
Every Processing program has access to a special color[]
array called
pixels
that stores the color of the individual pixels on the screen.
For example, this program sets every pixel on the screen to be a random color:
void setup() {
size(500, 500);
loadPixels();
for(int i = 0; i < pixels.length; ++i) {
pixels[i] = color(random(256), random(256), random(256));
}
updatePixels();
}
Before you access pixels, you must be sure to call loadPixels
, and after
you have modified pixels
you must call updatePixels
. Forgetting to
call either of those functions can cause your program not to work.
Since the screen is 500 pixels high and 500 pixels wide, there are exactly
\(500 \times 500 = 250000\) values in pixels
, i.e. one quarter of a
million values. If, say, your screen was 1920 by 1080 pixels, then
pxiels
would have \(1920 \times 1080 = 2073600\), i.e. over two
million values.
Here’s an interesting program that let you draw on a white screen with a red circle, and then changes red pixels to a random color whenever you press a key:
void setup() {
size(500, 500);
background(255);
smooth();
}
void draw() {
noStroke();
fill(255, 0, 0);
ellipse(mouseX, mouseY, 50, 50);
}
void keyPressed() {
loadPixels();
for (int i = 0; i < pixels.length; ++i) {
if (pixels[i] == color(255, 0, 0)) {
pixels[i] = color(random(256), random(256), random(256));
}
}
updatePixels();
}
Using Arrays with Functions¶
You can pass arrays as parameters to functions, and also return them as values. For example, this applies the absolute value function to every element in an array:
void absAll(float[] arr) {
for(int i = 0; i < arr.length; ++i) {
arr[i] = abs(arr[i]);
}
}
For example:
float[] scores = { -3.22, 6.09, -1.1 };
absAll(scores);
// now scores is { 3.22, 6.09, 1.1 }
This one returns a new int[]
array initialized to { 0, 1, 2,
..., n }
:
int[] range(int n) {
int[] result = new int[n];
for(int i = 0; i < n; ++i) {
result[i] = i;
}
return result;
}
For example:
int[] start = range(6);
// now start is { 0, 1, 2, 3, 4, 5, 6 }
It’s often useful to test if an array contains a particular value. One way to
do that is with contains
:
int find(int x, int[] arr) {
for(int i = 0; i < arr.length; ++i) {
if (arr[i] == x) {
return i;
}
}
return -1;
}
find
returns the index of the first location in arr
that contains
x
. If x
is not anywhere in the array, then -1 is returned. For
example:
int[] nums = {-1, 5, -3, 5, 0};
println(find(5, nums)); // 1
println(find(0, nums)); // 4
println(find(2, nums)); // -1
Questions¶
- What are the main differences between arrays and
ArrayList
s? - How many elements are in the array
arr
? - Write a line of code that creates a new array of 350
int
values namedarr
. - For the array
points
, what’s the smallest valid index value, and the largest valid index value. - For a screen that’s \(h\) pixels high and \(w\) pixels wide,
exactly how many values are in the
pixels
array? - What does the standard Processing function called
sort()
do? Hint: check the Processing documentation!
Programming Questions¶
The inverse of the RGB color (r, g, b) is (255 - r, 255 - g, 255 - b). Write a program that draws something on the screen, and when you press any key every pixel on the screen is replaced by its inverse color.
Write a function called
reverseInts
, with return-typevoid
, that takes anint[]
array as input and reverse its elements.For example:
int[] ages { 7, 3, 9, 8, 11, 11 }; reverseInts(ages); // now ages is { 11, 11, 8, 9, 3, 7 }
Write a function called
fillInts
, with return-typeint[]
, that takes twoint
s as input:n
, the size of the returned array, anda
, the initial value of every element in the array.For example:
int[] ones = fillInts(4, 1); // { 1, 1, 1, 1 } int[] negs = fillInts(5, -12); // { -12, -12, -12, -12 }