Arrays

Like ArrayListss, 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 ArrayLists. Recall that an ArrayLists 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

  1. What are the main differences between arrays and ArrayLists?
  2. How many elements are in the array arr?
  3. Write a line of code that creates a new array of 350 int values named arr.
  4. For the array points, what’s the smallest valid index value, and the largest valid index value.
  5. For a screen that’s \(h\) pixels high and \(w\) pixels wide, exactly how many values are in the pixels array?
  6. What does the standard Processing function called sort() do? Hint: check the Processing documentation!

Programming Questions

  1. 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.

  2. Write a function called reverseInts, with return-type void, that takes an int[] 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 }
    
  3. Write a function called fillInts, with return-type int[], that takes two ints as input: n, the size of the returned array, and a, 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 }