• No results found

Wrapper Classes, Selection Statements and Iteration Blocks Iteration Blocks

In document Core Java Handout v1.0 (Page 116-145)

Learning Objectives

After completing this session, you will be able to:

‰ Implement wrapper classes

The Wrapper Classes Some Facts:

‰ Primitive data types are not objects: Cannot access methods of the Object class

‰ Only actual objects can access methods of the Object class

‰ Need of wrapper classes: Need an object representation for the primitive type variables to apply methods that are in-built in Java

Definition: Object representations of simple variables that are not object variables

‰ The designers decided instead that for each primitive type there would be a corresponding wrapper class.

‰ An instance of a wrapper contains, or wraps, a primitive value of the corresponding type.

‰ The wrappers are normal classes in the java.lang package that extend the Object superclass like all Java classes.

‰ Other than for the primitive type int, the wrappers come with the same name as the corresponding primitive type except that the first letter is capitalized:

o Integer is a wrapper class of the primitive int o Character is a wrapper class of the primitive char o Double is a wrapper class of the primitive double

Wrapping a value:

Give the primitive to the wrapper constructor as shown in the following example:

Example:

int i = 123;

Integer iWrap = new Integer(i);

UnWrapping a value:

Each wrapper class has its own method for unwrapping a value.

For example, Boolean class has the method booleanValue(), Character class has the method charValue() , and so on Example: int unWrapped = iWrap.intValue();

Why Should You Use Wrapper Classes?

‰ Wrappers allow for situations where numerical values are needed but objects instead of primitives are required.

‰ For example, a very useful tool is as the Vector class, which is a list that that can grow or shrink, unlike an array.

‰ The elements of a Vector instance are object references.

‰ If one wants to use a Vector to hold a list of numbers, then the numbers must be wrapped in instances of their corresponding type.

‰ The wrapper classes also provide various tools such as constants (the smallest and largest possible int value, for example) and static methods.

‰ You will often use wrapper methods to convert a number type value to a string or a string to a number type.

Converting Primitive Types to Objects (Wrapper) and the Reverse

The wrapper constructors create class objects from the primitive types. For example, for a double floating point number "d" :

double d = 5.0;

Double aDouble = new Double(d);

Here a Double wrapper object is created by passing the double value in the Double constructor argument.

In turn, each wrapper provides a method to return the primitive value like:

double r = aDouble.doubleValue();

Each wrapper has a similar method to access the primitive value:

‰ intValue() for Integer,

‰ booleanValue() for Boolean, and so forth

The following statement creates an instance of the Integer class with the integer value 7801.

Integer dataCount = new Integer(7801);

The following statement converts an Integer object to its primitive data type int. The result is an int with value 7801.

int newCount = dataCount.intValue();

A common translation you need in programs is converting a String to a numeric type, such as an int (Object->primitive).

String pennsylvania = "65000";

int penn = Integer.parseInt(pennsylvania);

Wrappers are Immutable

The two main applications of wrapper classes are:

‰ Wrapping a primitive so it can pretend to be an object.

‰ Applying the static utility methods (for example, Integer.parseInt()).

Once you create a wrapper object, there is no way to change the value of that object.

There is no setter method for a wrapper object.

Example: If you create a wrapper object like:

Integer iWrap = new Integer(25); then, The value of iWrap will always be 25

You can, of course, refer iWrap to a different wrapper object, but then you will have two objects.

Try It Out

Problem Statement:

Write a program that illustrates the use of Boolean Wrapper class.

Code:

class BooleanWrapper {

public static void main(String args[]) { boolean booleanVar = 1 > 2;

Boolean booleanObj = new Boolean("True");

/*

* primitive to object; can also use valueOf method

*/

Boolean booleanObj2 = new Boolean(booleanVar);

System.out.println("booleanVar = " + booleanVar);

System.out.println("booleanObj = " + booleanObj);

System.out.println("booleanObj2 = " + booleanObj2);

System.out.println("compare 2 wrapper objects: "

+ booleanObj.equals(booleanObj2));

/* object to primitive */

booleanVar = booleanObj.booleanValue();

System.out.println("booleanVar = " + booleanVar);

} }

Refer File Name: BooleanWrapper.java to obtain soft copy of the program code

How It Works:

‰ When you run the program, it produces the following results:

booleanVar = false booleanObj = true booleanObj2 = false

compare 2 wrapper objects: false booleanVar = true

Tips and Tricks:

What happens in Integer.parseInt() if the thing you pass is not a number? And does it recognize spelled-out numbers like “three”?

Solution:

‰ Integer.parseInt() is used to get the int value of a String

‰ Integer.parseInt() works only on Strings that represent the ASCII values for digits (0,1,2,3,4,5,6,7,8,9). If you try to parse something like “two” or “real”, then the code will throw an exception.

Summary

‰ The wrapper classes correlate to the primitive types.

‰ Wrappers have two main functions:

o To wrap primitives so that they can be handled like objects.

o To provide utility methods for primitives (usually conversions)

‰ The three most important methods available in the wrapper classes are:

o xxxValue() takes no argument, returns a primitive

o parseXxx() takes a String, returns a primitive, and throws NumberFormatException

o valueOf() takes a String, returns a wrapped object, throws NumberFormatException

‰ Wrapper constructors can take a String or a primitive, except for Character, which can only take a char.

Test Your Understanding

1. Which one of the following is wrong?

a) All the type wrappers are defined in java.lang package.

b) The isNaN() method is made available by the Double class.

c) A number cannot be converted to and from Strings.

d) The Runtime class encapsulates the java run time environment.

e) ‘Like the String class, the wrapper classes are immutable’. Comment on this statement.

Session 27: Wrapper Classes, Selection Statements and Iteration Blocks

Learning Objectives

After completing this session, you will be able to:

‰ Identify Wrapper classes for the primitive data types

‰ Describe Auto boxing

‰ Explain unboxing

Primitive Types: Wrapper Classes

The following table lists the primitive types and the corresponding wrapper classes:

Primitive Wrapper

boolean java.lang.Boolean byte java.lang.Byte char java.lang.Character double java.lang.Double float java.lang.Float int java.lang.Integer long java.lang.Long short java.lang.Short void java.lang.Void

Converting Strings to Primitive Types

The primitive type wrappers provide various static utility methods such as those to convert numbers to strings and strings to numbers.

You occasionally want to pass values to an applet. The applet hypertext tag includes the param sub-tag for this like the following:

<applet ...>

<param name = "string_name" value = "string_value" >

</applet>

for passing strings to the applet program. The parameter has a name and corresponding value.

For example, you could pass two strings with numbers like the following:

<applet code="myApplet" codebase="Java" width=100 height=50>

<param name="fpNumber" value="12.45">

<param name="intNumber" value="10">

</applet>

In the applet code, usually in the init() method, you then use the getParameter(String) method from the applet class to obtain a given parameter, as in the following code:

String fpStr = getParameter ("fpNumber");

String intStr = getParameter ("intNumber");

You now have the parameter values in string form and need to convert them to numbers. The wrapper classes provide tools for this in the form of static methods.

For example, the following code:

public void init () {

string fpStr= getParameter ("fpNumber");

double fpNum = Double.parseDouble (fpStr);

String intStr = getParameter ("intNumber");

int intNum = Integer.parseInt (intStr);

……

shows the use of the parseDouble method in Double and the parseInt method in Integer.

Converting Primitive Types to Strings

‰ You can convert a primitive type to a string in several ways.

‰ The String class provides the static valueOf methods (there is one for each primitive type).

‰ The easiest way to turn a number into a string is to simply concatenate using the "+"

operator:

‰ The “+” operator is overloaded in Java (in fact, it is the only overloaded operator) as a string concatenator.

‰ Anything added to a string is also a string.

Converting Primitive Types to Strings (Example)

In the following code, you convert numerical values to strings using the valueOf() methods (there is one for each primitive type) of String class:

int i = 1;

double d = 5.0;

String dStr = String.valueOf(d);

String iStr = String.valueOf(i);

In the following code, you convert numerical values to strings using the "+" operator:

String aStr = "d = " + d;

String bStr = "i = " + i;

Now dStr and iStr objects hold string representations of 5.0 and 1, while aStr holds "d = 5.0" and bStr holds "i = 1“.

Autoboxing

‰ The autoboxing feature added to Java 5.0 does the conversion (wrapping) from primitive to wrapper object.

‰ This "wrapping" is called "autoboxing" in the sense that the primitive value is automatically "boxed up" into the wrapper object.

‰ Autoboxing is available for all the primitive or wrapper types.

Without Autoboxing (Java versions before 5.0)

Example: An ArrayList of primitive ints

public void doNumsOldWay() {

ArrayList listOfNumbers = new ArrayList

listOfNumbers.add(new Integer(3));

Integer one = (Integer) listOfNumbers.get(0);

int intOne = one.intValue();

}

With Autoboxing (Java versions 5.0 or greater)

Example: An ArrayList of primitive ints

public void doNumsNewWay() {

ArrayList<Integer> listOfNumbers = new ArrayList<Integer>;

listOfNumbers.add(3);

int num = listOfNumbers.get(0);

}

Autoboxing Illustrations

The general rule is that boxing and unboxing work wherever you can normally use a primitive or a wrapped object.

It can be illustrated in the following:

‰ Method arguments

‰ Return values

‰ Boolean expressions

‰ Operations on numbers

‰ Assignments

Method Arguments

‰ If a method takes a wrapper type, then you can pass a reference to a wrapper or a primitive of the matching type.

‰ If a method takes a primitive, then you can pass in either a compatible primitive or a reference to a wrapper of that primitive type.

‰ Example: void takeNumber(Integer i) { }

Return Values

‰ If a method declares a primitive return type, then you can return either a compatible primitive or a reference to the wrapper of that primitive type.

‰ If a method declares a wrapper return type, then you can return either a reference to the wrapper type or a primitive of the matching type.

‰ Example:

int giveNumber() { return x;

}

‰ In the preceding example, x can be either a reference to Integer wrapper or int primitive type.

Boolean Expressions

Any place a boolean value is expected, you can use either an expression that evaluates to a boolean (4 > 2), or a primitive boolean, or a reference to a Boolean wrapper.

Example:

boolean one = true; // nothing new here

Boolean two = true; // autoboxing of primitive 'true' to Boolean type

if (one && two) // auto unboxing do_something ();

Before Java 5.0, the if, while, and do-while statements are all expected as boolean expressions.

Through the use of unboxing, those flow control statements now also accept expressions that evaluate to Boolean types.

Autoboxing With Switch Statement

Similarly, the old switch statement expects a byte, short, int, or char type in Java 1.4 and earlier to Java 1.4.

With the addition of autoboxing in Java 5.0, switch now also accepts Byte, Short, Integer, and Character types.

Operations on Numbers

This is probably the strangest one. You can now use a wrapper type as an operand in operations

That means you can apply, say, the increment operator against a reference to an Integer object!

Examples:

Integer i = new Integer(56);

i++;

Integer j = new Integer(4);

Integer k = j + 3;

Assignments

You can assign either a wrapper or primitive to a variable declared as a matching wrapper or primitive.

For example, a primitive int can be assigned to an Integer reference variable and a reference to an Integer object can be assigned to a variable declared as an int primitive.

Example: Double d = x;

In the preceding example, x can be either a reference to Double wrapper or double primitive type.

Try It Out

Problem Statement:

Write a program that illustrates the use of Wrapper classes for the primitive types namely int, char, long, float, double, and boolean.

Code:

public class WrappedClassApp {

public static void main(String args[]) { Boolean b1 = new Boolean("TRUE");

Boolean b2 = new Boolean("FALSE");

System.out.println(b1.toString() + " or " + b2.toString());

for (int j = 0; j < 16; ++j)

System.out.print(Character.forDigit(j, 16));

System.out.println();

Integer i = new Integer(Integer.parseInt("ef", 16));

Long l = new Long(Long.parseLong("abcd", 16));

long m = l.longValue() * i.longValue();

System.out.println(Long.toString(m, 8));

System.out.println(Float.MIN_VALUE);

System.out.println(Double.MAX_VALUE);

} }

Refer File Name: WrappedClassApp.java to obtain soft copy of the program code

How It Works:

‰ The program examines some of the more useful methods provided by the wrapped classes.

‰ It creates two objects of class Boolean from string arguments passed to their constructors.

‰ It assigns these objects to b1 and b2 and then converts them back to String objects when it displays them.

‰ They are displayed in lowercase, as boolean values are traditionally represented.

‰ The program then executes a for loop that prints out the character corresponding to each of the hexadecimal digits.

‰ The static forDigit() method of the Character class is used to generate the character values of digits in a number system of a different radix.

‰ The static parseInt() and parseLong() methods are used to parse strings according to different radices.

‰ In the example, they are used to convert strings representing hexadecimal numbers into Integer and Long values.

‰ These values are then multiplied together and converted to a string that represents the resulting value in base 8.

‰ This is accomplished using an overloaded version of the toString() method.

‰ The sample program concludes by displaying the minimum float value and the maximum double value, using the predefined class constants of the Float and Double classes.

Typical problems include real-time problems or challenges:

Java 5 (JDK 1.5 and further) includes autoboxing and auto-unboxing. A developer might be tempted to apply objects such Integer or Double exclusively, abandoning primitives altogether.

For example, it is possible to write code like this:

// A bad use of autoboxing/unboxing!

Double a, b, c;

a = 10.0;

b = 4.0;

c = Math.sqrt(a*a + b*b);

System.out.println(“Hypotenuse is “ + c);

Solution:

‰ In this example, objects of type Double hold values that are used to calculate the hypotenuse of a right triangle.

‰ Although this code is technically correct, and in fact, work properly, it is a very bad use of autoboxing or unboxing.

‰ It is far less efficient than the equivalent code written applying the primitive double.

‰ The reason is that each autobox and auto-unbox adds overhead that is not present if the primitive type is used.

‰ In general, you should restrict your use of the type wrappers to only those cases in which the object representation of a primitive type is required.

Summary

‰ As of Java 5, autoboxing / unboxing allow you to convert primitives to wrappers or to convert wrappers to primitives automatically.

‰ Using the == with wrappers is tricky; wrappers with the same small values (typically lower than 127), will be ==, larger values will not be ==.

Test Your Understanding

1. State true or false for the following:

a) Autoboxing always creates the proper object, and auto-unboxing always produces the proper value. There is no way for the process to produce the wrong type of object or value.

b) Using Java 5 (JDK 1.5 and furhter), the method calls such as intValue() or doubleValue() are very much needed in the code.

Session 30: Wrapper Classes, Selection Statements and Iteration Blocks

Learning Objectives

After completing this session, you will be able to:

‰ Use decision control structures (if, if-else, switch), which allows selection of specific sections of code to be executed.

Control Structures

Control structures allows you to change the ordering of how the statements in your programs are executed

Two types of control structures are:

‰ Decision control structures: Allows you to select specific sections of code to be executed

‰ Repetition control structures: Allows you to execute specific sections of the code a number of times.

Decision Control Structures

Decision control structures are Java statements that allows you to select and execute specific blocks of code while skipping other sections

Types of decision control structures are:

‰ if-statement

‰ if-else-statement

‰ if-else if-statement

if-statement

if-statement specifies that a statement (or block of code) will be executed if and only if a certain boolean statement is true.

if-statement has the form:

if( boolean_expression ) statement

or

if( boolean_expression ){

statement1;

statement2;

}

where boolean_expression is either a boolean expression or boolean variable.

if-statement Flowchart

The following figure shows the flowchart of an if statement:

Examples of if-statement Example 1:

int grade = 68;

if( grade > 60 )

System.out.println("Congratulations!");

Example 2:

int grade = 68;

if( grade > 60 ) {

System.out.println("Congratulations!");

System.out.println("You passed!");

}

Coding Guidelines

‰ The boolean_expression part of a statement should evaluate to a boolean value, which means that the execution of the condition should either result to a value of true or a false.

‰ Indent the statements inside the if-block.

‰ For example,

if( boolean_expression ) { //statement1;

//statement2;

}

if-else Statement

‰ if-else statement is used when you want to execute a certain statement if a condition is true, and a different statement if the condition is false.

‰ if-else statement has the form:

if( boolean_expression ) { statement1;

statement2;

. . . }

else {

statement3;

statement4;

. . . }

if-else Flowchart

The following figure shows the flowchart of an if-else statement:

Examples of if-else Statement Example 1:

int grade = 68;

if( grade > 60 )

System.out.println("Congratulations!");

else

System.out.println("Sorry you failed");

Example 2:

int grade = 68;

if( grade > 60 ){

System.out.println("Congratulations!");

System.out.println(“You passed!");

else{

System.out.println("Sorry you failed");

}

Coding Guidelines

‰ To avoid confusion, always place the statement or statements of an if or if-else block inside brackets {}.

‰ You can have nested if-else blocks. This means that you can have other if-else blocks inside another if-else block.

‰ For example,

if( boolean_expression ){

if( boolean_expression ){

//some statements here }

} else{

//some statements here }

if-else-else if Statement

‰ The statement in the else-clause of an if-else block can be another if-else structure.

‰ This cascading of structures allows you to make more complex selections.

‰ The statement has the form:

if( boolean_expression1 ) statement1;

else if( boolean_expression2 ) statement2;

else

statement3;

if-else-else if Flowchart

The following figure shows the flowchart of an if-else-else if statement:

Example of if-else-else if Statement Example:

int grade = 68;

if( grade > 90 ){

System.out.println("Very good!");

}

else if (grade > 60){

System.out.println("Good");

} else{

System.out.println("Sorry you failed");

}

Common Errors

The condition inside the if-statement does not evaluate to a boolean value, for example,

//WRONG

int number = 0;

if( number ) {

//some statements here }

The variable number does not hold a boolean value.

Writing elseif instead of else if Using = instead of == for comparison.

For example, //WRONG

int number = 0;

if( number = 0 ){

//some statements here }

This should be written as, //CORRECT

int number = 0;

if( number == 0 ){

//some statements here }

switch allows branching on multiple outcomes switch statement has the form:

switch( switch_expression ){

case case_selector1:

statement1;//

statement2;//block 1

break;

case case_selector2:

statement1;//

switch_expression is an integer or character expression

case_selector1, case_selector2 and so on, are unique integer or character constants When a switch is encountered:

‰ Java first evaluates the switch_expression, and jumps to the case whose selector matches the value of the expression.

‰ The program executes the statements in order from that point on until a break statement is encountered, skipping then to the first statement after the end of the switch structure.

‰ If none of the cases are satisfied, then the default block is executed. Take note however, that the default part is optional.

Note:

‰ Unlike with the if statement, the multiple statements are executed in the switch statement without needing the curly braces.

‰ When a case in a switch statement has been matched, all the statements associated with that case are executed. Not only that, the statements associated with the succeeding cases are also executed.

‰ To prevent the program from executing statements in the subsequent cases, you use a break statement as your last statement.

Flowchart of switch Statement Sample Program:

15 default:

15 default:

In document Core Java Handout v1.0 (Page 116-145)