|
home—info—labs—hws—exams
textbook—java.lang docs—java.util docs—archive
We have seen lists, with their methods get(int) and add(Object), as a way of large sequences of data.
By the way, lists (which can hold any item, at each index) are very much like Strings (which hold a char at each index).
We now show yet another way of collecting sequences of data: arrays.
action | String | Lists | arrays |
The type | String | java.util.LinkedList<Double> | double[] |
constructor | new String(stringLiteral) (or, just stringLiteral) | new double[50]; | |
add-at-end | — | myList.add( 23.4 ); | — |
access ith element | myStr.charAt(i) | myList.get(i) | myArray[i] |
change ith element | — (Strings are immutable) | 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 | myStr.length() | myList.size() | myArray.length |
convert to String | myStr | myList.toString() | java.util.Arrays.toString(myArray) |
Can hold primitive types? | no (only chars) | no | yes |
Hmns r gd t ndrstndng sntncs, vn wth ll vwls rmvd.We'll write three versions of removeVowels, which is given a String/list-of-Character/array-of-char, and it returns a another String/list-of-Char consisting of all the non-vowels in the input. For example, removeVowels( "Humans are good at understanding sentences, even with all vowels removed." ) would return the above answer as a String.
reminder: Sometimes people confuse the variable referring to the list, with the loop-variable which refers to an element of the list. They are very different!
You don't confuse an apple with a bag-of-apples; you don't confuse a bus-passenger with a bus; so similarly don't confuse an item with a collection-of-items.
int[] data; data = new int[500]; // Initialize (allocate) the array itself. for (int i=0; i<data.length; ++i) { data[i] = i*i*i; // Initialize the value stored at index i. } |
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”.2
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. } |
As mentioned, an array can only get and set, while a java List can do all that and more. You'll see in 220 that arrays can be used to implement class List. What follows are examples where many people would content themselves with arrays, rather than lists.
Or suppose that we want a music-program to store information about each measure of a symphony. (Note that music scores are indexed by measure#; during rehearsal it's common to say “let's start from measure 95”.)
52 cards in deck:
public static final int NUM_SUITS = 4; public static final int NUM_RANKS = 13; Card[] deck; cards = new Card[NUM_SUITS*NUM_RANKS]; // No 'Card' objects created, yet! for ( int i = 0; i<temps.length; ++i) { deck[i] = new Card( (i%NUM_RANKS)+1, i/NUM_RANKS ); } |
Representing the Monopoly board: exactly 40 locations. (Presumably, you'd have a class Location to represent one location.3
Note that using % with the array size is common:
Location[40] board; board = new Location[40]; // ... spend time initializing the array contents ... PairODice pd = new PairODice(); int position = 33; pd.roll(); position = (position + pd.getTotal()) % board.length; |
The ordinal suffix for numbers 0...99. That is, "0th", "1st", "2nd", "3rd", etc..
String[] suffixes; suffixes = new String[100]; suffixes[0] = "th"; suffixes[1] = "st"; suffixes[2] = "nd"; //... |
Note that these suffixes might be one place to use Java's helpful automatic-array initialization syntax:
String[] suffixes = { "th", "st", "nd", "rd", "th" } |
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.
- 'a',
- 'a'+0,
- (char)99
Note that unlike casting for double and int, there aren't methods inside class Character to help with these conversions (?*#%!); casting is the only way to explicitly convert between char and int.- 'a'+1,
- 'a'+'1' (not concatenation!, nor incrementing by 1),
- 'm'-'a' (“how many letters after 'a' is 'm'?”),
- 'm' > 'a',
- ¡Unicode characters have a larger range!: (char)8617 or (char)2000 or (char)21488.
/** 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; } } |
1 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. ↩
2 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. ↩
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!
↩home—info—labs—hws—exams
textbook—java.lang docs—java.util docs—archive
©2008, Ian Barland, Radford University Last modified 2008.Dec.01 (Mon) |
Please mail any suggestions (incl. typos, broken links) to ibarlandradford.edu |