25 Jan 2012 [ 201 week3 ]

Examples

This week's examples are getting more involved, so you can just download the templates within this zip file; look in the examples folder for the week3 NetBeans project. You'll be able to get the latest version from the sidebar link for future classes.

Once you've downloaded the NetBeans project, you can open it up in NetBeans (through the menu, or (in Windows at least) just by dragging the folder onto NetBeans). These examples are simple enough that any other editor will also work fine without additional setup if you want to compile them by hand.

Update: I created an alternate project format that hopefully won't depend on a particular JDK version; the NetBeans project depends on having JDK 1.7 available.

Basics

Let's take a look at the basic array syntax, and some useful utilities.

import java.util.Arrays;

public class Basics {
    public static void main(String[] args) {
        int[] a = { 1, 2, 3, 4, 5, 6, 7 };
        String[] b = new String[10]; // What is b[3]?
        boolean[] c = new boolean[5]; // What is c[4]?
        System.out.println(b[3]);
        System.out.println(c[4]);
        // Set a to a new array value.
        // Note that you can't just say a = { 4, 5, 6 }.
        a = new int[] { 4, 5, 6, 7, 8 };
        
        // Take a look at the Arrays class.  Use a method to initialize
        // all entries in b to "X".
        
        // Longer way:
        for (int i = 0; i < b.length; i++) {
            b[i] = "X";
        }
        // Shorter way:
        Arrays.fill(b, "X");
        
        // Print b to make sure it worked.
        // Try to print the values in different ways: just call
        // println with input b, and use the Arrays.toString method.
        // What's the difference?
        System.out.println(b);
        for (String s : b) {
            System.out.println(s);
        }
        System.out.println( Arrays.toString(b) );
        
        // 2-D example
        int[][] x = new int[2][2];
        for (int r = 0; r < x.length; r++) {
            for (int col = 0; col < x[r].length; col++) {
                x[r][col] = 1;
            }
        }
        
        // Reverse order of elements in a and then print all values.
        for (int i = 0; i < a.length / 2; i++) {
            int swapIndex = a.length - i - 1;
            int temp = a[i];
            a[i] = a[swapIndex];
            a[swapIndex] = temp;
        }
        System.out.println( Arrays.toString(a) );
        
        // Alternate version that creates a new array and copies
        // old array in reverse. Wasteful since it doesn't work
        // in-place.
        
        // int[] aSwap = new int[a.length];
        // for (int i = 0; i < a.length; i++) {
        //     aSwap[aSwap.length - 1 - i] = a[i];
        // }
        // a = aSwap;
    }
}

Primes

This example uses arrays to find primes more efficiently.

import java.util.Arrays;


public class PrimeSieve {
    public static void main(String[] args) {
        // A sieve method for finding prime numbers goes as follows:
        
        // Keep a list of all possible primes from 0 to 1000.
        // We don't really need entries for 0 and 1, but we'll just
        // ignore them, since it makes indexing easier.
        boolean[] isPrime = new boolean[1001];
        
        // Initialize all entries to true; we'll set to false once we've
        // proved that it's not prime.
        Arrays.fill(isPrime, true);
        
        // Then for each value (from 2 on up), cross off all multiples
        // of that value in our list.
        for (int test = 2; test < isPrime.length; test++) {
            if (isPrime[test]) {
                for (int nonprime = 2 * test; 
                        nonprime < isPrime.length;
                        nonprime = nonprime + test 
                        ) {
                    isPrime[nonprime] = false;
                }
            }
        }
        
        // After crossing off all multiples, what's left has to be prime.
        for (int test = 2; test < isPrime.length; test++) {
            if (isPrime[test]) {
                System.out.println(test);
            }
        }
    }
}

Hangman

We're going to implement a simple hangman game. Here, the ArrayList class will come in handy, since we won't know in advance how big of an array will need in some situations.

Creating and using ArrayLists works like:

ArrayList<Integer> x = new ArrayList<Integer>();
x.add(5); // x now has entries { 5 }
x.add(6); // x now has entries { 5, 6 }
System.out.println("x has " + x.size() + " elements.");
System.out.println("x[0] = " + x.get(0));
x.set(0, 55); // Set element to new value.

ArrayList provides all the same functionality of ordinary arrays (plus a lot extra), but you have to remember to use ordinary method syntax rather than the special array [] syntax.

Here's the starting point for our hangman game (which will be updated here when we're done). The project includes a dictionary file that our program will access using a standard Java method for reading bundled resources.

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class Hangman {

    public static void main(String[] args) {
        // Find included dictionary.txt file, open it, 
        // and wrap with a Scanner.
        InputStream dictStream = Hangman.class.getResourceAsStream("dictionary.txt");
        Scanner dictScan = new Scanner(dictStream);

        // Read all words in file and save in an array or collection.
        // Or, save only words of the lengths you want.
        ArrayList<String> words = new ArrayList<String>();
        while (dictScan.hasNext()) {
            String line = dictScan.nextLine();
            if (line.length() >= 7) {
                words.add(line);
            }
        }
        System.out.println(words.size());

        // Choose a random word using the Random object
        // (more convenient than Math.rand that we used before).
        Random rand = new Random();
        int index = rand.nextInt(words.size());
        String target = words.get(index);

        // Set up a guess limit.
        int misses = 0;
        int MAX_MISSES = 10;

        boolean[] correct = new boolean[target.length()];
        int numCorrect = 0;

        Scanner keyboard = new Scanner(System.in);
        // Repeatedly ask for guesses and print progress.
        // How should you track and show progress?
        while (misses < MAX_MISSES && numCorrect < correct.length) {
            for (int i = 0; i < target.length(); i++) {
                if (correct[i]) {
                    System.out.print(target.charAt(i));
                } else {
                    System.out.print("-");
                }
            }
            System.out.println();
            System.out.print("Next guess: ");
            String guess = keyboard.nextLine();
            char guessLetter = guess.charAt(0);
            boolean missFlag = true;
            for (int i = 0; i < target.length(); i++) {
                if (guessLetter == target.charAt(i)) {
                    if (!correct[i]) 
                        numCorrect++;
                    correct[i] = true;
                    missFlag = false;
                } 
            }
            if (missFlag)
                misses++;
        }
        if (numCorrect == correct.length) {
            System.out.println(target + "! You won!");
        } else {
            System.out.println("You lose!");
            System.out.println("The word was: " + target);
        }
    }
}

Readings

Read the "Arrays" chapter in the book. This arrays outline section provides a good quick review.