-
Notifications
You must be signed in to change notification settings - Fork 1
Arrays
In this section we'll be going over using and processing arrays. The array class is a powerful tool that allows us to store multiple values at once and as a result, allows us to return more than one value outside of a method for use.
- Declaring arrays
- Accessing/Editing elements
- Foreach loop
- Cloning/Copying
- Passing as arguments
- Returning arrays
An array is a group of like-typed variables/values that are referred to by a common name. Array can contains primitives data types, like integers and strings, as well as objects of a class depending on the definition of array.
An array declaration has two components: the type and the name. Type declares what kind of things the array will hold.
public class Main{
int[] numbers = ....; //the type is int and the name of the array is numbers
...
string[] names = ...; //the type is string and the name of the array is names
}
To instantiate an array, we also need to specify the size of the array. So as a recap:
First, we must declare a variable of the desired array type.
Second, we must allocate the memory that will hold the array, using new, and assign it to the array variable.
public class Main{
int[] numbers = new int[20]; //this int array has a size of 20, meaning it can hold 20 integers
}
In a situation, where the size of the array and elements of the array are already known, array literals can be used. We essentially list out the array elements without specifying the size
public class Main{
int[] numbers = {1,2,3,4,5,6,7,8,9,10}; //this int array has a size of 10, an the elements are 1-10
}
In the section above we learned how to declare an array with a specific size or with specific elements inside of it. But how do we populate the empty array? How do we change an already stored value within it?
In order to access an element from a declared array, you must use the array name with the position of the value you want to access:
> int[] arr = {1, 2, 3}; //array size 3, name arr
> int c = arr[0]; //storing 1 into variable c
> System.out.println(c);
1
Same thing goes for editing values within an array:
> int[] arr = {1, 2, 3}; //array size 3, name arr
> arr[0] = 20; //changing 1st element to 20
> System.out.println(arr[0]);
20
One very important note is that array positions start at zero. For example, if you have int[] arr = new int[10]
, the size of the array is 10 with the positions for accessing elements being 0-9.
If you tried to access the 10th element like so: arr[10] = ...
an ArrayIndexOutOfBoundsException
will be thrown.
Now that we know how to access and edit array values, lets look into processing them. Let's make a program that takes decimal numbers, prints them out, and outputs their average.
> public class Example {
> public static void main(String[] args) {
> double[] arr = {1.2, 3.2, 4.5, 0.3, 2}; //array size 5
> double avg = 0;
>
> for(int i = 0; i < arr.length; i++) { //for loop that runs until i = length of the array
> System.out.println(arr[i]); //arr[0], arr[1], arr[2], ...
> }
>
> for(int i = 0; i < arr.length; i++) { //sums up all elements
> avg += arr[i];
> }
>
> avg = (avg/arr.length); //divides sum by # of elements
>
> System.out.println("Average: " + avg);
> }
> }
1.2
3.2
4.5
0.3
2.0
Average: 2.24
Another way to process elements is to use the foreach loop or another name for it is the enhanced for loop.
Instead of taking 3 parameters in the for loop (beginning position, value to run to, update) (for(int i = 0, i < arr.length; i++)
), this takes only two which takes (element type being processed : array used in the processing) (for(double sum : arr)
).
Note: the enhanced for loop accesses all elements sequentially so it's only useful if you're processing every single element in the array.
Here is an example of the same process done with the different loops:
> double[] arr = { 1.2, 1.3, 1.4 };
> for(int i = 0; i < arr.length; i++) {
> System.out.println(arr[i]);
> }
1.2
1.3
1.4
And with the enhanced for loop:
> double[] arr = { 1.2, 1.3, 1.4 };
> for(double val : arr) {
> System.out.println(val);
> }
1.2
1.3
1.4
Here is the previous example rewritten using enhanced for loops:
> public class Example {
> public static void main(String[] args) {
> double[] arr = {1.2, 3.2, 4.5, 0.3, 2}; //array size 5
> double avg = 0;
>
> for(double val : arr) { //enhanced for loop to process all elements
> System.out.println(val); //val = arr[0], val = arr[1], val = arr[2], ...
> }
>
> for(double val : arr) { //sums up all elements
> avg += val;
> }
>
> avg = (avg/arr.length); //divides sum by # of elements
>
> System.out.println("Average: " + avg);
> }
> }
1.2
3.2
4.5
0.3
2.0
Average: 2.24
So why use the enhanced for loop? It's useful if you're going to process every single element in a given array, meaning you don't have to define the beginning and end in the parameters. Also, in some cases, using an enhanced for loop can be more efficient than a standard one.
Say you want another copy of a array, there are two ways to go about this.
Shallow copying refers to simply creating another reference to a value.
For example:
> public static void main{
> int[] array1 = {1,2,3,4,5,6,7,8,9,10};
> int[] array2 = array1; //This is the process of shallow copying, array2 basically points to array1
> System.out.println(Arrays.toString(array2)); //Arrays.toString(nameOfArray) will print out the values of array
> }
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Most of the time shallow copying is probably not what you want to do. The reason is simple, because both array1 and array2 point to the same value, changing one will change the other
For example:
> public static void main{
> int[] array1 = {1,2,3,4,5,6,7,8,9,10};
> int[] array2 = array1;
> array1[0] = 2; //Because array2 points to array1, if array1 changes, array2 will reflect that
> System.out.println(Arrays.toString(array2));
> }
[2, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Deep copying refers to creating a new array and copying the values of the first one over to the second one
For example:
> public static void main{
> int[] array1 = {1,2,3,4,5,6,7,8,9,10};
> int[] array2 = new int[10];
> //Use a for loop to copy the contents of array1 to array2, each array pointing to different references
> for (int i = 0; i < 10; i++){
> array2[i] = array1[i];
> }
> array1[0] = 2; //Since array2 points to a different reference point, changing array1 doesn't affect array2
> System.out.println(Arrays.toString(array2));
> }
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Say you want to give a method a existing array. You can easily pass the array as an argument. However, note that the method you want to pass the array to has to have the correct value type as a argument So if you want a method to receive a integer array as an argument you must create the method as:
public static void methodName(int[] arrayName){
}
The "int[]" is telling the program that it is expecting an integer type array.
If you want to pass a string arrayyou would have to create the method like:
public static void methodName(String[] arrayName){
}
And so on for char[], double[], etc.
A full coding example would go something like:
> public static void main{
> int[] array1 = {1,2,3,4,5,6,7,8,9,10};
> arrayMethod(array1); //Pass a array1 as an argument to the method arrayMethod
> }
>
> public static void arrayMethod(int[] array){
> System.out.println(Arrays.toString(array));
> }
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
NOTE: Keep in mind that when you pass an array to a method you are passing the REFERENCE point. Therefore, tempering a passed array will reflect that change back in the main method.
For example:
> public static void main{
> int[] array1 = {1,2,3,4,5,6,7,8,9,10};
> arrayMethod(array1); //Pass a array1 as an argument to the method arrayMethod
> System.out.println(Arrays.toString(array1); //Print array1
> }
>
> public static void arrayMethod(int[] array){
> array[0] = 2;
> }
[2, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Because the "array" in arrayMethod was pointing to array1, tempering with it was the same as changing array1 back in the main method.
So the question is, what if we want to pass a array to a method, mess around with it, without harming the original back in the main method? Create a deep copy using a loop.
To return an array, the method must first be configured to have the correct return type. Remember that in the previous examples, the method arguments were configured to receive a array type of either integer, String, etc. The same principle applies when returning.
For example, to return an integer type array:
public static int[] returnArrayMethod(){
}
Afterwards, you must (obviously) state which array you wish to return using the "return" method.
> public static int[] returnArrayMethod(){
> int[] arrayToReturn = {...};
> return arrayToReturn;
> }
A full coding example where the main method receives a array from another method will be something like:
> public static void main{
> int[] array1 = createArrayMethod(); //array1 will basically be created in createArrayMethod
> System.out.println(Arrays.toString(array1); //Print array1
> }
>
> public static int[] createArrayMethod(){
> int[] array1 = {1,2,3,4,5,6,7,8,9,10}; //Create the array you wish to return
> return array1; //Return array using "return" method
> }
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Create a program that asks the user to input 5 decimal numbers. Find the min, the max, and the average.
Input 5 numbers, press enter after each number:
5.5
3.45
3.14159
2.718
1.4142
Min: 1.4142
Max: 5.5
Avg: 3.244758
Implement the bubble sorting algorithm to sort an array of 10 integer values.
Bubble sort works by switching adjacent values if they are in the wrong order:
{ 4, 3, 6, 1, 9 } -> { 3, 4, 6, 1, 9 }
{ 3, 4, 6, 1, 9 } -> { 3, 4, 6, 1, 9 }
{ 3, 4, 6, 1, 9 } -> { 3, 4, 1, 6, 9 }
...
Once this loops once, it loops again and again until all values are sorted in their proper order.