Download System.out.println(".")

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
CPSC 112
Introduction to Programming
Midterm Exam Review Guide
Spring 2017 (The current version is the 2016 version, and
we will update to 2017 soon.)
This guide covers some basic topics. Please be sure to
read the lecture slides for additional topics such as
program analysis as well.
YALE DEPARTMENT OF COMPUTER SCIENCE
Table of Contents
“Native” Java.................................................................................................................................................... 4
Architecture ................................................................................................................................................. 4
Operators ..................................................................................................................................................... 4
Data Types ................................................................................................................................................... 8
Primitive Data Types ................................................................................................................................ 9
Arrays ..................................................................................................................................................... 10
Printing Output .......................................................................................................................................... 13
Generic Printing ..................................................................................................................................... 13
Formatted Output.................................................................................................................................. 14
Variables .................................................................................................................................................... 16
Local and Global (Class-scope) Variables ............................................................................................... 16
The final Keyword .................................................................................................................................. 16
Program Structure and Control Flow ......................................................................................................... 16
Using Methods ....................................................................................................................................... 16
Declaring Methods................................................................................................................................. 17
Methods with Exceptions ...................................................................................................................... 18
if (...) {…} / else if (…) {…} / else{ … } Statement ..................................................................................... 19
switch (…) {…} Statement ....................................................................................................................... 20
for (…; …; …) {…} Statement ................................................................................................................... 21
while (…) {…} Statement ........................................................................................................................ 23
do { … }while (…) Statement .................................................................................................................. 24
Loop Types ............................................................................................................................................. 24
Fencepost Loops .................................................................................................................................... 25
Program Analysis ................................................................................................................................... 25
Standard Java Classes .................................................................................................................................... 26
String .......................................................................................................................................................... 26
Regular expressions ................................................................................................................................... 29
Scanner ...................................................................................................................................................... 29
Math........................................................................................................................................................... 32
Graphics using StdDraw ............................................................................................................................. 33
Color........................................................................................................................................................... 33
Much of the material contained in this review guide is included from the Java Platform API (“Javadocs”) and The Java
Tutorials. Please see these websites for further details about the Java programming language as presented herein.
“Native” Java
We are taking artistic license in referring to “native” Java and if you do a Google search on this term, you
will probably not find anything that satisfactorily indicates what this means. Think of this phrase as a
reference to those features that are built-in to Java and that are not represented as standalone classes or
interfaces in the Jave framework / Java Development Kit (JDK). It is relevant to tackle these aspects of the
language – including operators, primitive data types, conditional statements, and loops – separately from
some of the “higher-levels” parts of the Java platform in order to build a clear foundation of the
language’s underpinnings and to distinguish simple aspects of Java from more complicated things that are
implemented by grouping these simple operations together. While the general overviews given should be
sufficient to understand what these programming conventions do and how they can be used, refer to
your textbook as needed to lookup additional information about any of the items discussed.
Architecture
Java is an architecture-neutral language, meaning that source code compiled into “bytecode” for use on
one platform can be used on any other that has the Java Runtime Environment (JRE) installed. While
integrated development environments (“IDE”’s) such as Eclipse, Dr. Java, and many others can be used to
automate the processes for compiling and running Java programs, take note of the following applications
included with the Java Development Kit (JDK) that are instrumental to building and using Java programs:



java – runs a .class file (which represents a Java application as Java bytecode) via the Java
Runtime Environment (JRE)
javac – compiles Java source code (.java files) into Java bytecode (.class files)
jar – utility for compressing multiple files (e.g., .class, .txt, .java, etc.) into a single .jar file; .class
files within a .jar file can be executed without having to decompress the .jar file in which they are
stored
Operators
The Simple Assignment Operator
One of the most common operators that you'll encounter is the simple assignment operator "=". It assigns
the value on its right to the operand on its left:
int cadence = 0;
int speed = 0;
int gear = 1;
This operator can also be used on objects to assign object references.
The Arithmetic Operators
The Java programming language provides operators that perform addition, subtraction, multiplication,
division, and reminder. There's a good chance you'll recognize them by their counterparts in basic
mathematics. The only symbol that might look new to you is "%", which divides one operand by another
and returns the remainder as its result.
+
*
/
%
additive operator (also used for String concatenation)
subtraction operator
multiplication operator
division operator
remainder operator
All of these operators follow the basic order-of-operations common to arithmetic. Additionally, note that
parentheses may be used to change (or emphasize) the order in which these operations occur.
The following program, ArithmeticDemo, tests the arithmetic operators.
public class ArithmeticDemo {
public static void main (String[] args){
int result = 1 + 2; // result is now 3
System.out.println(result);
result = result - 1; // result is now 2
System.out.println(result);
result = result * 2; // result is now 4
System.out.println(result);
result = result / 2; // result is now 2
System.out.println(result);
result = result + 8; // result is now 10
result = result % 7; // result is now 3
System.out.println(result);
}
}
You can also combine the arithmetic operators with the simple assignment operator to create compound
assignments. For example, x+=1; and x=x+1; both increment the value of x by 1.
The + operator can also be used for concatenating (joining) two strings together, as shown in the
following ConcatDemo program:
public class ConcatDemo {
public static void main(String[] args){
String firstString = "This is";
String secondString = " a concatenated string.";
String thirdString = firstString+secondString;
System.out.println(thirdString);
}
}
By the end of this program, the variable thirdString contains "This is a concatenated string.", which gets
printed to standard output.
The Unary Operators
The unary operators require only one operand; they perform various operations such as
incrementing/decrementing a value by one, negating an expression, or inverting the value of a boolean.
+
++
-!
Unary plus operator; indicates positive value (numbers are
positive without this, however)
Unary minus operator; negates an expression
Increment operator; increments a value by 1
Decrement operator; decrements a value by 1
Logical complement operator; inverts the value of a boolean
The following program, UnaryDemo, tests the unary operators:
public class UnaryDemo {
public static void main(String[] args){
int result = +1; // result is now 1
System.out.println(result);
result--; // result is now 0
System.out.println(result);
result++; // result is now 1
System.out.println(result);
result = -result; // result is now -1
System.out.println(result);
boolean success = false;
System.out.println(success); // false
System.out.println(!success); // true
}
}
The increment/decrement operators can be applied before (prefix) or after (postfix) the operand. The
code result++; and ++result; will both end in result being incremented by one. The only difference is that
the prefix version (++result) evaluates to the incremented value, whereas the postfix version (result++)
evaluates to the original value. If you are just performing a simple increment/decrement, it doesn't really
matter which version you choose. But if you use this operator in part of a larger expression, the one that
you choose may make a significant difference.
The following program, PrePostDemo, illustrates the prefix/postfix unary increment operator:
public class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
System.out.println(i);
// "4"
++i;
System.out.println(i);
// "5"
System.out.println(++i); // "6"
System.out.println(i++); // "6"
System.out.println(i);
// "7"
}
}
The Equality and Relational Operators
The equality and relational operators determine if one operand is greater than, less than, equal to, or not
equal to another operand. The majority of these operators will probably look familiar to you as well. Keep
in mind that you must use "==", not "=", when testing if two primitive values are equal.
==
!=
>
>=
<
<=
equal to
not equal to
greater than
greater than or equal to
less than
less than or equal to
The following program, ComparisonDemo, tests the comparison operators:
public class ComparisonDemo {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if(value1 == value2) System.out.println("value1 == value2");
if(value1 != value2) System.out.println("value1 != value2");
if(value1 > value2) System.out.println("value1 > value2");
if(value1 < value2) System.out.println("value1 < value2");
if(value1 <= value2) System.out.println("value1 <= value2");
}
}
Output:
value1 != value2
value1 < value2
value1 <= value2
The Conditional Operators
The && and || operators perform Conditional-AND and Conditional-OR operations on two boolean
expressions. These operators exhibit "short-circuiting" behavior, which means that the second operand is
evaluated only if needed.
&& Conditional-AND
|| Conditional-OR
The following program, ConditionalDemo1, tests these operators:
public class ConditionalDemo1 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}
Summary of Operator Precedence
As a summarize, the precedence of all operators in Java is the following:






Arithmetic operators
Relations operators (==, !=, <, >, <=, >=)
NOT (!)
AND (&&)
OR (||)
Assignment operators (=)
Data Types
The Java programming language is statically-typed, which means that all variables must first be declared
before they can be used. This involves stating the variable's type and name, as you've already seen:
int gear = 1;
Doing so tells your program that a field named "gear" exists, holds numerical data, and has an initial value
of "1". A variable's data type determines the values it may contain, plus the operations that may be
performed on it.
Primitive Data Types
A primitive type is predefined by the language and is named by a reserved keyword. Primitive values do
not share state with other primitive values. In addition to int, the Java programming language supports
seven other primitive data types. Some primitive data types supported by the Java programming language
are:

int: The int data type is a 32-bit signed two's complement integer. It has a minimum value of -
2,147,483,648 and a maximum value of 2,147,483,647 (inclusive). For integral values, this data
type is generally the default choice unless there is a reason (like the above) to choose something
else. This data type will most likely be large enough for the numbers your program will use, but if
you need a wider range of values, use long instead.

double: The double data type is a double-precision 64-bit IEEE 754 floating point. Its range of
values is beyond the scope of this discussion, but is specified in section 4.2.3 of the Java Language
Specification. For decimal values, this data type is generally the default choice. As mentioned
above, this data type should never be used for precise values, such as currency.

boolean: The boolean data type has only two possible values: true and false. Use this data type
for simple flags that track true/false conditions. This data type represents one bit of information,
but its "size" isn't something that's precisely defined.

char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000'
(or 0) and a maximum value of '\uffff' (or 65,535 inclusive).
In addition to the primitive data types listed above, the Java programming language also provides special
support for character strings via the java.lang.String class. Enclosing your character string within double
quotes will automatically create a new String object; for example, String s = "this is a string";. String
objects are immutable, which means that once created, their values cannot be changed. The String class is
not technically a primitive data type, but considering the special support given to it by the language, you'll
probably tend to think of it as such.
When using int and double data types together in common expressions, you are strongly encouraged to
type cast variables as you intend, even when this may be done automatically by the Java Runtime
Environment. Doing so enhances readability while helping ensure that your program operates as desired.
To type cast a variable and/or value, simply encapsulate the data type you wish to use in parentheses, and
include this notation in advance of where the variable/value appears. Consider the following example:
double answer = (double)4 / (double)10;
This will cause the value 0.4 to be placed within answer. Note that had type casting not been used in this
example, the value 0.0 would have been stored in answer instead since Java would have performed
integer division, resulting in down-rounding to the nearest whole number (0).
Arrays
An array is a container object that holds a fixed number of values of a single type. The length of an array
is established when the array is created. After creation, its length is fixed. You've seen an example of
arrays already, in the main method of the "Hello World!" application. This section discusses arrays in
greater detail.
Each item in an array is called an element, and each element is accessed by its numerical index. As
shown in the above illustration, numbering begins with 0. The 9th element, for example, would
therefore be accessed at index 8.
The following program, ArrayDemo, creates an array of integers, puts some values in it, and prints each
value to standard output.
class ArrayDemo {
public static void main(String[] args) {
int[] anArray;
// declares an array of integers
anArray = new int[10];
// allocates memory for 10 integers
anArray[0] = 100; // initialize first element
anArray[1] = 200; // initialize second element
anArray[2] = 300; // etc.
anArray[3] = 400;
anArray[4] = 500;
anArray[5] = 600;
anArray[6]
anArray[7]
anArray[8]
anArray[9]
=
=
=
=
700;
800;
900;
1000;
System.out.println("Element
System.out.println("Element
System.out.println("Element
System.out.println("Element
System.out.println("Element
System.out.println("Element
System.out.println("Element
System.out.println("Element
System.out.println("Element
System.out.println("Element
at
at
at
at
at
at
at
at
at
at
index
index
index
index
index
index
index
index
index
index
0:
1:
2:
3:
4:
5:
6:
7:
8:
9:
"
"
"
"
"
"
"
"
"
"
+
+
+
+
+
+
+
+
+
+
anArray[0]);
anArray[1]);
anArray[2]);
anArray[3]);
anArray[4]);
anArray[5]);
anArray[6]);
anArray[7]);
anArray[8]);
anArray[9]);
}
}
The output from this program is:
Element
Element
Element
Element
Element
Element
Element
Element
Element
Element
at
at
at
at
at
at
at
at
at
at
index
index
index
index
index
index
index
index
index
index
0:
1:
2:
3:
4:
5:
6:
7:
8:
9:
100
200
300
400
500
600
700
800
900
1000
In a real-world programming situation, you'd probably use one of the supported looping constructs to
iterate through each element of the array, rather than write each line individually as shown above.
However, this example clearly illustrates the array syntax.
Declaring a Variable to Refer to an Array
The above program declares anArray with the following line of code:
int[] anArray;
// declares an array of integers
Like declarations for variables of other types, an array declaration has two components: the array's type
and the array's name. An array's type is written as type[], where type is the data type of the contained
elements; the square brackets are special symbols indicating that this variable holds an array. The size of
the array is not part of its type (which is why the brackets are empty). An array's name can be anything
you want, provided that it follows the rules and conventions for naming variables in Java. As with
variables of other types, the declaration does not actually create an array — it simply tells the compiler
that this variable will hold an array of the specified type.
Similarly, you can declare arrays of other types:
double[] anArrayOfDoubles;
boolean[]
anArrayOfBooleans; char[]
anArrayOfChars; String[]
anArrayOfStrings;
You can also place the square brackets after the array's name:
double anArrayOfDoubles[];
Creating, Initializing, and Accessing an Array
One way to create an array is with the new operator. The next statement in the preceding ArrayDemo
program allocates an array with enough memory for ten integer elements and assigns the array to
the anArray variable.
anArray = new int[10];
// create an array of integers
If this statement were missing, the compiler would print an error like the following, and compilation
would fail:
ArrayDemo.java:4: Variable anArray may not have been initialized.
The next few lines assign values to each element of the array:
anArray[0] = 100; // initialize first element
anArray[1] = 200; // initialize second
element anArray[2] = 300; // etc.
Each array element is accessed by its numerical index:
System.out.println("Element 1 at index 0: " +
anArray[0]); System.out.println("Element 2 at index 1: "
+ anArray[1]); System.out.println("Element 3 at index 2:
" + anArray[2]);
Alternatively, you can use the shortcut syntax to create and initialize an array:
int[] anArray = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
Here the length of the array is determined by the number of values provided between { and }.
You can also declare an array of arrays (also known as a multidimensional array) by using two or more
sets of square brackets, such as String[][] names. Each element, therefore, must be accessed by a
Page 12
corresponding number of index values.
In the Java programming language, a multidimensional array is simply an array whose components are
themselves arrays. This is unlike arrays in C or Fortran. A consequence of this is that the rows are
allowed to vary in length, as shown in the following MultiDimArrayDemo program:
class MultiDimArrayDemo {
public static void main(String[] args) {
String[][] names = {{"Mr. ", "Mrs. ", "Ms. "},
{"Smith", "Jones"}};
System.out.println(names[0][0] + names[1][0]); //Mr. Smith
System.out.println(names[0][2] + names[1][1]); //Ms. Jones
}
}
The output from this program is:
Mr. Smith
Ms. Jones
Finally, you can use the built-in length property to determine the size of any array. The code
System.out.println(anArray.length);
will print the array's size to standard output.
Printing Output
Generic Printing
Invoking System.out.print or System.out.println outputs a single value after converting the
value to a String, if necessary. Note that System.out.print outputs a value without giving it its own
line, whereas System.out.println adds a newline after printing the parameter passed. We can see
this in the example below:
public class Root{
public static void main(String[] args) {
int i = 2;
double r = Math.sqrt(i);
System.out.print("The square root of ");
System.out.print(i);
System.out.print(" is ");
System.out.print(r);
System.out.println(".");
i = 5;
r = Math.sqrt(i);
System.out.println("The square root of " + i + " is " + r + ".");
}
}
Here is the output:
Page 13
The square root of 2 is 1.4142135623730951.
The square root of 5 is 2.23606797749979.
In one case, the variables i and r are printed directly in standalone calls to print(); in another case,
these variables are concatenated into a String and then printed with the rest of the String’s contents.
While either approach is acceptable, note that the latter is more succinct.
Formatted Output
Java introduces formatting string that is used by System.out.printf and String.format. The
difference between printf and format is that the former prints to the output, while the later
generates a String that you can print later. We use printf as example.
You can use printf anywhere in your code where you have otherwise been using print or println.
For example,
System.out.printf(.....);
The syntax for printf is as follows:
public PrintStream printf(String format, Object... args)
where format is a string that specifies the formatting to be used and args is a list of the variables to be
printed using that formatting. A simple example would be
System.out.printf("The value of the float variable is %f, while the " +
"value of the integer variable is %d, and " +
"the string is %s",
floatVar, intVar, stringVar);
The first parameter, format, is a format string specifying how the objects in the second parameter,
args, are to be formatted. The format string contains plain text as well as format specifiers, which are
special characters that format the arguments of Object... args. (The notation Object... args is
called varargs, which means that the number of arguments may vary.)
Format specifiers begin with a percent sign (%) and end with a converter. The converter is a character
indicating the type of argument to be formatted. In between the percent sign (%) and the converter you
can have optional flags and specifiers. There are many converters, flags, and specifiers, which are
documented
Here is a basic example:
int i = 461012;
System.out.printf("The value of i is: %d%n", i);
The %d specifies that the single variable is a decimal integer. The %n is a platform-independent newline
character. The output is:
Page 14
The value of i is: 461012
The below table lists some of the converters and flags that are commonly used in conjunction with
printf.
Converter
Flag
Explanation
d
A decimal integer.
f
A float.
n
A new line character appropriate to the
platform running the application. This is
generally interchangeable with \n.
08
Eight characters in width, with leading
zeroes as necessary.
+
Includes sign, whether positive or negative.
,
Includes locale-specific grouping characters.
-
Left-justified.
.3
Three places after decimal point.
10.3
Ten characters in width, right justified, with
three places after decimal point.
The following program shows some of the formatting that you can do with format based on the
converters noted above. The output is shown within double quotes in the embedded comment:
public class TestPrint {
public static void main(String[] args) {
long n = 461012;
System.out.printf("%d%n", n);
System.out.printf("%08d%n", n);
System.out.printf("%+8d%n", n);
System.out.printf("%,8d%n", n);
System.out.printf("%+,8d%n%n", n);
double pi = Math.PI;
System.out.printf("%f%n", pi);
System.out.printf("%.3f%n", pi);
System.out.printf("%10.3f%n", pi);
System.out.printf("%-10.3f%n", pi);
}
}
Page 15
//
//
//
//
//
-->
-->
-->
-->
-->
"461012"
"00461012"
" +461012"
" 461,012"
"+461,012"
//
//
//
//
-->
-->
-->
-->
"3.141593"
"3.142"
"
3.142"
"3.142"
Note that when using %.xf (where x indicates a desired number of digits to display to the right of a
decimal point when printing a double or float value), the least significant digit is rounded up or down
based on any additional digits that are truncated.
Variables
Local and Global (Class-scope) Variables
Generally, variables are local to the context in which they appear, whether within a nested statement, a
method, or even an entire class. In the last of these examples, however, it is usually said that a variable
is global because it can be accessed across multiple methods without being passed as a parameter (see
the discussion on methods, below). When defining a variable directly inside a class rather than within a
method, be sure to include the static keyword with the definition. This in effect “globalizes” the
variable and has additional implications that will be discussed later in the course.
The final Keyword
The static modifier, in combination with the final modifier, is also used to define constants. The
final modifier indicates that the value of this field cannot change.
For example, the following variable declaration defines a constant named PI, whose value is an
approximation of pi (the ratio of the circumference of a circle to its diameter):
static final double PI = 3.141592653589793;
Constants defined in this way cannot be reassigned, and it is a compile-time error if your program tries
to do so. By convention, the names of constant values are spelled in uppercase letters. If the name is
composed of more than one word, the words are separated by an underscore (_).
Program Structure and Control Flow
Using Methods
Methods contain sets of Java statements that can be invoked using a single method “call.” These
structures can both accept input and can create output, though may not necessarily do either. A typical
method call is the following:
double result = calculateAnswer(51.2, numEngines, length, grossTons);
In this case, the method is named calculateAnswer, and a combination of values (51.2) and
variables (numEngines, length, and grossTons) are passed as parameters. The return value
generated by calculateAnswer is placed within result. In addition to custom methods that
Page 16
programmers may create, note that Java includes a wealth of functionality that is built-in. See the
section on “Standard Java Classes” for more information.
Declaring Methods
Here is an example of a typical method declaration:
public static double calculateAnswer(double wingSpan,
int numberOfEngines, double length, double grossTons) {
//do the calculation here
}
The only required elements of a method declaration are the method's return type, name, a pair of
parentheses, (), and a body between braces, {}.
More generally, method declarations have six components, in order:
1. Modifiers—such as public, private, static, and others you will learn about later.
2. The return type—the data type of the value returned by the method, or void if the method
does not return a value.
3. The method name.
4. The parameter list in parenthesis—a comma-delimited list of input parameters, preceded by
their data types, enclosed by parentheses, (). If there are no parameters, you must use empty
parentheses.
5. The method body, enclosed between braces—the method's code, including the declaration of
local variables, goes here.
The Java programming language supports overloading methods, and Java can distinguish between
methods with different method signatures. This means that methods within a class can have the same
name if they have different parameter lists (there are some qualifications to this that will be discussed in
the lesson titled "Interfaces and Inheritance").
Suppose that you have a class that can use calligraphy to draw various types of data (strings, integers,
and so on) and that contains a method for drawing each data type. It is cumbersome to use a new name
for each method—for example, drawString, drawInteger, drawFloat, and so on. In the Java
programming language, you can use the same name for all the drawing methods but pass a different
argument list to each method. Thus, the data drawing class might declare four methods named draw,
each of which has a different parameter list.
public class DataArtist {
...
public static void draw(String s) {
...
}
public static void draw(int i) {
...
}
Page 17
public static void draw(double f) {
...
}
public static void draw(int i, double f) {
...
}
}
Overloaded methods are differentiated by the number and the type of the arguments passed into the
method. In the code sample, draw(String s) and draw(int i) are distinct and unique methods
because they require different argument types. You cannot declare more than one method with the
same name and the same number and type of arguments, because the compiler cannot tell them apart.
The compiler does not consider return type when differentiating methods, so you cannot declare two
methods with the same signature even if they have a different return type.
Methods with Exceptions
Technically, an exception is an object representing a runtime error. But this does not say much.
The main motivation when programming languages introduced exceptions is to allow a method
to signal to its invoker that an error has occurred instead of having to return a special return
value to signal the error. Consider the Integer.parseInt method that takes a string and
returns an integer. If the input string is not a valid number, which value to return to signal the
error? For such cases, throwing an exception is a more uniform approach.
Certain methods (e.g., Scanner(File source)) require that the invoker must handle exceptions
(i.e. checked exceptions). There are two approaches to handle exceptions.
o Could handle exception with a throw clause in the invoking method’s header, with
syntax:
o public static <type> <name>(…) throws <type>
 Essentially an acknowledgement that you realize the method could throw
an exception; passes the duty of handling the checked exception to the
method that invoked it.
o Could handle exception with a try/catch statement
o The important thing to remember with a try/catch statement is that code is
executed normally until an exception is triggered (if one is triggered at all). At
this point (if it occurs), code within the try statement ceases execution and the
catch statement for the appropriate exception begins execution.
Page 18
if (...) {…} / else if (…) {…} / else{ … } Statement
The if-then statement is the most basic of all the control flow statements. It tells your program to
execute a certain section of code only if a particular test evaluates to true. For example, consider a
method that would adjust the speed of a (virtual) bicycle given a Boolean variable indicating whether
the bike is in motion:
void applyBrakes(){
if (isMoving){ // the "if" clause: bicycle must be moving
currentSpeed--; // the "then" clause: decrease current speed
}
}
If this test evaluates to false (meaning that the bicycle is not in motion), control jumps to the end of the
if-then statement.
In addition, the opening and closing braces are optional, provided that the "then" clause contains only
one statement:
void applyBrakes(){
if (isMoving) currentSpeed--; // same as above, but w/o braces
}
Deciding when to omit the braces is a matter of personal taste. Omitting them can make the code more
brittle. If a second statement is later added to the "then" clause, a common mistake would be forgetting
to add the newly required braces. The compiler cannot catch this sort of error; you'll just get the wrong
results.
The if-then-else statement provides a secondary path of execution when an "if" clause evaluates to
false. You could use an if-then-else statement in the applyBrakes method to take some action if the
brakes are applied when the bicycle is not in motion. In this case, the action is to simply print an error
message stating that the bicycle has already stopped.
void applyBrakes(){
if (isMoving) {
currentSpeed--;
} else {
System.err.println("The bicycle has already stopped!");
}
}
The following program, IfElseDemo, assigns a grade based on the value of a test score: an A for a score
of 90% or above, a B for a score of 80% or above, and so on.
public class IfElseDemo {
public static void main(String[] args) {
Page 19
int testscore = 76;
char grade;
if (testscore >= 90) {
grade = 'A';
} else if (testscore >= 80)
grade = 'B';
} else if (testscore >= 70)
grade = 'C';
} else if (testscore >= 60)
grade = 'D';
} else {
grade = 'F';
}
System.out.println("Grade =
{
{
{
" + grade);
}
}
The output from the program is:
Grade = C
You may have noticed that the value of testscore can satisfy more than one expression in the compound
statement: 76 >= 70 and 76 >= 60. However, once a condition is satisfied, the appropriate statements
are executed (grade = 'C';) and the remaining conditions are not evaluated. By the same token, once
you have determined a certain condition to be true (e.g., through the use of an if statement), the
typically remains true in subsequent lines. This ability to make an assumption based on prior analysis is
formally known as assertion.
switch (…) {…} Statement
Unlike if-then and if-then-else statements, the switch statement can have a number of possible
execution paths. A switch works with the char and int primitive data types; it also works with the
String class.
The following code example, SwitchDemo, declares an int named month whose value represents a
month. The code displays the name of the month, based on the value of month, using the switch
statement.
public class SwitchDemo {
public static void main(String[] args) {
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
case 2: monthString = "February";
Page 20
break;
break;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
default:
monthString
monthString
monthString
monthString
monthString
monthString
monthString
monthString
monthString
monthString
monthString
=
=
=
=
=
=
=
=
=
=
=
"March";
"April";
"May";
"June";
"July";
"August";
"September";
"October";
"November";
"December";
"Invalid month";
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
break;
}
System.out.println(monthString);
}
}
In this case, August is printed to standard output.
The body of a switch statement is known as a switch block. A statement in the switch block can be
labeled with one or more case or default labels. The switch statement evaluates its expression,
then executes all statements that follow the matching case label.
You could also display the name of the month with if-then-else statements:
int month = 8;
if (month == 1) {
System.out.println("January");
} else if (month == 2) {
System.out.println("February");
}
. . . // and so on
Deciding whether to use if-then-else statements or a switch statement is based on readability and
the expression that the statement is testing. An if-then-else statement can test expressions based
on ranges of values or conditions, whereas a switch statement tests expressions based only on a single
numeric or String value.
Another point of interest is the break statement. Each break statement terminates the enclosing
switch statement. Control flow continues with the first statement following the switch block. The
break statements are necessary because without them, statements in switch blocks fall through: All
statements after the matching case label are executed in sequence, regardless of the expression of
subsequent case labels, until a break statement is encountered. Furthermore, note that a default
section handles all values that are not explicitly handled by one of the case sections.
for (…; …; …) {…} Statement
The for statement provides a compact way to iterate over a range of values. Programmers often refer to
it as the "for loop" because of the way in which it repeatedly loops until a particular condition is
satisfied. The general form of the for statement can be expressed as follows:
Page 21
for (initialization; termination test; increment) {
statement(s)
}
When using this version of the for statement, keep in mind that:



The initialization expression initializes the loop; it's executed once, as the loop begins.
When the termination test expression evaluates to false, the loop terminates.
The increment expression is invoked after each iteration through the loop; it is perfectly
acceptable for this expression to increment or decrement a value.
The following program, ForDemo, uses the general form of the for statement to print the numbers 1
through 10 to standard output:
public class ForDemo {
public static void main(String[] args){
for(int i=1; i<11; i++){
System.out.println("Count is: " + i);
}
}
}
The output of this program is:
Count
Count
Count
Count
Count
Count
Count
Count
Count
Count
is:
is:
is:
is:
is:
is:
is:
is:
is:
is:
1
2
3
4
5
6
7
8
9
10
Notice how the code declares a variable within the initialization expression. The scope of this variable
extends from its declaration to the end of the block governed by the for statement, so it can be used in
the termination and increment expressions as well. If the variable that controls a for statement is not
needed outside of the loop, it's best to declare the variable in the initialization expression. The names i,
j, and k are often used to control for loops; declaring them within the initialization expression limits their
life span and reduces errors.
As a final note about for and while loops, observe the availability of the break statement. You can use
break to terminate a for or while loop, as shown in the following BreakDemo program:
public class BreakDemo {
public static void main(String[] args) {
Page 22
int[] arrayOfInts = { 32, 87, 3, 589, 12, 1076,
2000, 8, 622, 127 };
int searchfor = 12;
int i;
boolean foundIt = false;
for (i = 0; i < arrayOfInts.length; i++) {
if (arrayOfInts[i] == searchfor) {
foundIt = true;
break;
}
}
if (foundIt) {
System.out.println("Found " + searchfor
+ " at index " + i);
} else {
System.out.println(searchfor
+ " not in the array");
}
}
}
This program searches for the number 12 in an array. The break statement, shown in boldface,
terminates the for loop when that value is found. Control flow then transfers to the print statement at
the end of the program. This program's output is:
Found 12 at index 4
while (…) {…} Statement
The while statement continually executes a block of statements while a particular condition is true. Its
syntax can be expressed as:
while (expression) {
statement(s)
}
The while statement evaluates expression, which must return a boolean value. If the expression
evaluates to true, the while statement executes the statement(s) in the while block. The while
statement continues testing the expression and executing its block until the expression evaluates to
false. Using the while statement to print the values from 1 through 10 can be accomplished as in the
following WhileDemo program:
public class WhileDemo {
public static void main(String[] args){
Page 23
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}
}
You can implement an infinite loop using the while statement as follows:
while (true){
// your code goes here
}
do { … }while (…) Statement
The Java programming language also provides a do-while statement, which can be expressed as
follows:
do {
statement(s)
} while (expression);
The difference between do-while and while is that do-while evaluates its expression at the bottom
of the loop instead of the top. Therefore, the statements within the do block are always executed at
least once, as shown in the following DoWhileDemo program:
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count <= 11);
}
}
Loop Types
Loops created using either for or while can exist in a number of forms; the most common of these are
summarized below:



Continuous Loops – iterate ad infinitum, and commonly an unintended programming error
Early Exit Loops – through the use of the break keyword, some loops can be “stopped early”
Sentinel Loops – these are the most traditional loops which continue iterating until a particular
condition (i.e., the termination test) tested on each iteration is no longer true
Page 24
Additionally, be on the lookout for so-called “fencepost” or “off-by-one” issues when using loops. These
are common sources of errors where mistaken interpretation of exactly how many times a loop should
iterate causes a loop to execute one time more or less than intended. Be sure to double-check your test
condition to be sure that it causes the proper number of iterations to occur.
Fencepost Loops
Fencepost is a general term in computer science when you alternate between two operations
but begin and end with the same operation.
In class we made the Fence Post Analogy: If consecutive fence posts are connected by wire,
then you will have one more fence post than connecting wire when you finish building your
fence.
It is important to recognize fence post situations in your programs because in those situations
the extra fence post will often have to be handled before or after the loop structure used.
place a post
loop(length of fence – 1 number of times)
place wire
place post
A slightly less efficient method for handling a fence post problem is to check within the loop if
you are on the first or last fence post and to handle that case differently
Program Analysis
Program analysis is a method of analyzing whether certain requirements (definitive statements
about a program at given points in execution) are satisfied.
The foundation of program analysis is assertions, where an assertion is a statement made about
the state of a program at a given point that could always be true, always be false, or true/false
depending on certain initial conditions
In particular, assertions can be made around control statements. For example if a while loop
has as its test condition x < 0, then you know that at the point the while loop is entered x is
negative and at the moment the while loop is exited, x is nonnegative, if there is no break inside
the loop.
Program requirements often use Iff, which is a stronger statement than if. Iff A happens, then B
happens is equivalent to saying if A happens, then B happens and if B happens, then A happens.
Page 25
One example of an application of using iff statements to describe execution of a program is iff
the user doesn’t input an integer, then an error message is printed. If you know that one of the
two conditions is true (either the user didn’t input an integer or an error message was printed),
then you know the other condition must have been true as well.
Standard Java Classes
This section offers a comprehensive review of relevant methods available within Java framework classes
that have been covered in this course. This information is in large part based on documentation
available through the Java Platform API (“Javadocs”) on the Java website. Additional information about
these classes and methods may be obtained by reviewing the Javadocs at the following URL:
http://java.sun.com/javase/6/docs/api/
You may also consult your textbook for more extensive examples demonstrating how these classes and
methods can be used.
String
The String class represents character strings. All string literals in Java programs, such as "abc", are
implemented as instances of this class.
Strings are constant; their values cannot be changed after they are created. String buffers support
mutable strings. Because String objects are immutable they can be shared. For example:
String str = "abc";
is equivalent to:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
Here are some more examples of how strings can be used:
System.out.println("abc");
String cde = "cde";
System.out.println("abc" + cde);
String c = "abc".substring(2,3);
String d = cde.substring(1, 2);
String Class Methods
public String()
Page 26
Initializes a newly created String object so that it represents an empty character sequence. Note
that use of this constructor is unnecessary since Strings are immutable.
public String(String original)
Initializes a newly created String object so that it represents the same sequence of characters
as the argument; in other words, the newly created string is a copy of the argument string.
Unless an explicit copy of original is needed, use of this constructor is unnecessary since
Strings are immutable.
Parameters:
original - a String.
public char charAt(int index)
Returns the char value at the specified index. An index ranges from 0 to length() - 1. The
first char value of the sequence is at index 0, the next at index 1, and so on, as for array
indexing.
If the char value specified by the index is a surrogate, the surrogate value is returned.
Parameters:
index - the index of the char value.
Returns:
the char value at the specified index of this string. The first char value is at index 0.
public int compareTo(String anotherString)
Compares two strings lexicographically. The comparison is based on the Unicode value of each
character in the strings. The character sequence represented by this String object is compared
lexicographically to the character sequence represented by the argument string. The result is a
negative integer if this String object lexicographically precedes the argument string. The result
is a positive integer if this String object lexicographically follows the argument string. The
result is zero if the strings are equal; compareTo returns 0 exactly when the equals(Object)
method would return true.
Parameters:
anotherString - the String to be compared.
Returns:
the value 0 if the argument string is equal to this string; a value less than 0 if this string is
lexicographically less than the string argument; and a value greater than 0 if this string is
lexicographically greater than the string argument.
public boolean equals(Object anObject)
Compares this string to the specified object. The result is true if and only if the argument is not
null and is a String object that represents the same sequence of characters as this object.
Parameters:
anObject - the object to compare this String against.
Returns:
true if the String are equal; false otherwise.
public boolean equalsIgnoreCase(String anotherString)
Compares this String to another String, ignoring case considerations. Two strings are
considered equal ignoring case if they are of the same length, and corresponding characters in
the two strings are equal ignoring case.
Page 27
Parameters:
anotherString - the String to compare this String against.
Returns:
true if the argument is not null and the Strings are equal, ignoring case; false otherwise.
public int indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character.
Parameters:
ch - a character (Unicode code point).
Returns:
the index of the first occurrence of the character in the character sequence represented by this
object, or -1 if the character does not occur.
public int indexOf(int ch,
int fromIndex)
Returns the index within this string of the first occurrence of the specified character, starting the
search at the specified index.
Parameters:
ch - a character (Unicode code point).
fromIndex - the index to start the search from.
Returns:
the index of the first occurrence of the character in the character sequence represented by this
object that is greater than or equal to fromIndex, or -1 if the character does not occur.
public int indexOf(String str)
Returns the index within this string of the first occurrence of the specified substring.
Parameters:
str - any string.
Returns:
if the string argument occurs as a substring within this object, then the index of the first
character of the first such substring is returned; if it does not occur as a substring, -1 is
returned.
public int indexOf(String str, int fromIndex)
Returns the index within this string of the first occurrence of the specified substring, starting at
the specified index. If no such value of k exists, then -1 is returned.
Parameters:
str - the substring for which to search.
fromIndex - the index from which to start the search.
Returns:
the index within this string of the first occurrence of the specified substring, starting at the
specified index.
public int length()
Returns the length of this string. The length is equal to the number of 16-bit Unicode characters
in the string.
Returns:
the length of the sequence of characters represented by this object.
Page 28
public String substring(int beginIndex,
int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified
beginIndex and extends to the character at index endIndex - 1. Thus the length of the
substring is endIndex-beginIndex.
Examples:
"hamburger".substring(4, 8) returns "urge"
"smiles".substring(1, 5) returns "mile"
Parameters:
beginIndex - the beginning index, inclusive.
endIndex - the ending index, exclusive.
Returns:
the specified substring.
public String toLowerCase()
Converts all of the characters in this String to lower case using the rules of the default locale.
Returns:
the String, converted to lowercase.
public String toUpperCase()
Converts all of the characters in this String to upper case using the rules of the default locale.
Returns:
the String, converted to uppercase.
Regular expressions
A regular expression is a string that defines a search pattern for strings. Regular expressions are a very
powerful tool that we use to search, edit, and manipulate text. See lecture 13 for definitions and
examples of regular expressions. A good tutorial on regular expressions is
http://www.vogella.com/tutorials/JavaRegularExpressions/article.html
Scanner
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
The resulting tokens may then be converted into values of different types using the various next
methods.
For example, this code allows a user to read a number from System.in:
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
The scanner can also use delimiters other than whitespace. This example reads several items in from a
string:
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
Page 29
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();
prints the following output:
1
2
red
blue
The next() and hasNext() methods and their primitive-type companion methods (such as nextInt() and
hasNextInt()) first skip any input that matches the delimiter pattern, and then attempt to return the next
token. Both hasNext and next methods may block waiting for further input. Whether a hasNext method
blocks has no connection to whether or not its associated next method will block.
In this example, \\s*fish\\s* is a regular expression, where \s represents a white space character, and *
means it matches from 0 to many white space characters. We write \\s because Java takes \ as a special
character.
The same output can be generated with the code below, which uses a regular expression to parse all
four tokens at once:
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input);
s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
MatchResult result = s.match();
for (int i=1; i<=result.groupCount(); i++)
System.out.println(result.group(i);
s.close();
Scanner Class Methods
public Scanner(InputStream source)
Constructs a new Scanner that produces values scanned from the specified input stream.
Parameters:
source - An input stream to be scanned
public Scanner(String source)
Constructs a new Scanner that produces values scanned from the specified string.
Parameters:
source - A string to scan
public boolean hasNext()
Returns true if this scanner has another token in its input. This method may block while waiting
for input to scan. The scanner does not advance past any input.
Page 30
Returns:
true if and only if this scanner has another token
public boolean hasNextDouble()
Returns true if the next token in this scanner's input can be interpreted as a double value using
the nextDouble() method. The scanner does not advance past any input.
Returns:
true if and only if this scanner's next token is a valid double value
public boolean hasNextInt()
Returns true if the next token in this scanner's input can be interpreted as an int value in the
default radix using the nextInt() method. The scanner does not advance past any input.
Returns:
true if and only if this scanner's next token is a valid int value
public boolean hasNextLine()
Returns true if there is another line in the input of this scanner. This method may block while
waiting for input. The scanner does not advance past any input.
Returns:
true if and only if this scanner has another line of input
public String next()
Finds and returns the next complete token from this scanner. A complete token is preceded and
followed by input that matches the delimiter pattern. This method may block while waiting for
input to scan, even if a previous invocation of hasNext() returned true.
Returns:
the next token
public double nextDouble()
Scans the next token of the input as a double. This method will throw
InputMismatchException if the next token cannot be translated into a valid double value. If
the translation is successful, the scanner advances past the input that matched.
Returns:
the double scanned from the input
public int nextInt()
Scans the next token of the input as an int.
An invocation of this method of the form nextInt() behaves in exactly the same way as the
invocation nextInt(radix), where radix is the default radix of this scanner.
Returns:
the int scanned from the input
public String nextLine()
Advances this scanner past the current line and returns the input that was skipped. This method
returns the rest of the current line, excluding any line separator at the end. The position is set to
the beginning of the next line.
Since this method continues to search through the input looking for a line separator, it may
buffer all of the input searching for the line to skip if no line separators are present.
Returns:
Page 31
the line that was skipped
Math
The class Math contains methods for performing basic numeric operations such as the elementary
exponential, logarithm, square root, and trigonometric functions.
Math Class Methods
public static int abs(int a)
public static double abs(double a)
public static float abs(float a)
Returns the absolute value of the parameter specified. If the argument is not negative, the
argument is returned. If the argument is negative, the negation of the argument is returned.
Special cases:



If the argument is positive zero or negative zero, the result is positive zero.
If the argument is infinite, the result is positive infinity.
If the argument is NaN, the result is NaN.
Parameters:
a - the argument whose absolute value is to be determined
Returns:
the absolute value of the argument.
public static int max(int a, int b)
public static double max(double a, double b)
public static float max(float a, float b)
Returns the greater of two double values. That is, the result is the argument closer to positive
infinity. If the arguments have the same value, the result is that same value. If either value is
NaN, then the result is NaN. Unlike the the numerical comparison operators, this method
considers negative zero to be strictly smaller than positive zero. If one argument is positive zero
and the other negative zero, the result is positive zero.
Parameters:
a - an argument.
b - another argument.
Returns:
the larger of a and b.
public static int min(int a, int b)
public static double min(double a, double b)
public static float min(float a, float b)
Returns the smaller of two double values. That is, the result is the value closer to negative
infinity. If the arguments have the same value, the result is that same value. If either value is
Page 32
NaN, then the result is NaN. Unlike the the numerical comparison operators, this method
considers negative zero to be strictly smaller than positive zero. If one argument is positive zero
and the other is negative zero, the result is negative zero.
Parameters:
a - an argument.
b - another argument.
Returns:
the smaller of a and b.
public static double pow(double a, double b)
Returns the value of the first argument raised to the power of the second argument.
Parameters:
a - the base.
b - the exponent.
Returns:
the value ab.
public static long round(double a)
public static int round(float a)
Returns the closest int to the argument. The result is rounded to an integer by adding 1/2,
taking the floor of the result, and casting the result to type int.
Parameters:
a - a floating-point value to be rounded to an integer.
Returns:
the value of the argument rounded to the nearest int value.
public static double sqrt(double a)
Returns the correctly rounded positive square root of a double value. Special cases:
 If the argument is NaN or less than zero, then the result is NaN.
 If the argument is positive infinity, then the result is positive infinity.
 If the argument is positive zero or negative zero, then the result is the same as the
argument.
Otherwise, the result is the double value closest to the true mathematical square root of the
argument value.
Parameters:
a - a value.
Returns:
the positive square root of a. If the argument is NaN or less than zero, the result is NaN.
Graphics using StdDraw
We used methods defined in the StdDraw class for graphics. See
http://zoo.cs.yale.edu/classes/cs112/cs112-2014-spring/doc_StdDraw/ for list of methods.
Color
The Color class is used encapsulate colors in the default sRGB color space.
Page 33
Color Predefined Variables (Colors)













Color.WHITE
Color.LIGHT_GRAY
Color.GRAY
Color.DARK_GRAY
Color.BLACK
Color.RED
Color.PINK
Color.ORANGE
Color.YELLOW
Color.GREEN
Color.MAGENTA
Color.CYAN
Color.BLUE
Color Class Methods
public Color(int r,
int g,
int b)
Creates an opaque sRGB color with the specified red, green, and blue values in the range (0 255). The actual color used in rendering depends on finding the best match given the color
space available for a given output device. Alpha is defaulted to 255.
Parameters:
r - the red component
g - the green component
b - the blue component
Page 34