Java Tutorial - Part V
Written by pergesu
Graciously hosted by RRFN (
www.promodtecnologies.com)
Feel free to distribute this as much as you like. Just don't modify it at all;
distribute it in its entirety. Check back for more Java tutorials to spread
around as well.
Table of Contents
-------------------------
1) Intro
2) What are arrays?
3) An array program
4) Stuff to know
5) Rand and averaging
6) Passing arrays to methods
7) Why pass by reference
8) Linear search
9) Wrap up
-------------------------
Section 1
Intro
-------------------------
In the last tutorial, you learned how to write and call methods. You basically
just learned the syntax of a method, how do define it, and what the different
parts do. I know I said that we were going to cover more complex methods, but I felt
a change was in order. In this part of the series, you will learn all about arrays
and how to use them.
-------------------------
Section 2
What are arrays?
-------------------------
An array is just a collection of data. The data all have to be the same type.
Furthermore, arrays take up contiguous areas of memory. This last fact isn't
important to you as a programmer, but it is something you should know.
Why should you use arrays? They make your life simple. Suppose you create a program
that gets 10 grades from the user and averages them. You could create 10 variables,
and have the user enter data in that way. I guess if you wrote a function to handle
the input it wouldn't be too bad, but I still wouldn't like typing out 10 function
calls. Just think if you had to do 200 grades! You'd get pretty friggin bored. That's
what arrays are created for. They allow you to group a number of variables into one
variable. You access all the data through one name. It's pretty slick, as you'll see
in the next section. But first, I want you to see how to declare an array:
int intArray[] = new int[5];
The brackets- [] - next to the variable signify that you're creating an array. In
this case, the array is an array of integers, and is called intArray. On the right
hand side of the equals sign you have new int[5]. When declaring an array, you must
use new. new is an operator that assigns memory. In this case, it's saying "allocate
an array of 5 integers and assign it to intArray."
An array has to have a specified number of elements. An element is one part of the
array, it's sort of like a variable. I said earlier that an array is a collection of
data. Each one of these data is called an element. An array may be of any size, as
long as there's enough memory in the computer. You can access an individual element
of the array through index referencing. This is a fancy way of stating which element
you want to play with. You'll see how this all works in the example program. But
enough talk...
--------------------------
Section 3
An array program
---------------------------
// ArrayEx.java
// Shows how to use arrays
public class ArrayEx
{
public static void main(String args[])
{
int array[] = new int[5]; // Creates an integer array of 5 elements
// Access each element individually, and assign it a value
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
array[4] = 5;
// Access each element and print value
System.out.println(array[0]);
System.out.println(array[1]);
System.out.println(array[2]);
System.out.println(array[3]);
System.out.println(array[4]);
}
}
If you compile and run this program, you'll get the numbers 1-5. Not anything
special. Now, an explanation of the code
int array[] = new int[5];
This was explained earlier. It creates an array of integers called array with 5
elements. The number in between the brackets on the right hand side is that number of
elements.
array[0] = 1; //and so forth
This shows how you can access an individual element of the array. The first thing I
want you to note is that we treat it just as we would any other integer. That's
because it is! The variable array is a bunch of integers, and each element is just an
integer. So you can do whatever you want with it that you would any integer.
See the number in the brackets? It's called the subscript, and it's the element
you're currently accessing. Array elements range from 0 to arraylength-1. So if you
have an array with 17 elements, the last element in the array is [16]. So array[0] is
the first element, array[1] is the second, and so on.
In that program, we created an array, initialized every element, and displayed the
values of the elements. But see how we had to individually access each element? It
doesn't seem like it saved much time. All it really did was cut back on the number of
variable declarations we made, so it doesn't seem that much of a benefit. But the
beauty is that you can make the subscripts of the array be variables. Hell, you throw
an array in a loop, and it's awesome. Check this out:
// ArrayEx2.java
// Another example of arrays, but with variable subscripts
public class ArrayEx2
{
public static void main(String args[])
{
int array[] = new int[200];
for(int i = 0; i < 200; i++)
array[i] = i * 2;
for(int i = 0; i < 200; i++)
System.out.println(array[i]);
System.exit(0);
}
}
Go ahead, compile and run it. See what it does, then see how it does it...
int array[] = new int[200];
We just created another array of integers. But we made it really big this time, so we
could appreciate arrays. Can you imagine having to type up 200 variable declarations?
First for loop
Here we loop 200 times. Because we're going through the array on each pass, and the
primary intent is to do something with the array, it's commonly called looping
through the array. Here we loop through it, and access each element. We then assign
it a variable value, which is the iteration of the loop times 2. Remember that an
iteration is a pass through the loop. This shows you that you can make the subscript
a variable, not just a fixed value.
Second for loop
We're just looping through the array, printing the values of each element.
----------------------------
Section 4
Stuff to know
-----------------------------
There's a way to assign values to an array right as you declare it. An example is
below:
int a[] = { 3, 4, 9, -7, 16 };
There are some thing to notice. First off, you don't have to have a new in there. In
fact, you can't. By creating the curly brackets and placing values in there, you're
telling the compiler the length of the array. You've also filled the elements with
values. But you still treat it the same way as you would any other array.
This may seem sort of bone headed to some of you, but I just want to make sure that
you all know that you can create an array of any data type. Objects, primitive types,
heck, you can even make an array of arrays. I've just been using integers in the
examples because they're easy to create examples with. Just keep in mind that you can
create an array of whatever you want.
Every array knows it's own length. An array has a property, which believe it or not,
is called length. You can access it using this synxtax:
arrayName.length;
It's quite useful in loops. Very often you'll write a program, and possibly want to
change the number of elements in the array. Instead of hardcoding the loops, you can
just use the array length, and you have to make fewer changes to your code. In all
future examples, I will use the length property of arrays. So don't be freaked when
you see that. You know what it is cause I just told you.
----------------------------
Section 5
Rand and averaging
-----------------------------
This program will be a bit more complex, though nothing over your head. Still
sticking to example stuff. But you're going to learn a few things here. First off,
you'll learn how to generate and use random numbers. You'll also get another chance
at looping through an array, and performing some operations using the data within
the array. So here we go:
// RandAve.java
// Demonstrating random numbers and arrays
public class RandAve
{
public static void main(String args)
{
int array[] = new int[500];
int sum = 0;
double average;
for(int i = 0; i < 500; i++)
array[i] = (int) (Math.random() * 100);
for(int i = 0; i < 500; i++)
sum += array[i];
average = sum / 500;
System.out.println("The sum of the integers is " + sum);
System.out.println("The average of the integers is " + average);
}
}
For an explanation...
int array[] = new int[500];
Create a big array of integers
First for loop
Just fill the array with random numbers
array[i] = (int) (Math.random() * 100);
Here we get a random number between 1 and 100 and assign it to the current element.
Math.random() is a method that lets you get a random number. It actually returns a
floating point value, so to get a number that you want, you have to multiply it by
the maximum possible number. So if you want it to be numbers between 1 and 5, you
would have Math.random() * 5. Note the (int) type-cast in front of it. Remember that
I type cast temporarily changes the data type, so that the compiler can understand
it. Because random() returns a floating point value, you need to cast it to an
integer. That's what this does. If you're wondering how we were able to access the
method without importing anything... Java is pretty cool and automatically imports
some stuff for you. It'll import stuff in the Math package, the System package, and a
couple others. Recall that a package is a group of classes, and they're grouped
primarily by functionality so that you can easily find them.
Second for loop
Gets the sum of all the numbers in the array
average = sum / 500;
Gets the average
Then we display the sum and average of all the numbers in the array.
----------------------------
Section 6
Arrays to methods
-----------------------------
Previously you've learned what a benefit methods can be in your programs. Hopefully
you've also seen how beneficial arrays can be as well. It would make sense that you
should be able to combine both of these benefits to create even more powerful
programs. You already know how to write methods and pass them arguments, so you
really already know how to pass arrays. It's just like passing any other data type.
There are just a few nuances of passing arrays to methods that I want to point out.
The first thing is is that this gets into pass-by-reference, something which I
briefly mentioned earlier. In all the methods that you've written so far (You HAVE
been writing programs on the side, haven't you?), you've passed the variables by
value. This means that whenever you call a method, the value of the variable is
passed, nothing else. You might have noticed that you can modify a variable in your
method all you want, but it remains unchanged outside that method. That's the case
with primitive types, at least.
Pass-by-reference occurs when you pass a method or an object to a method. When this
occurs, the value of the variable is not passed to the method, but rather the address
of the variable. Because the method has access the the address of the variable, any
actions that it takes actually occur on the variable itself, not just a copy. So any
modifications you make to the variable will show up in all other methods. Remember
that this is only with arrays and objects.
There are a number of languages, C and C++ being two, that allow you as the
programmer to determine when variables are passed by reference or by value. In Java,
however, this is not the case. This is the only major limitation I've encountered
with Java so far, and it's something that if you program C or C++, you'll sorely
miss. However, it does reduce errors for the (as yet) unseasoned programmer.
That's a lot of talk, and I know you wanna learn to program, so let's check some
code!
// PBR.java
// Demonstrates pass-by-reference versus pass-by-value
public class PBR
{
public static void main(String args[])
{
int array[] = new int[10];
for(int i = 0; i < array.length; i++)
array[i] = i;
for(int i = 0; i < array.length; i++)
System.out.println("Before any mod, array[" + i + "] = " + array[i]);
for(int i = 0; i < array.length; i++)
modElement(array[i]);
for(int i = 0; i < array.length; i++)
System.out.println("After modElement, array[" + i + "] = " + array[i]);
modArray(array);
for(int i = 0; i < array.length; i++)
System.out.println("After modArray, array[" + i + "] = " + array[i]);
System.exit(0);
}
public static void modElement(int x)
{
x += 3;
System.out.println("Inside modElement, x = " + x);
}
public static void modArray(int array[])
{
for(int i = 0; i < array.length; i++)
{
array[i] += 5;
System.out.println("Inside modArray, array[" + i + "] = " + array[i]);
}
}
}
Compile and run this program, you may be surprised by the output.
The first thing we do is assign values to elements of the array, then display the
contents. Then we pass each element of the array to modElement. Inside this method,
we modify the value of the element, and display it. Then we display the contents of
the array back in the main() method. You will see that the elements are the same as
they were before modElement was called. Next we call modArray(). The entire array is
passed to this method. As I said earlier, arrays are passed by reference, so the
address of the array is going to the method. This means it has direct access to the
contents of the array. The method adds five to each element in the array and then
displays the contents. Then we display the contents back in main(). Notice that the
values are the same. They were changed in modArray, and the changes affected the
array back in main(). But you didn't do anything differently. That's because Java
passes arrays by reference.
----------------------------
Section 7
Why pass by ref?
-----------------------------
If you wondered why Java passes arrays and objects by reference, but primitive types
by value, then you're asking smart questions. Let's think about it sort of closely.
An integer takes up 8 bits, or one byte of memory. So if you pass it to a method, and
it's passed by value, the integer takes up 2 bytes of memory- 1 in the calling
method, and one in the called. Now take an array or an object. An array may have a
large number of elements. In an array of 100 integers, it will take up 200 bytes of
memory if passed by value. This still isn't much, but it gets larger with more
elements. Consider an object. You haven't learned too much about them yet, but they
can contain a large amount of information. A single object could easily take a couple
kilobytes of memory, depending on its size. Passing by value would use quite a bit of
memory. Now if you were to have an array of objects... it could be pretty taxing on
the computer. It's not too much of a problem with today's RAM prices, but copying all
that data still take quite a while, and you lose performance.
As you know, passing by reference just passes the address of the variable to the
method. Because of this, no data has to be copied over. Just think of the performance
gain achieved when a method receives simply 0x2854 (an address in memory) rather than
100 integers. A single hexadecimal value as opposed to a whole bunch of values. It
makes sense.
---------------------------
Section 8
Linear search
---------------------------
One common application of arrays is to contain a bunch of data, and then search
through the data to find a particular entry. There are a number of different
algorithms, and I'll go over the simplest right here. It's something that I'm sure
you could do on your own.
// LinearSearch.java
// A linear search of an array
import javax.swing.*;
public class LinearSearch
{
public static void main(String args[])
{
int a[] = new int[100];
String toSearch;
int num;
for(int i = 0; i < a.length; i++)
a[i] = (int) (Math.random() * 700);
toSearch = JOptionPane.showInputDialog("Enter the value to search for");
num = Integer.parseInt(toSearch);
for(int i = 0; i < a.length; i++)
{
if(a[i] == num)
{
JOptionPane.showMessageDialog(null, num + " was found at a[" + i + "]", "Results",
JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
}
JOptionPane.showMessageDialog(null, num + " was not found ");
System.exit(0);
}
}
None of this is really a problem for you. It just creates an array of integers, asks
the user for a number to search for, and then loops through the array checking to see
if the number exists. It does what you want, but it's extremely inefficient. First
off, it just loops straight through. It examines every single element in order, until
it finds what it's looking for. What if it doesn't ever find what it's looking for?
Then it loops through the whole array. It works, but it's not the most efficient
mechanism.
-----------------------
Section 9
Wrap up
-----------------------
This part of the tutorial has gone well over 400 lines, so I think it's probably
time to stop. You covered a lot in this part. You learned how to declare and use
arrays, how to loop through them, getting their length without actually knowing it,
and how the compiler passes different types of variables differently. It's quite a
bit to cover at one time. I left off with saying that the linear search of arrays are
inefficient. I'll cover efficient searching and sorting techniques in a later
tutorial. The next tutorial will most likely go over method overloading. In the mean
time, work on some programs! You already have more than enough knowledge to create
pretty complex programs. Want a big challenge? Why not try to create a really simple
poker program? I guarantee you can do it, you have all the tools, so you just need to
do it. Until next time,
-pergesu