Activity 6.1.1. Other analogies?
Can you think of another example of something that is like an array (like a row of lockers)?
int score1
, score2
, score3
, β¦ , score10
. But what if we had a hundred exam scores? That would be a lot of variables! Worse yet, what if we didnβt know when we were writing the program how many scores we would need to deal with?
int
valuesβ where n is a number that isnβt necessarily known until the program runs. And we might also like to be able to treat that collection of n values as a single value for some purposesβbeing able to assign it to a variable or pass it as an argument to a methodβwhile still being able to access the individual values. Even better would be if this new kind of value knew how many values were in it so we could do things like write loops that access each of the component values no matter how many there are.
score1
and score2
, we can have one variable named scores
and access the elements like scores[0]
and scores[1]
. Anything we can do with a regular variable, such as using it in an expression or assigning it a value we can also do with an array element.
0
, not 1
. Most programming languages these days use this kind of zero-based indices but a few, including many block-based languages such as Snap!, use one-based indices where the first item in a list is at index 1
. One-based indices fit better with how English speakers number things so if you are coming from Snap! or if Java is your first programming langauge, it may take a little while to remember that the first element of an array is at index 0
. (Sometimes programmers will refer to the first element of an array as the βzerothβ element to be super clear. Or maybe just because βzerothβ is kind of fun to say.)
int
values, we use the type int[]
which is pronounced βarray of int
β or βint
arrayβ.
int
variable we write:
int score; // One int value
int
, we write:
int[] scores; // A reference to an array of any number of int values
null
which is the reference equivalent of 0
for an int
or 0.0
for a double
which means, βno objectβ. Any variable with a reference type that hasnβt been assigned an actual reference value will have the value null
.
0
, 0.0
, false
, or null
depending on the element type and another that lets us specify specific values that will be put into the new array.
new
followed by what looks like an array type but with an int
expression (often a literal int
) inside the square brackets that says how big the array should be. The whole expression causes a new arrayβs to be created and space allocated for itβs object data and then evaluates to a reference to that new array. We then need to do something with that reference like assign it to a variable or possibly pass it a method.
int[] nums = new int[10]; // a reference to a new array of ten ints
String[] strings = new String[1000000]; // a reference to a new array of a million Strings.
// clobber the old references
nums = new int[10]; // reference to new array of same size
strings = new String[10]; // reference to new array of different size
0
for elements of type int
0.0
for elements of type double
false
for elements of type boolean
null
for all reference typesnew
but instead of specifying the size of the array inside the square brackets, we place a list of initial values in curly braces ({}
) after the square brackets:
int[] highScores = new int[] { 99, 98, 98, 88, 68 };
String[] names = new String[] { "Jamal", "Emily", "Destiny", "Mateo", "Sofia" };
int
with initial values specified, space is allocated for the specified number of items of that type and the values in the array are stored directly in the arrayβs object data. When we create an array of an reference type such as String
, space is allocated to hold the references in the array. The actual object dataβString
objects in this caseβlive somewhere else in memory and only references are stored in the array.
new
and the array type since Java can infer the type from the variable declaration.
int[] highScores = { 99, 98, 98, 88, 68 };
String[] names = { "Jamal", "Emily", "Destiny", "Mateo", "Sofia" };
someMethod(new int[] { 1, 2, 3 });
System.out.println
calls to print their lengths.
length
. Weβll learn more about instance variables in ChapterΒ 8Β Classes but for now all we need to know is that we can access the size of any array with the dot operator, a dot .
followed by the word length
immediately after any expression whose value is an array reference. For example, arrayName.length
accesses the length of the array referenced by the variable arrayName
.
int
expression that gives us the index of the element we want to access. Remember that an index is a number that indicates the position of an item in a list, starting at 0.
arrayname[index]
can be used anywhere a regular variable can be used. That is, we can use it in an expression to get the value of an element of the array. But we can also use it on the left side of an assignment operator to change the value stored at that position in the array.
System.out.println(highScores[0]); // Print the zeroth element of the array
highScores[0] = 99; // Assign a new value to the zeroth element of the array
System.out.println(highScores[0]); // Print the zeroth element of the array, now 99
highScores[0] += 5; // Add five to the value, raising it to 104
highScores[0]++; // Increment the value so it's now 105
ArrayIndexOutOfBoundsException
.
highScores
?
String[] cars = {βHondaβ, βVolvoβ, βBMWβ};
String[] cars = {βHondaβ, βVolvoβ, βBMWβ};
highScore
or name
at index 7 above to see what happens. The index must be between 0 and the length of the array - 1 or it will give an error message called ArrayIndexOutOfBoundsException
.
int
. In fact, it is somewhat unusual to use a literal index. More likely we will use at least a variable or even a more complex arithmetic expression. For instance given an array like highScores
, the expression highScores.length - 1
gives us the index of the last element of the array. Here are some examples, assuming i
is an int
variable that is a legal index into highScores
:
highScores[i]; // Score at index i
highScores[i + 1]; // Next score
highScores[highScores.length - 1]; // Last score
highScores[(int (Math.random() * highScores.length)]); // Random score
(int) (Math.random() * max)
will return a number from 0
up to max
. Whatβs the maximum number it can be for this array?
int
parameterpublic void changeIntParameter(int n) {
// changes the variable n
n = 20
}
int num = 10;
changeIntParameter(num); // pass copy of the value 10
System.out.println(num); // prints 10
changeIntParameter
accepts an int
argument which is stored in the parameter n
. That parameter is a variable that only exists until changeIntParameter
returns. In this method, n
is assigned a new value but the code has no effect because immediately after that the method returns and the variable n
doesnβt exist any more. The assignment to n
has no effect on wherever its argument value came from. In this case because the argument came from the variable num
some people expect the change to n
to also change num
. But itβs the value of num
that was passed to changeIntParameter
. This would perhaps be more obvious if we had instead called changeIntParameter(10)
. Few people would expect the value of 10
to suddenly be 20
!
int[]
parameterpublic void changeArrayParameter(int[] ns) {
// changes the variable ns
ns = new int[] { 20 };
}
int[] nums = new int[] { 10 };
changeArrayParameter(nums); // pass copy of reference to nums
System.out.println(nums[0]); // prints 10
nums
is a reference to a newly created int[]
rather than just an int
. But when changeArrayParameter
is called, a copy of that reference is passed as the argument and stored in the methodβs parameter ns
. Then, like the code in changeIntParameter
, changeArrayParameter
immediately assigns a completely new value to its parameter, clobbering the one that was there just like changeIntParameter
clobbered the value 10
with the new value 20
. Then the method returns and the change to ns
no longer matters because ns
no longer exists.
public void changeArrayElement(int[] ns) {
// changes the referenced array
ns[0] += 10;
}
int[] nums = new int[] { 10 };
changeArrayElement(nums); // pass copy of reference to nums
System.out.println(nums[0]); // prints 20
nums
is a reference to a newly created array and a copy of that reference is passed to changeArrayElement
where it is stored in the parameter ns
. But changeArrayElement
doesnβt assign a new value to ns
. Instead it uses an array access expression to assign a new value to the zeroth element of the referenced array. Since nums
and ns
are both references to the same underlying object data, this assignment actually changes the array so the change is visible after changeArrayElement
returns.
Math.random()
and the length
of one of the arrays and save it in a variable called index
.
printHtmlImage
method has been given to get the image URL online and print it out as an HTML image.
length
attribute.
new
, all of its elements are initialized to the default values for the element data type. The default value for int `` is ``0
, for double
is 0.0
, for boolean
is false
, and for a reference type (like String
or a class you have created) is null
.
[]
are used to access and modify an element in a 1D (one dimensional) array using an index.
0
through one less than the length of the array, inclusive. Using an index value outside of this range will result in an ArrayIndexOutOfBoundsException
.
i
that is used in loops to traverse an array. In challenging AP problems, you will see mathematical expressions inside the square brackets ([]
). For example, array[i-1]
refers to the previous element right before the ith element in array, and array[i+1]
refers to the next element after the ith element. In the problems below, note that arrays can be passed in as arguments to methods and returned as values, just like any variable.
array
initialized to {4, 10, 15}
, which of the following represents the contents of the array after a call to mystery(array, 2)
?
public void mystery(int[] a, int i)
{
a[i] = a[i-1] * 2;
}
mystery
method, will result in array2
having the contents {5, 10, 20}
?
public int[] mystery(int[] a, int i, int value)
{
a[i + 1] = a[i] + value;
return a;
}
int[] array1 = {5, 10, 15};
int[] array2 = mystery(array1, 0, 10);
{5, 15, 15}
.int[] array1 = {5, 15, 20};
int[] array2 = mystery(array1, 0, 0);
{5, 5, 20}
.int[] array1 = {5, 10, 15};
int[] array2 = mystery(array1, 1, 10);
int[] array1 = {5, 15, 20};
int[] array2 = mystery(array1, 2, 0);
ArrayIndexOutOfBoundsException
.int[] array1 = {5, 10, 15};
int[] array2 = mystery(array1, 1, 20);
{5, 10, 30}
.