CS 3230 - Chap 3 Notes

Fundamental Programming Structures in Java

"To-day we have naming of parts..."

This page contains the high points from Chapter 3. The first 4 pages of this chapter were covered in the Lab 1 notes, so I will start with "Data Types" on pg. 39.

There are not a lot of code samples on this page because I figure most of you know about this stuff already. However, the chapter is peppered with code snippets.

Variables

Variables in Java are strongly typed, meaning every variable declared stores one type of thing.

Primitives (p.39)

These are non-object data types; Java is not a "pure" OO language because it has these, but they are efficient and convenient.

Integer (p.39) - byte (8-bit), short (16-bit), int (32-bit), long (64 bit). int is by far the most practical. Note that unlike C / C++, the sizes are not platform dependant; this is an improvement. Literal consists of numbers and an optional sign, i.e. 113, -267.

Floating-Point (p.40) - float (32-bit), double (64-bit). Per pg.41 at the top, don't use these if you need precision, use BigDecimal instead. Literal consists of numbers with a decimal in the middle and an optional exponent.

Character (p.41) - char (16-bit). Java uses Unicode natively, meaning it can support large character sets such as Kanji and Hangul. Literal is a single character enclosed in single quotes, i.e. 'a', '%'. Special characters (including extended Unicode characters) are escaped with an initial backslash (see p.41).

Boolean (p.42) - boolean. Literal values are true and false. Booleans cannot be converted to numeric types. C++ has played catch-up to Java here, but I like the C++ keyword better, cuz it's shorter (bool).

Wrapper Classes - each of these primitives has a wrapper class which includes parsing / conversion methods and handy constants such as not-a-number (NaN) and positive / negative infinity; this solves the problem of initializing a variable to a very large or small number.

Declaring (p.42)

You declare a variable by giving its type followed by an identifier (a non-reserved word that you or somebody else has chosen). Epxamples are on p.42 and the text that follows explains valid identifiers.

Constants (p.43) - variables can be declared constant by putting the final keyword in front. (in C++ it's const)

Assignments (p.43)

You assign a value to a variable by using a single equals (=) sign. Compare with equivalence (==) below.

Initialization (p.43) - You can declare a variable and assign it a value all on one line: int weekdays = 5;

Operators (p.44)

Like it's predecessors, C and C++, Java has a large number of operators. (Not quite as many as C++, though.)

Arithmetic (p.44) - plus (+), minus (-), multiply (*), divide (/), modulo (% -- remainder of division).

Shortcut (p.44) - combination of assignment and math operation; makes code more compact. Example: x += 5;

Increment / Decrement (p.45) - increment (++), decrement (--). Can be done either as prefix (before) or postfix (after).

Relational (Equality / Inequality) (p. 45 bottom) - <, >, <=, >=, !=, == (double equals, different from assignment, but you will not get burned by it as you do in C / C++).

Boolean (p.46 top) - not (!), and (&&), or (||). Note that the && and || operators short-circuit: if the left-hand side has already determined the result of the expression, the right hand side will not be executed. This is often useful.

Bitwise (p.46) - and (&), or (|), xor (^), complement (~), left shift (<<), right shift (>>), right shift with zero-fill (>>>). These are very occasionally useful.

Math Functions / Constants (p.47) - All the extra buttons you would find on a scientific calculator are found in the Math class: sin, cos, pow, log. The Math class also contains the constants PI and E. (You might want to use PI in your Robocode project

Conversions (p.47 very bottom) - Many strongly typed languages are a royal PITA because you need to cast everything all the time. Java will automatically promote smaller types to larger types (such as going from an int to a long) with no explicit casting because no loss of precision will occur. This is called widening conversion. The chart at the top of p.48 tells the story.

Casting (p.48) - When you try to assign a larger data type's value into a smaller data type (such as going from an int to a short) a cast is required because there is a possible loss of precision. This is called narrowing conversion. You use parens around a type, i.e. int num = (int)Math.random();

Parentheses / Precedence (p.49) - Some operators take precedence over others ("or bind more tightly"). The table on p.49 shows the precedence order. When in doubt, add parentheses.

Control Flow (p.60)

There are three types of programming statements:

  1. Sequential
  2. Conditional
  3. Repetative

Sequential is simplest, when we hit a semicolon, we advance to the next statement. Let's have a look at how the other ones are done.

Conditional (or "Branching") (p.61)

if (p.61) - General-purpose conditional, as the expression can use any combination of the relational / boolean operators. If the true/false expression in the following parentheses evaluates to true, the curly-brace delimited block underneath is executed, otherwise it is skipped. Note that it is possible to omit the curlies and just have a single statement, but I advice against it.

if...else (p.62) - As above, but the else block is executed if the expression evaluates to false.

if...else if...else if... (p.63 top) - General-purpose multi-way switching. A final else condition can be used as a catch-all if none of the previous conditions were met.

switch (p.70 bottom) - Specialized form of multi-way switching; the cases only test equivalence (no >, <, etc. or compound expressions). A default case can be added at the end as a catch-all if none of the previous cases were matched. Note that cases can "fall through" if you omit the break keyword.

Repetative (or "Looping")

while (p.64) - Indeterminate loop. Works like the if statement, but the block continually executed until the condition is false. This means you should have some code within the while loop that will eventually make the condition false. Loop executes a minimum of zero times.

do...while (p.65) - As above but the condition is tested at the bottom of the loop rather than the top. Loop executes a minimum of 1 time.

for (p.68) - Determinate loop. Executes a fixed number of times based on starting value, ending value, and step value. (N.b. The for loop is actually much more flexible than this, but iteration is the most common usage.) Appropriate for occasions where you know beforehand how many times you want the loop to execute. Best used for processing arrays.

Breaking Out (p.71)

You can exit a loop (or conditional!) at some point in the middle of the loop rather than the beginning or end. Note that these should be used sparingly.

break (p.71 bottom) - Exits a loop. Often used in conjunction with an if statement to create a conditional exit.

labeled breaks (p.73) - This is Java's alternative to the highly-controversial goto statement. (There is no goto statement in Java.) Rather than allowing you to transfer control flow to anyplace in the program, you can break out to a clearly labeled point, usually this is the top of a loop or somewhere else within the loop.

Fundamental Objects

One of the long-standing problems with C and C++ is that arrays and strings are both treated as pointers. This makes them error-prone (running off the end of an array) and unweildy (strdup, str(n)cpy, str(n)cat, free, etc.). The Java designers tidied up this troublesome area by making strings and arrays real-live objects with properties and methods all their own. Additionally, there are some other commonly-used objects which we will look at now.

Strings (p.49 bottom)

Assignment (p.49 bottom) - Just use the assignment operator (=) and a string literal: a sequence of characters delimited by double quotes.

Concatenation (p.50 top) - The plus (+) operator is overloaded to concatenate if one of the arguments is a string. (Code: StrCat.java)

Length (p.50 bottom) - Strings in Java can tell you how long they are! Just use the length() method.

Modifying (p.50 bottom) - The String object in Java is immutable; you cannot edit characters in place. If you want to do that, use the StringBuffer class instead. The Java designers did this for efficiency. This is one of those things that people complain about the first time they see it, but in practice it's not nearly as big a deal as they thought it would be.

Equivalence (p.52) - Use the equals() method of the string class to test if two strings have the same letters in the same order in the same case. Do not use the equals (==) operator as that will just test if the strings are found at the same location in memory.

The API documentation for the Java String class can be found here. (Pages 54-55 in your book shows you what it looks like.)

Arrays

An array is a list of values indexed by a number.

Declaration (p.76-77) - Two ways: int ary[] (legacy), or int[] ary (new-and-improved). See the note on p.77.

Instantiating (p.76 bottom) - Because arrays are objects, you will need to make a new instance by assigning it the result of the new operator like so: ary = new int[100] (you don't have to use 100; put in any number you like for the size).

Assignment (p.76 bottom) - You can assign a value to a particular element in the array by using an index (or subscript) to indicate where you would like the value stored. Example: ary[5] = 17; As mentioned previously, the for loop is ideal for array processing, including initial assignments.

Length (p.77 top) - Arrays in Java can tell you how long they are! Simply use the length property. (Useful as part of the condition in a for loop.) Note that whereas length() is a method in the String class, it is a property in the array. Specifically, it is a constant property initialized when the array is instantiated and cannot be changed afterward. (Code: AryLen.java -- note that this code will not compile.)

Initialization (p.77 middle) - An alternative to instantiating an array, you can assign an array an initializer list contianing values that the array will be filled with. If you do this, you do not need to new the array.

Shallow / Deep Copies (p.77 bottom) - If you assign one array to another using just the assignment operator, it makes an alias to the original array. If you change the value in one list, it will also change the second. This is called a shallow copy. If you want to make a deep copy, where a new array is instantiated and populated with the values of the previous array, you can use System.arraycopy() (p.78).

Command-Line Parmeters (p.79) - Remember main(String[] args) from Lab 1? This is an array of strings that gets passed into your program from the command line. P.79 shows how it can be used.

Convenience Methods (p.82) - sorting, searching, filling can all be done with various members of the Arrays class (see p.82).

Multidimensional (p.82) - N-dimensional arrays can be created in Java but 2 or 3 dimensions are practical limits. Think of multidimensional arrays as a "list of lists" where each element in one array contains another array.

"Ragged" Arrays (p.85) - It is possible to have a multidimensional array where the lists beyond the first dimension are unequal lengths. These are called "ragged" because they are somewhat reminiscent of a piece of tattered cloth.

NumberFormat (p.57 bottom)

In C it is wonderfully easy to format numbers to certain widths and precisions; just use printf("%0.2f", dollars); In Java, it is not nearly so elegant. You have to use the NumberFormat class and tell it how you'd like your number to look (see p. 58 for gory details).

If there's an upside to the NumberFormat approach, it's that you can easily get formats for things like currencies and percents (see p.59 bottom).

Big Numbers (p.74)

BigInteger / BigDecimal (p.74 bottom) - Use these class for storing and performing math on numbers that are too big for the primitive types. You would want to use BigDecimal when extra precision in floating-point calculations is required. (See the tables on p.76 for common methods.)