RU beehive logo ITEC dept promo banner
ITEC 120
2007fall
ibarland,
jdymacek

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs

lect14b
arrays

Reading: Chapter 7.
Some powerpoint slides for Chapter 7 are also available on the course's Blackboard (WebCT) page.

Arrays vs Lists

Suppose we want to process the temperature every day in January. How can we represent that data?
double[31], which we use as:

 
java.util.Random randy = new java.util.Random();
double LO = 20.0;
double HI = 40.0;

double[] temps;                               // Declare.

temps = new double[31];                      // Allocate.


temps[0] = 35.0;      // We'll fill the array with random numbers.
temps[1] = 22.7;
temps[2] = 30.0;
temps[3] = //...
//...
temps[30] = 23.4;


// Isn't there a better way to initialize each location?
// Yes -- use a loop, to get the *computer* to count 0..30 for us:

// Initialize our model with random numbers between LO and HI.
for (int i = 0; i<temps.length; ++i) {
  temps[i] = LO + (HI-LO)*randy.nextDouble();  // Initialize.
  }
In BlueJ, we'll inspect the array. It's an object which has fields named “0”, “1”, … through “30”. (You might notice it also has a field named “length”.)

Examples of when to use arrays (rather than lists)

Case Study

Example: count how many times each character occurs in a String.

representing char: Characters are represented by short ints in Java; most ordinary letters are encoded by numbers in 32...127. Java lets you do arithmetic on char: try (in Code Pad)
We can use this conversion between int and char to help us have letters correspond to indices: 'A' will be at index 0, 'B' will be at index 1, etc.. In general, for a char ltr, if ltr holds an upper-case letter then we can use ltr - 'A' as an index.
/** Adapted from Java Foundations, Chpt 7, example 7.3
 */
class LetterCounts {
    public static final int NUM_LETTERS = 26;  // Named constant.

    private String msg;
    private int otherCount;
    private int[] upperCounts = new int[NUM_LETTERS];  // Declare and allocate.
    private int[] lowerCounts = new int[NUM_LETTERS];


    /** Constructor.
     * @param src A String to count the letters of.
     */
    public LetterCounts( String text ) {

        msg = text;
        otherCount = 0;

        // Initialize our declared, allocated arrays:
        for ( int i = 0;  i < NUM_LETTERS; ++i ) {
            upperCounts[i] = 0;
            lowerCounts[i] = 0;
            }

        // Now, look at every character in our argument:
        for ( int i = 0;  i < text.length();  ++i ) {
            char ltr = text.charAt(i);
            if ('A' <= ltr && ltr <= 'Z') {
                upperCounts[ ltr-'A' ] = upperCounts[ ltr-'A' ] + 1;
                }
            else if ('a' <= ltr && ltr <= 'z') {
                ++lowerCounts[ ltr-'a' ];
                }
            else {
                ++otherCount;
                }
            }

        }


  /** Return a String with the results of counting the letters.
   * @return a String with the results of counting the letters.
   */
  public String toString() {
    String resultSoFar = "";
    for (int offset=0; offset < NUM_LETTERS; ++offset ) {
      resultSoFar += (char)(offset+'A') + ": " + upperCounts[offset] + "\t"
                  +  (char)(offset+'a') + ": " + lowerCounts[offset] + "\n";
      }
    return resultSoFar + "Other: " + otherCount;
    }

  public int[] getUpperCounts() { return this.upperCounts; }
  public int[] getLowerCounts() { return this.lowerCounts; }
  
  }
      

Arrays vs Lists

In practice, lists prove much more flexible than arrays: it's much more common to have data of the form “0 or more data” than “exactly 100 data”.3

actionListsarrays
The type java.util.LinkedList<Double> double[]
constructor new java.util.LinkedList<Double>() new double[50];
add-at-end myList.add( 23.4 );
access ith element myList.get(i) myArray[i]
change ith element myList.set(i,23.4) myArray[i] = 23.4
increment ith element
(useful only when the collection holds numbers)
myList.set(i, myList.get(i)+1 ) myArray[i] = myArray[i] + 1 or
myArray[i] += 1 or
++myArray[i]
determine the size/length myList.size() myArray.length
convert to String myList.toString() java.util.Arrays.toString(myArray)
Can hold primitive types? no yes

main

BlueJ has a rich interface for interacting with Java programs: you can call any method of any class. Most IDEs have a much more limited interface: They let you choose a certain class, but then you can only call one specific (static) method of that class:


/**
 * Write a description of class Acronym here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Acronym {

  /** A test driver which makes an acronym from its input,
   * printing the results to SYstem.out.
   * @param args The words of input.  Each String must be non-empty (and non-null).
   */
  public static void main( String[] args ) {
    System.out.println( "A " + args.length + "-letter acronym for "
                      + Acronym.wordsToString( args, " ", "\"", "\"" )
                      + " is "
                      + "\"" + Acronym.acronym(args) + "\""
                      + "." );
  }

  /* Return a single string, concatenating each word in an array of Strings.
   * @param words the individual Strings.
   * @param between What to put in between each word; usually " " or ", ".
   * @param before What to start the answer with; often "".
   * @param after What to finish the answer with; often "".
   */ 
  public static String wordsToString( String[] words, String between, String before, String after ) {
    String innards = "";
    if (words.length > 0) {
      innards += words[0];
      }
    for ( int i=1;  i < words.length;  ++i ) {
      innards += between + words[i];
      }
    return before + innards + after;
    }
    
  /** Return an acronym for an array-of-words, each letter capitalized.
   * and separated by a ".".
   * @param words An array of single words.  Each String must be non-empty.
   * @return an acronym for an array-of-words, each letter capitalized.
   */
  public static String acronym( String[] words ) {
    String asf = "";   // "acronym so far"
    for ( int i=0;  i < words.length;  ++i ) {
      asf += words[i].toUpperCase().charAt(0) + ".";
      }
    return asf;
    }
      
      
  }
There is nothing special about the method-name “main” except that it's been chosen as the de facto starting method by most IDEs. The input argument -- an array of Strings -- is a convention from the UNIX operating system. This input is the primary way your java program gets initial information from the operating system, when your java program is launched: a fixed number of words. For example, from a UNIX shell:
java Acronym hello, world

Review and different perspective

Arrays are like lists, but:

Why a new data structure, if a List can already do everything an array can, and yet the array is limited to a fixed size?

If a list is a line-up bag of suspects (er, objects), then an array is a bus of objects.

When creating an array, initialize all the fields immediately. If you can't, that's a good indication that you want to use a List instead.

(Note that when you add into the middle of a list, it changes what index each later object has. With an array, you can't add into the middle, so that isn't an issue. You can only overwrite the existing contents of a particular bus-seat-#.)

Processing arrays: for-loops are very natural. Also, for-each loops still work, and are perfect when you don't need the index-number to process the element.
double[] data;
data = new double[500];
java.util.Random r = new java.util.Random();

// Initialize array contents with random numbers in [0,1).
for (int i = 0;  i < double.length;  ++i ) {
  data[i] = r.nextDouble();
  }


// Find the average:
double sumSoFar = 0.0;

for ( double d : data ) {
  sumSoFar += d;
  }

double average = sumSoFar / data.length; 
// N.B. if data.length is 0, then floating-division gives Double.NaN.

1

Hmm... Some locations are properties (with rents, sale-prices, etc.); other locations are events (community-chest, Go, etc.). How to have one single class that can represent both these elements which have many differences, but also many similarities (they all have images, might have people on them, can trigger events, etc.).

Really this is two problems: union types (properties vs. events-only), and shared functionality (what both types do). Interfaces and inheritance (next week) provide a good solution to these problems!

     

2 Usually, in Java, you can extend classes to give them additional behavior. However, in Java, you can't extend array classes, so this class was kludged on.      

3 And when using a list, there are two common choices: LinkedList<Type> and ArrayList<Type>. Nearly always, ArrayList<Type> is the better choice. Despite its name, ArrayList is not an array; it's a list.      

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs


©2007, Ian Barland, Radford University
Last modified 2007.Dec.06 (Thu)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme