260 likes | 378 Views
Yes. Is condition true?. No. MAKING DECISIONS. Booleans Basic Choices (Should I stay or should I go?) Choosing From Many Alternatives switch statements M&M’s example break statements Factory Pattern. Booleans.
E N D
Yes Is condition true? No MAKING DECISIONS • Booleans • Basic Choices (Should I stay or should I go?) • Choosing From Many Alternatives • switch statements • M&M’s example • break statements • Factory Pattern
Booleans • Booleans, named in honor of British logician George Boole (1815-1864), are another base type defined by Java. They can have one of two values: true or false • booleans are declared and assigned just like numbers • default value is false boolean foo = true; boolean bar = false; foo = bar; // foo is now false...
We can use a boolean in Cow class • Cow can only fly when moon is full public class Cow extends FarmAnimal implements CowConstants { private boolean _canWeJump; public Cow(Moon myMoon) { // _moon is protected instance variable of // FarmAnimal, our superclass super(myMoon); // other setup code elided } /* when user clicks on cow, check if isFull() method of Moon returns true */ public void react() { _canWeJump = _moon.isFull(); // use this boolean to make decision later } } • Terminology tidbit • a method that returns a boolean is called a predicate • it usually begins with ‘is’ as in ‘isFull()’
Relational Operators Relational Operators • Numerical expressions (variables, constants, literal constants, etc…) can be compared using these operators. They return boolean value, either true or false • Note that == is used to test for equality; don’t confuse it with = of assignment! boolean isEven = ((x % 2) == 0); Operator != > < <= >= == Meaning not equal to greater than less than less than or equal to greater than or equal to equal to
Comparing References • We can check to see if two references are referring to the same instance of a class using == or if they are referring to different instances using != public class TestClass { public void compareReferences() { Cow cow1 = new Cow(); Cow cow2 = new Cow(); boolean isEqual = (cow1 == cow2); // false cow2 = cow1; isEqual = (cow1 == cow2); // true } } • We can also check to see if a reference is not referring to anything boolean isNull = (cow1 == null);
Logical Operators: And, Or, and Not • And (&&) takes two boolean expressions and returns true only if both expressions are true • Or (||) takes two boolean expressions and returns true if at least one expression is true • Not (!) takes one boolean expression and returns its negation • Examples: boolean bool1 = (3 == 2) && (2 < 3); // false boolean bool2 = (!bool1) || (5.6 >= 8); // true boolean bool3 = !(bool1 && bool2); // true • & and | have their own meanings in Java • bitwise AND and OR operator for integers • if you’re curious about what these do, take CS31 • has different meaning for booleans which we will discuss in a few slides
if Statements • But how do booleans help us make decisions? • Answer: if statements! • Syntax: if (<boolean expression>) { // code to be executed if expression is true } • Boolean expression is evaluated • if true, Java executes code in body of if statement and then goes on with rest of method • if false, skips over body of if statement and continues with method
Checking booleans • Note that you should never check if a boolean variable is true (or false) in the following way: if (myBoolean == true) System.out.println(“true!”); • What if you mistyped and instead wrote: if (myBoolean = true) System.out.println(“true!”); • The value true would be assigned to myBoolean and the conditional statement would always evaluate to true • Assignments always evaluate to the result of the right side of the assignment • This is a HUGE source of bugs!! Remember to always use == when checking for equality! • Instead, you should always say: if (myBoolean) System.out.println(“true!”);
Previous Statements Is condition true? Yes No Execute if clause Execute rest of method if: The Flow Chart
if-else • What if we want to do something different when expression is false? • We can add else clause to if! • Remember Moon’s isFull() predicate? if (_moon.isFull()) { // code to calculate weight and maybe fly } else { // code for cow to remain on ground } • We don’t have to use braces if body of if or else is one statement: if (_moon.isFull()) this.jumpOverMoon(); else this.mooPiteously();
Previous Statements Is condition true? Yes No Execute if clause Execute else clause Execute rest of method if-else: The Flow Chart
Complex if statements • We may want more than one condition in our if-statements • We can add another if statement in else’s body. if (<boolean expression>) { // body } else if (<boolean expression>) { // body } • We can also nest our if statements by putting one inside another. • Our cow is now ready to fly!
Ready For Takeoff! public class Cow extends FarmAnimal implements CowConstants { private double _weight; // in pounds // some other boring stuff public Cow(Moon moon, /* some stuff FarmAnimal needs */ ) { super(moon); // some tedious setup code _weight = COW_START_WEIGHT; } public void react() { if ((_moon.isFull()) && (_weight < MAX_FLYING_WEIGHT)) this.jumpOverMoon(); else this.mooPiteously(); } public void mooPiteously() { // play a cow sound } }
Short-Circuiting • What is the value of n after the following code has executed? int n = 1; if (false && (n++ == 2)) { System.out.println(“Went into the if clause”); } System.out.println(n); • Answer: n is 1 • since the left side of the condition evaluated to false the right side is not evaluated • The same holds for || and true • if the left side of the conditional evaluates to true, the right side is not evaluated • This is called short-circuiting • part of the conditional is skipped • Java takes a shorter route to evaluate conditional • Can avoid short-circuiting by using & and | operators (both sides always evaluated) • What if, in our above example, we always wanted to do the right side, which increments n? if (false & (n++ == 2)) • If we used this instead, n would be 2 but we would still not go in to the if clause.
“Side-effect”ing • Note that the previous example updated a variable inside a conditional if (false && (n++ == 2)) • We only provide this as an example of C-style hacking which you might see when you look through someone else’s code. • In this course, you should never write something like this • Increment your variables outside of conditionals • As you’ve seen, updating them inside conditionals makes the code confusing and hard to read.
If... If... If... • What if we want lots of conditional statements? • Could keep writing if-statements: if (condition1) { /* body1 */ } else if (condition2) { /* body2 */ } else if (condition3) { /* body3 */ } else if (condition4) { /* body4 */ } ... else { /* bodyn */ } • In English, this means • if condition1, execute body1 • otherwise, if condition2, execute body2 • otherwise, if condition3, execute body3 • otherwise, if condition4, execute body4 . . . • otherwise, execute bodyn • If all we want to do is something different for each value of a simple variable (e.g, age) can’t we do something simpler? • Yes! We can use a switch statement!
25 5 10 switch Statement • switch is used to choose among more than two mutually exclusive choices, based on values of a variable. Very special form of general if-else-if • switch is like vending machine. When coins are deposited into machine they fall into ramp with holes for each different type of coin. Smallest slot is for dimes; largest, for quarters
switch Statement: Selector • switch can pick out one action from among many using a simple key called a selector • Selectors cannot be references, fractional numbers, or other complex data types. Of types we have encountered so far, can be ints, shorts, bytes, or longs • Value of selector determines action to be taken. Each possible value for selector should result in one action or set of actions (one block of code executed) • Sometimes selector does not cover all cases. Use default value to specify what action(s) should be performed when selector does not fit any other values listed
Previous Statements Determine the value of the selector selector = value 1 selector = value n default Execute statement 1 Execute statement n Execute statement n+1 Execute the rest of the program switch: The Flow Chart • Much like specialized if-else-if that tests mutually exclusive values of single variable … …
switch Example: M&M’s • Let’s make a factory object that produces M&M’s using a switch statement! • Factory is a design pattern we’ll discuss later • Want to make bunch of M&M’s • M&M’s come in different colors • M&M colors are chosen by some weighted distribution • more reds, oranges, and browns • fewer greens, yellows, and blues • Factory specification: Get a random value. Based on random value, create an M&M of one of the six possible colors. The M&M created should be based on a distribution. Return the M&M.
Designing M&M Factory • Can use switch statement to weight probability of getting each color by having multiple values of the selector assigned to a single statement body that generates a more popular outcome • can “group” cases together - only write one statement body • We’ll use the static method Math.random()for some randomness: • Returns a random double between 0.0 and 1.0; simply multiply by desired range • static means we can call this method without actually instantiating Math • Remember to cast the resulting number so you can get an int again (if you want one). _randomInt = (int)(Math.random()*15) • Let’s see some code...
M&M’s “First Solution” Version • If 2 is number that is randomly generated, what color is our M&M? • note: MnM is created with a java.awt.Coloras a parameter public class MnMFactory { // constructor elided public MnM getMnM(){ // get a random number to serve as the selector int rand = (int)(Math.random()*10); MnM mnm = null; // not yet created switch(rand) { case 0: case 1: mnm = new MnM(java.awt.Color.orange); // red is the most popular color, hence a red // MnM will be created in three cases case 2: case 3: case 4: mnm = new MnM(java.awt.Color.red); // code for 6 and 7 elided // they are blue and green respectively default: // a brown color mnm = new MnM(new java.awt.Color(150,100,0)); } return mnm; } }
break • But there’s a problem with that code . . . • If nothing alters flow of control, switch statements “fall through” to next case • i.e., all case statements after one which matches selector are executed! • In our example, nothing alters flow of control • so, if rand is 0 or 1, code under all cases will be executed • likewise, if rand is 2, 3 or 4, code under cases 2, 3, 4, 5, 6, 7 as well as the default case will be executed • Remember, we only want one M&M per match! • Must have way to stop case from falling through: break out of switch statement
M&M Factory Method • Now, what happens when 3 is selected? How about 4? 5? // ... code elided to save space int rand = (int)(Math.random()*10); MnM mnm = null; // not created yet switch(rand) { case 0: case 1: mnm = new MnM(java.awt.Color.orange); break; case 2: case 3: case 4: mnm = new MnM(java.awt.Color.red); break; case 5: mnm = new MnM(java.awt.Color.yellow); break; // cases 6 and 7 elided. case 6 creates a blue // MnM and case 7 creates a green MnM default: // 3/11% chance of creating brown mnm = new MnM(new java.awt.Color (150, 100, 0)); // a brown color break; } return mnm; // ... code elided to save space
Previous Statements Determine the value of the selector selector = value 1 selector = value n default Execute statement 1 break; Execute statement 1 break; Execute statement 1 break; Execute the rest of the program Amendment to Previous Diagrams … …