Class
Members Peter
Komisar © Conestoga College latest version 4.5
2004
Practical Aspects of Object Oriented Programming
In
object-oriented programming, data and operations are formally coupled
in the
data structure called the
class. The class acts as a container for it's members.
Class
members include fields,
which are also called variables.
Variables hold values
that describe characteristics or
properties of an object. The class member that
describes behavior
is the method. Methods have
counterparts in other languages
known as functions, procedures,
routines or operations. Methods are the verbs
or
action parts of a class. Java classes also hold
constructors. These are special
methods
whose sole job is to create what are called new instances
or objects of a given class.
In this study we wish to
cover some of the aspects regarding constructors that tie into
inheritance that
were not covered in the earlier note and the previous Java course.
Constructors & Overloading
Invoking a Constructor
A
constructor is a unique and privileged method which is
used to create and initialize
new objects. Creating
a class instance using the constructor with the new operator
is called instantiation. In the following example, declaration,
instantiation and assignment
are all combined.
Example AClass reference = new AClass( ); // a constructor being invoked
The above example shows
a constructor being deployed in the instantiation process.
Defining a
Constructor
When
defining a constructor in a class definition the constructor has
three distinguishing
elements.
1) The
constructor shares the same name as the class
2) It
is defined with no explicit return type.
3) Like
methods it's identifier is followed by a pair of closed round braces.
The implied return type
of the constructor is the class object that is set up in memory.
Constructors are like methods in the the use of round braces to
receive arguments
and the use of curly braces to define the scope
of their actions. Following is the
general form of the
constructor.
General form of a constructor as it would appear in a class definition
class ClassName{
ClassName(
){
// the constructor with same name as class, no return type and round
braces
}
}
First consider a class called Car defined without any constructors defined.
Example
class Car{
// variables
int speed = 7;
int braking = 7;
int handling = 7;
// method
int getRating( ) { return speed + braking + handling; }
}
Now lets look at a
Car class and define a constructor in it. First notice the
constructor
has the same name as the class, Car, and has no
return type, unlike it's sibling, the
method.
class Car{
//
variables defined in class scope initialized to the default value 0
int speed;
int braking;
int handling;
// an no-args constructor
Car(
){
speed =7;
braking= 7;
handling = 7;
}
// class method
int getRating( ) { return speed + braking + handling; }
}
The
no-args default constructor
You might be
wondering what did this accomplish? We saw this class in a
simpler
form and would find if we tested it that it would work the
same without the constructor.
What really happened, in the
absence of us overtly supplying a constructor, was that
a
'no-argument' default constructor was supplied for us by the java
environment.
This supplied constructor did the work of initialization
just as our explicitly defined
constructor worked.
//
in the absence of an overtly supplied constructor the default no-args
constructor is supplied
The
Issue of Constructor Non-Participation In Inheritance
Inheritance allows a
class to extend another class in such a way as to have access
to
the resources of the parent class. We are able to assign values
to the parent
variables as if they had been defined in the child
class.
Constructors are not
really considered to be class members though they are ostensibly
defined within the class definition. This follows from the fact
that they are used to
create class objects rather than being a
participating member of it.
There is a special case
that pertains to this discussion. If you define a class with
a
constructor that takes arguments then the compiler doesn't bother
supplying
the no-args default constructor for you. Now
if a child class is built that attempts
to invoke the no-args
constructor of the parent the compile will fail as that
version of the constructor
in the parent is not defined. The solution here is to
provide a no-args constructor
overtly whenever you decide to define constructors
for a class.
This is shown in the next example.
// The no-args constructor is supplied automatically only if other constructors are not explicitly defined in a class.
Constructor
Overloading
You
might noticed from tours of the documentation that more than one
constructor
can be supplied for a
class. In the following example we can build the Car class with
three constructors. We are defining the
class without variables and methods to simplify
the
view.
Example
class Car{
Car( ) { // the no args constructor supplied
explicitly
}
Car(String options){
// a constructor defined taking a String argument
}
Car(String options, String customization){
// a constructor defined taking two string arguments
}
The compiler doesn't
mind several constructors being built with the same name.
This
is called constructor overloading. This is similar to method
overloading where
the compiler is able to
distinguish each constructor based on the order, type and
number
of arguments.
Using 'this' & 'super' in Constructors
Recall
that the keyword 'this' could be used to reference variables or method defined
in the scope of
a container class, that is, the
class that contains those variables
and methods. The 'this' keyword
also has a special form that is used to reference
constructors defined inside a class.
In
the case of constructors, the 'this' keyword is used as an identifier
together with
the form of
the constructor that it is being
used to invoke. For instance the following
example shows how
to invoke a constructor in the current class that has an argument
list consisting of a String, and an int value. (Another way of to
say this is that the form
matches a constructor defined in the
current class with a matching
constructor signature.)
Example
this( "x", 9 );
// invokes a constructor in the current class that takes a String value and an int
This
is easier to show in code. Following is a complete example
Example
class Limo{
Limo(String stretch, int spec1, int spec2, int spec3){
// some complex processing
}
Limo(String
tinted, String stretch ){
this(stretch , 1,2,3);
// calls the adjacent constructor with matching argument list
//
then do further construction, using tinted directive
}
}
Where
the 'this' keyword used with constructors references constructors
defined in
the containing class, the 'super' keyword can be used in constructors
to reference
a target constructor defined in a parent class.
The
super keyword is used in a similar way that the 'this'
keyword, in a form that imitates
a
constructor that needs to be invoked. The difference is the 'super'
keyword is used to
invoke a matching constructor in the
parent class. (This is where the trouble comes
in that
we spoke of earlier, in that a no-args constructor may be invoked that
is defined.)
To
example this we need to create a
constructor where a child class subclasses a
parent.
First we define Car class with two constructors.
Example
class Car{
Car(String options){
// build car with standard options
}
Car(String options, String customization){
// build car with custom options
}
//
potential problem as the no-args constructor is not defined
}
Now we create a
SportsCar class that extends the parent class, Car. Notice how
we
use super to specifically invoke one of the parent constructors by
matching the
argument lists.
class SportsCar extends Car{
SportsCar(String
options ){
super(options);
// passes control to the parent constructor with matching signature
}
}
Notice
now if we tried to use the no-args super( ) we would get a compiler
error
because now that constructors
have been defined in the Car class the no-args
constructor
has not been supplied.
/*
You might want to test this right now! Cut and paste the two classes
and compile. (It won't
* run because there is no main
method.) Then add a no-args version of super and try to compile.
* Observe the
results. Rectify by adding the no-args constructor to the parent.)
*/
A
final point on 'this' and 'super'. If the constructor form of these
keywords are used
each must be the
first statement in the constructor code block. This leads to the
obvious,
conundrum, 'In a constructor that uses both, how can they both be
first? Both insist on
being
the first call in a constructor. To use both, one must use the
form shown in the
last example where one constructor calls
'super' and then the second constructor calls
'this'.
A
last word about Java constructors, if
this was a C++ course we would go onto a
discussion of
destructors, the counterpart of a
constructor. Java saves us the need
for destructors by taking
care of all the memory deallocation
chores via the gc thread
or garbage collector.
// Both this( ) and super( ), used in their constructor forms, insist on being the first statement in a constructor.
Following is another complete example showing super and this used inside constructors
Second
Constructor Example
class
Old{
Old( ){
System.out.println("No-args Old");
}
Old(String name){
System.out.println("Hi " + name + "! I am Old's one
arg constructor being invoked.");
}
}
class Young extends
Old{
Young(String name){
super(name);
System.out.println("Young having called String constructor of
Old");
}
Young(String name, String day, String month){
this(name);
System.out.println("Young calls 'this' and adds it's own
properties");
System.out.println(" Day is: " + day + " and " +
" Month is: " + month + "\n");
}
}
public class OY{
public static void main(String[] args){
System.out.println( " \n**** No arg Old ****\n " );
new Old();
System.out.println(
" \n**** Single arg Young ****\n " );
new Young("Bentley");
System.out.println( " \n**** One arg Old ****\n " );
new Old("Syvester");
System.out.println( " \n**** Three args Young ****\n "
);
new
Young("Melissa","Thursday","April");
}
}
Output
**** No arg Old ****
No-args
Old
**** Single arg Young ****
Hi Bentley!
I am Old's one arg constructor being invoked.
Young having called
String constructor of Old
**** One arg Old ****
Hi
Syvester! I am Old's one arg constructor being invoked.
****
Three args Young ****
Hi Melissa! I am Old's one arg
constructor being invoked.
Young having called String constructor
of Old
Young calls 'this' and adds it's own properties
Day
is: Thursday and Month is: April
Events
in Constructor Invocation
The following table shows the specific order of activities followed during the construction process.
Events in Constructor Invocation
|
The following
code sample demonstrates the invocation of parent and grandparent
constructors.
Sample
Demonstrating Invocation of Ancestor Constructors
class
Dark{
Dark(){
System.out.println("1. Dark");
}
public static void main(String[] args){
new Dark();
new Dawn();
new Day();
}
}
class Dawn extends Dark{
Dawn(){
System.out.println("2. Dawn");
}
}
class Day extends Dawn{
Day(){
System.out.println("3.
Day");
}
}
Output
1.
Dark
1. Dark
2. Dawn
1. Dark
2. Dawn
3. Day
The
redundancy in the output demonstrates how parent constructors are
invoked recursively.
Classes of the java.lang Package
The
java library of classes is enormous and growing! Incidently this note
itself seems
large. This is mainly
due to the inclusion of tables that summarize the methods of the
classes we are studying. The classes
of the java.lang package do basic 'bread and butter'
activities.
The functions these classes provide are so fundamental that they are
supplied
without the need to import the java.lang package. Major players
in this package are the
String class and the Math
class. There is also the set of wrapper classes, one for
each
primitive type. There are other neccessary classes like System, class
Class and
ClassLoader. Object class
is defined in the lang package as is the Thread class. Java's
SecurityManager is also defined in the lang
package. The lang package is also where
two
dozen exception classes and twenty-one error classes are defined.
In this section
we look at the
String, Math and wrapper classes.
Though
in a different package, the util package, Vector is
included too, because it has been
used so much throughout the
java libraries. Though Vector is often
replaced by by classes
such as ArrayList contained in the collection
package, it remains a classic Java workhorse.
//
ArrayList adds some nice features however ArrayLists operations are not
synchronized
// as are Vector's methods. In a
multi-threaded environment, you would need to make sure
// calls on ArrayList are
synchronized.
The String Class
In Java when you
need a string of characters in your programs, you use an instance of
the
String class. (We look at String class a little closer later
in the course.) String objects hold
a series of adjacent
characters in a way similar to an array. However, where with an array
you would reference an element of the array to get a character,
with String you use one of
the class methods to manipulate the
string.
String literals
A String literal is created when zero or more characters are enclosed in double quotes.
Example
"A String literal"
// String literal
String literals are
normally used in some context. For instance as an argument to a
method.
Example
setText(" String literal as a method argument " );
String literals are
also used in assignments.
Example
String string = " A String literal assigned to a String
reference variable. ";
String is a class so
an object of String class can be created using a String class
constructor.
Example
String s = new String("A string" );
Strings as Immutable Objects
Strings are said to be
immutable. This means a
String object is unchangeable. This
description can be
misleading. It makes it sound as though a String object is somehow
final like a variable that has been marked final and can no
longer be changed. What is
unchangeable is the String object that
has been stored in memory. So how do we make
changes to a a
String object? What actually occurs when java methods are used to change
a String object is that the string is copied
into an instance of the mutable StringBuffer class.
The changes
are made to this representation and then a new immutable String
object is
built. The old reference is then made to point to the
new object while the old dereferenced
object is discarded. Once no
longer referenced, it is just a matter of time before the
background thread called the garbage collector deallocates the
memory associated with
the old immutable String object.
//
When a change on a string is executed the string is written to a
StringBuffer the
//
modifications are effected and then a new immutable String object is
created.
// The reference to
the string object is made to point to the new string and the old
// one is discarded.
The Overloaded Addition Operator
There is one case of
operator overloading in Java. The
addition operator, represented
by the '+' symbol, is overloaded
to do String concatenation. (Overloading in this context
is
when a symbol is able to do more than one kind of operation in a
language.) If one of the
operands to the operator, +
is a String object, the other type will either be promoted
to String
type (as in the case of primitives) or the toString( )
method will be called on it (in the case
of object types.) In the
following case each primitive value represented by x and y will be
supplied in their String form.
Example
System.out.println(" x is " + x + "y is " + y );
Common
String class Construction
Following
are two common constructions of a String object. The first uses a
constructor
while the second is a
String literal assignment.
Example1 String s1 = new String( "common constructor"); // via a constructor
Example 2 String s2 = "a string literal"; // assigning a string literal
There are several String
constructors ( 9 ) and String objects can be created in a number
of
ways. The following example shows a Sting object constructed from an
array of char
type.
Example
String ball = "balloon"; // is equivalent to:
char
parts[] = {'b', 'a', 'l','l','o','o','n'};
String
ball2 = new String(parts);
Deep and Shallow Comparisons
When reference types
are compared via the equality operator, ==, the addresses stored in
the references are compared. This is called a shallow
comparison. If the equals( ) method
is used, the
contents pointed to by the address stored in the reference is
compared. This
is a deep comparison.
The following two cases cover the different unique circumstances
that may occur and are easily extrapolated to other variations.
Comparisons of Same Addresses and Same Stored Values
To complicate matters,
the java environment maintains a pool of
string literals.
Each string
literal is represented in
the pool. Identical string literals are only represented once in the
pool.
If an identical literal is
used twice in a program, it is only represented once in the literal
pool.
When deep and shallow
comparison are made on the two references representing the same
string literal value the result is
that consistent with the idea that the reference both refer to the
same stored value and simultaneously,
the references also point to the same address.
Example 1
String
xx = "X";
String xy = "X";
if
(xx.equals(xy)) //
a 'deep' comparison ( of values stored ) resolves to true
// . . .
if
(xx = =
xy) // a second 'shallow' comparison between the same
references also
resolves to true
The
second "shallow" comparison also resolves to true as the
addresses where the string literal,
"X" is stored, is
the same location.
Comparisons
of Different Addresses but Same Values
On
the other hand, when a reference is created via the constructor
housing a literal, first the
literal
is recorded in the literal pool and then a new string is created,
copied from the one in
the literal
pool. This copy is stored at a different location so will not share
the same address
as the one in the
literal pool.
Example 2
String yy = "X";
String yx = new String("X");
if
(yy.equals(yx))
// a 'deep' comparison (of stored values) resolves to true
//
however
if (yy = =
yx)
// will resolve to false
Code
Sample Demonstating Deep and Shallow Comparison
class sTz{
public static void main(String[]args){
// First Scenario
String xx = "X";
String xy =
"X";
if
(xx.equals(xy))
System.out.println
("\n"+"A deep comparison tests true for comparison on
literal assignmnents");
if (xx ==
xy)
System.out.println
("A shallow test yields true indicating one value is stored at
one address \n");
// Second
Scenario
String yy = "X";
String yx =
new String("X");
if (yy.equals(yx))
System.out.println
("Values are the same when assigned by literal or by
literal-supplied constructor");
if (yy == yx)
;
else
System.out.println
("Shallow
tests false showing the two values are stored at different
addresses");
}
}
String Class Documentation // documentation for reference
Constructor
Summary
Here
are 9 String constructors that show String instances can be created
from an
empty character sequence, a
provided String object (where in fact a copy is created
and
encapsulated in the new instance), a StringBuffer instance, and
arrays. (or parts
of arrays), of
byte and char type, with or without specified character encodings.
String( ) |
Initializes a newly
created String object so that it represents |
String(byte[] bytes) |
Construct a new
String by converting the specified array |
String(byte[]
bytes, |
Construct a new
String by converting the specified subarray |
String(byte[]
bytes, int offset, |
Construct a new
String by converting the specified subarray |
String(byte[] bytes,
|
Construct a new
String by converting the specified array |
String(char[] value) |
Allocates a new
String so that it represents the sequence of |
String(char[] value,
|
Allocates a new
String that contains characters from a |
String(String value) |
Initializes a newly
created String object that is a copy of |
String(StringBuffer buffer) |
Allocates a new
string that contains the sequence of |
// constructors deprecated because they didn't work properly are left out
Method
Summary
// the short
summary from the JDK API documentation
char charAt(int index) |
Returns the character at the specified index. //An index ranges from 0 to length() - 1. // The first character of the sequence is at index 0 |
int compareTo(Object o) |
Compares this String to another Object. |
int compareTo(String StringB ) |
Compares two strings lexicographically. // returns a negative int if string is less than argument, 0 if the same, and a positive int if greater than See API for details |
int
compareToIgnoreCase |
Compares two strings lexicographically, ignoring case considerations. |
String concat(String str) |
Concatenates the specified string to the end of this string. |
static String
copyValueOf |
Returns a String that is equivalent to the specified character array. |
static String copyValueOf
|
Returns a String that is equivalent to the specified character array. |
boolean endsWith(String suffix) |
Tests if this string ends with the specified suffix. |
boolean equals(Object anObject) |
Compares this string to the specified object. |
boolean equalsIgnoreCase
|
Compares this String to another String, ignoring case considerations. |
byte[] getBytes( ) |
Convert this String into bytes according to the platform's default character encoding, storing the result into a new byte array. |
byte[] getBytes(String enc) |
Convert this String into
bytes according to the specified character |
void getChars(int
srcBegin, int |
Copies characters from this string into the destination character array. |
int hashCode( ) |
Returns a hashcode for this string. |
int indexOf(int ch) |
Returns the index within this string of the first occurrence of the specified character. |
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. |
int indexOf(String str) |
Returns the index within this string of the first occurrence of the specified substring. |
int indexOf
|
Returns the index within this string of the first occurrence of the specified substring, starting at the specified index. |
String intern( ) |
Returns a canonical representation for the string object. |
int lastIndexOf(int ch) |
Returns the index within this string of the last occurrence of the specified character. |
int lastIndexOf
|
Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index. |
int lastIndexOf(String str) |
Returns the index within this string of the rightmost occurrence of the specified substring. |
int lastIndexOf
|
Returns the index within this string of the last occurrence of the specified substring. |
int length( ) |
Returns the length of this string. |
boolean
regionMatches (boolean |
Tests if two string regions are equal. |
boolean regionMatches(int
toffset, |
Tests if two string regions are equal. |
String replace
|
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar. |
boolean startsWith(String prefix) |
Tests if this string starts with the specified prefix. |
boolean startsWith
|
Tests if this string starts with the specified prefix beginning a specified index. |
String substring(int beginIndex) |
Returns a new string that is a substring of this string. |
String substring
|
Returns a new string that is a substring of this string. |
char[] toCharArray() |
Converts this string to a new character array. |
String toLowerCase( ) |
Converts all of the characters in this String to lower case using the rules of the default locale, which is returned by Locale.getDefault. |
String toLowerCase
|
Converts all of the characters in this String to lower case using the rules of the given Locale. |
String toString() |
This object (which is already a string!) is itself returned. |
String toUpperCase() |
Converts all of the characters in this String to upper case using the rules of the default locale, which is returned by Locale.getDefault. |
String toUpperCase(Locale locale) |
Converts all of the characters in this String to upper case using the rules of the given locale. |
String trim() |
Removes white space from both ends of this string. |
static String valueOf(boolean b) |
Returns the string representation of the boolean argument. |
static String valueOf(char c) |
Returns the string representation of the char argument. |
static String valueOf(char[] data) |
Returns the string representation of the char array argument. |
static String
valueOf |
Returns the string representation of a specific subarray of the char array argument. |
static String valueOf(double d) |
Returns the string representation of the double argument. |
static String valueOf(float f) |
Returns the string representation of the float argument. |
static String valueOf(int i) |
Returns the string representation of the int argument. |
static String valueOf(long l) |
Returns the string representation of the long argument. |
static String valueOf(Object obj) |
Returns the string representation of the Object argument. |
String
Class Code Example
The following code
example shows that the methods of the String class are
pretty
straight forward to use.
import java.io.*;
class
StringT{
public static void main(String[]
args){
char[] sa = {'S', 't', 'r', 'i', 'n','g'};
String string = new
String(sa);
// one of String's constructors
System.out.println("\n 1. string has the
value " +string );
String sb = "string";
int i
=
string.compareTo(sb);
// compareTo( )
System.out.println(" 2. The lexigraphical comparison yields "
+ i );
String
cat=string.concat(sb);
// concat( );
System.out.println(" 3. sb concatenated to string is " +
cat + "\n");
try{
byte[] b= new byte[string.length( )];
System.out.println(" 4. string length is
" +string.length( )+"\n");
for(int k=0;k<b.length;k++){
b = string.getBytes("8859_1"); //
getBytes("8859_1") with character encoding
System.out.println(b[k]);
}
}
catch(UnsupportedEncodingException uee){ //
have to catch unsupported encoding
System.out.println("Unsupported Encoding");
}
int j =
string.indexOf("St");
// indexOf( )
System.out.println("\n 5. The first occurence
of ring is at index " + j );
// This reports index 0 so think of the index like an offset starting
at zero
int z =
(int)'T';
// casting a char type to an int
System.out.println(" 6. The char literal T cast
to an int is "+ z);
System.out.println("
7. before and after trim()
\n");
// trim( )
System.out.println("
before length: " + " xyz
".length()); // calling on string
literals
System.out.println("
after length: " + " xyz
".trim().length());
String
string2=string.valueOf(sa);
// valueOf used on a char array
System.out.println("\n 8. This is sa array
returned as a string " + string2);
}
}
Wrapper Classes
Sometime you will
need to treat a primitive type, ( i.e. int ), as an object. As an
example, a primitive type cannot be added directly to a Vector
however often
a number would need to
be added to a Vector. Vector can only receive object
types.
Wrapper classes encapsulate primitive types in class objects
so they can
be treated like object types. For instance, Integer
is the wrapper class for integers.
A wrapper class exists for
each of the primitive types.
The Wrapper class name
for each primitive can be deduced by starting the
unabbreviated
version of the primitive type name with
capitals. For example, int
type's wrapper class is the
Integer class, while the char type's wrapper is the
Character
class. All the primitives and their corresponding wrapper classes are
listed in the following table.
Wrapper
Class for each Primitive Type
Wrapper |
Primitive |
Boolean |
boolean |
Character |
char |
Byte |
byte |
Short |
short |
Integer |
int |
Long |
long |
Float |
float |
Double |
double |
Besides providing
objects types for primitives, wrapper classes store useful constants
and methods to convert to and from String
and other types. In the following example
one of the
important roles wrapper classes serve is shown.
The Integer wrapper class
static
parseInt( ) method converts a String value to an int value. A wrapper
class is
built on the int by passing
it into the Integer class constructor. As an example of the
convenience method that the wrappers offer,
the int value is returned as a double
by
the Integer object's floatValue( ) method. Notice we don't have to
catch the
runtime
NumberFormatException but nothing stops us from doing that.
Wrapper Classes Like String Class Represent Immutable Values
Another important point
about the wrapper classes, they are like the String
class and
represent immutable values. There is a similarity between the
wrapper
classes and the the String class in that the String class
represents a wrapper for
a collection of primitive 'char' type and the
wrapper classes serve as containers
for the other numerical
primitive types.
Wrapper Class Code Example
*/
* parseInt() is a static method called here on the class * name */
class
Wrap{
public
static void main(String[] args){
if(args.length
< 1){
System.out.println("Enter
a number at the command line");
System.exit(0);
}
try{
int
i=Integer.parseInt(args[0]);
Integer
theWrapperClass= new Integer(i);
float
f = theWrapperClass.floatValue( );
//
intValue( ) returns enclosed wrappers int value
System.out.println("Here's
your number as a float: " + f);
}
catch(NumberFormatException
nfe){
System.out.println("Your
number is too big or has a format problem");
System.exit(0);
}
}
}
//
The number output converts to exponential floating point form at 10
million.
// A NumberFormatException is thrown when the range of an
int is exceeded,
//
~ +/- 2.147
billion.
The Math Class // for reference, won't be on final exam
Math
contains a collection of math methods and two constants. The
constants are
Math.PI and Math.E.
Both are public, static, final and double. The Math class
itself is made final so cannot be
sub-classed. It's constructor is private so it cannot
be
instantiated. It's methods and constants are
static so can be accessed through the
class
name. The result of this rigid definition, aside from tight control
and security,
is that Math class is accessed through simple,
static calls.
Example Math.random( );
A
Brief look at Math class Methods.
abs(
)
There are four versions of
abs( ), each which returns an absolute value for a value
provided which may be int, long, float, or
double. // resolves a -2 to a 2
ceil(
) & floor( )
These
methods take and return doubles corresponding to the nearest int
value above
or below the double
provided // ceil( ) will resolve a 1.1
to a 2
max(
) & min( )
There are
four versions of each max( ) and min( ) for int, long, float and
double types.
These methods take two
values and return the greater or the lesser of two, respectively.
random(
)
random( ) returns a random
number between 0.0 and just less than 1.0. This method
acts
as a wrapper for the creation of an instance of the Random class
which is one of
the utility methods
supplied in the java.util package.
//
Random # formula: random number = (int) ( Math.random( )
* number_range) + 1
round(
)
Two forms of this method are
available to round a float (to an int) or a double (to a long)
sin(
), cos( ) & tan( )
// there are also
asin acos atan & atan2
These
methods take doubles and return the sine, cosine, and tangent as
doubles.
sqrt(
double d )
sqrt( )
returns the square root of a double provided as an argument
pow(double
number, double power)
pow( )
returns a number evaluated to a given power
log(
)
Returns the natural logarithm
(base e) of a double value.
exp(
)
Returns the exponential number
e (i.e., 2.718...) raised to the power of a double value.
rint(
)
takes a double, rounds to an
int then returns this value as a double
IEEEremainder(double
f1, double f2 )
returns an IEEE
formulated remainder of a division
//
supplemental information The remainder value is mathematically equal
to f1 - f2 × n, where n
is
the mathematical integer closest to the exact mathematical value of
the quotient f1/f2, and if
two
mathematical integers are equally close to f1/f2, then n is the
integer that is even.)
toDegrees(
) // new
since
JDK1.2
Converts an angle
measured in radians to the equivalent angle measured in degrees.
toRadians(
) //
new since JDK1.2
Converts
an angle measured in degrees to the equivalent angle measured in
radians.
/*
not catching number format exception (Try entering something like
5y5) */
Math Code Example
class mathMethods{
public static void main(String[] args){
if(args.length <6){
System.out.println("Enter 6 numbers at the command line");
System.exit(0);
}
int
a=Integer.parseInt(args[0]);
int b=Integer.parseInt(args[1]);
int c=Integer.parseInt(args[2]);
int d=Integer.parseInt(args[3]);
int e=Integer.parseInt(args[4]);
int f=Integer.parseInt(args[5]);
double t;
int[] intArray=new int[]{a,b,c,d,e,f};
for ( int i=0; i < intArray.length - 1; i++ ){
int z=Math.min(intArray[i],intArray[i+1]
);
intArray[i+1]=z;
}
int
small=intArray[intArray.length-1];
System.out.println("The smallest number in this set is "+small);
System.out.println
(" The square
root of this number is " + Math.sqrt(small
) +
"\n
which when rounded is " +Math.round(
Math.sqrt(small) ) );
}
}
The Vector Class
One of the principle
drawbacks of using arrays is they need to be fixed in length. They
don't lend themselves to dynamically changing size. A Vector is a
Java class that acts
as a container similar to an array but one
which can grow or shrink in size to allow objects
to be added or
removed after the Vector has been created. While arrays are a
built-in
feature of the Java language the Vector class is a regular
Java library class and will
be referenced via the java.util package. Unlike arrays, which can be
specified for any
type defined in Java (primitives, arrays, and Object types ),
Vectors store one generic
type, that of Object.
It is easy to add an item to a Vector but to get it back it has
to be
cast to the appropriate type.
Vector, unlike the
String, Math and the wrapper classes are not in the java.lang
package.
To use the Vector class the java.util package needs to be
imported or Vector's fully
qualified name needs to be used, java.util.Vector. Following is the
class signature of
the Vector class
and it's hierarchy.
Vector Class Signature
public class Vector extends AbstractList implements List, Cloneable, Serializable
Vector Class Hierarchy
java.lang.Object
|
+--java.util.AbstractCollection
|
+--java.util.AbstractList
|
+--java.util.Vector
//
the inheritance tree shows Vector is a type of List and also
implements the List interface
//
A list is an ordered collection (also known generically as a sequence).
A Vector is created via
one of it's a 4 constructors. Vector has an empty constructor
and
a constructor that takes a Collection
object. It also has a constructor allowing
setting the
initial capacity of the Vector, and a fourth constructor allows
specifying
the initial capacity and the capacity increment. The
capacity increment decides the
size that the vector will grow by
and is automatically set to the size of the vector.
Vector implements the
methods of the List interface plus about 15 other methods for
a
total of about 40 methods. This shows you that Vector has quite a bit
of versatility
absent in the array.
Vector v=new Vector( 5 ); // this is a Vector with it's size set to 5.
You
can use add( ) and addElement( ) methods to add items to the Vector
and
remove( ) or removeElement( )
methods to remove items. Primitive types need to
be
'wrapped' in appropriate wrapper classes to be stored in a Vector.
The
elements( ) method will return
an Enumeration object which you can iterate with
Enumeration's hasMoreElements( ) and
nextElement( ) methods. elementAt( )
returns
a component at a specified index. It is interesting to note that the
Vector
object will allow more items
to be added than was declared to the constructor
as
the initial capacity. But if an access is attempted beyond what has
been added
( as in v.element(7) )
then the runtime exception ArrayOutOfBoundsException
is
thrown. This indicates that an Object array is being used within the
Vector
class. This array is copied
to a bigger array when the stated capacity of the
Vector
is exceeded.
//
The fact an ArrayOutofBoundsException may be thrown telegraphs that
// Vector is a wrapper for an array
accessorized with 'growable' algorithms
Vector Code Sample
import java.util.*;
class
VectorTest{
public static void
main(String[]args){
Vector v=new
Vector(3);
Integer i1=new Integer(1);
Integer i2=new Integer(2);
Integer i3=new Integer(3);
Integer
i4=new Integer(4);
v.add(i1);
v.add(i2);
v.add(i3);
v.add(i4); // not like
array. Vector adds past capacity.
Integer five=(Integer)(v.elementAt(3));
System.out.println(five.intValue());
}
}
Constructor
Summary
// from the jdk documentation
Vector( ) |
Constructs an empty vector so that its
internal data array |
Vector |
Constructs a vector containing the
elements of the |
Vector |
Constructs an empty vector with the
specified initial |
Vector(int initialCapacity, |
Constructs an empty vector with the specified
initial |
Method
List
void add (int index, |
Inserts the specified element at the
specified position |
boolean add(Object o) |
Appends the specified element to the end of this Vector. |
boolean addAll |
Appends all of the elements in the
specified Collection |
boolean addAll |
Inserts all of the elements in in the
specified Collection |
void addElement |
Adds the specified component to the
vector end, |
int capacity() |
Returns the current capacity of this vector. |
void clear ( ) |
Removes all of the elements from this Vector. |
Object clone( ) |
new Returns a clone of this vector. |
boolean contains |
Tests if the specified object is a
component in |
boolean containsAll |
Returns true if this Vector contains all
of the |
void copyInto |
Copies the components of this vector into
|
Object elementAt(int index) |
Returns the component at the specified index. |
Enumeration elements() |
Returns an enumeration of the components
of |
void ensureCapacity |
Increases the capacity of this vector, if
necessary, |
boolean equals(Object o) |
Compares the specified Object with this
Vector |
Object firstElement( ) |
Returns the first component (the item at
index 0) |
Object get(int index) |
Returns the element at the specified
position in |
int hashCode() |
Returns the hash code value for this Vector. |
int indexOf(Object elem) |
Searches for the first occurence of the given
argument, |
int indexOf |
Searches for the first occurence of the
given argument, |
void insertElementAt |
Inserts the specified object as a
component in this |
boolean isEmpty() |
Tests if this vector has no components. |
Object lastElement( ) |
Returns the last component of the vector. |
int lastIndexOf(Object elem) |
Returns the index of the last occurrence
of the |
int lastIndexOf |
Searches backwards for the specified
object, starting |
Object remove(int index) |
Removes the element at the specified
position in this |
boolean remove(Object o) |
Removes the first occurrence of the
specified element |
boolean removeAll |
Removes from this Vector all of its
elements that are |
void removeAllElements() |
Removes all components from this vector
and |
boolean removeElement |
Removes the first (lowest-indexed)
occurrence of |
void removeElementAt |
Deletes the component at the specified index. |
protected void removeRange |
Removes from this List all of the
elements whose index |
boolean retainAll |
Retains only the elements in this Vector that
are |
Object set |
Replaces the element at the specified
position in this |
void setElementAt |
Sets the component at the specified index
of this |
void setSize(int newSize) |
Sets the size of this vector. |
int size() |
Returns the number of components in this vector. |
List subList |
Returns a view of the portion of this
List between |
Object[] toArray() |
Returns an array containing all of the
elements in |
Object[] toArray(Object[] a) |
Returns an array containing all of the
elements in |
String toString() |
Returns a string representation of this
Vector, |
void trimToSize( ) |
Trims the capacity of this vector to be
the vector's |
Self Test Self Test With Answers
1) Pick the
incorrect statement. Constructors are unlike methods in that they
have
a) no return type
b) are named after the class
c) use round braces for arguments
d) cannot be abstract
2)
If used inside one of the constructors of a class called Cat
which
of the following would the constructor this( 1.1, 2.2 ) call?
a ) Cat (double x,
double y ) { /* */ }
b) Cat( int j, int k ) { /* */ }
c)
Cat( ) { /* */ }
d) Cat ( float u, int p ) { /*
*/ }
3) What will the
following print out? Select the correct answer.
String
x1 = "X";
String x2 = "X";
if (x1.equals(x2))
System.out.println( "Positive")
else
System.out.println("Negative")
a
) Positive
b ) Negative
4) What will the
following print out? Select the correct answer.
String
x1 = "X";
String x2 = "X";
if
(x1==x2)
System.out.println(
"Positive")
else
System.out.println("Negative")
a
)
b)
// Note: Will not have Math questions on final exam as was covered in earlier course
5) One of the following is not a valid wrapper class. Which is it?
a)
Float
b) Int
c)
Double
d) Long
6) Which of the following statements is not correct?
a)
The math class itself is final so can only be extended once
b) Math's constructor is private so it
cannot be instantiated.
c) Math
methods and constants are static
d)
Math methods are only accessible through the Math class name
7)
Math.floor(44.4) returns
a) 45
b) 45.0
c)
44
d) 44.0
8) Which of the following is not in the java lang package
a)
Vector
b) Boolean
c)
Math
d) String
9 ) Which of the following statements is not correct?
a)
The number of objects added may exceed the capacity.
b)
The no-args Vector constructor defaults to an initial capacity set to
5.
c) To return an element to it's
original type typically requires a cast.
d)
Vector can throw an exception is an element index is addressed
higher than the number
of elements that have been added to the
Vector.
Exercise
Using Constructors
1 ) Create a parent
class with three different constructors. Include one no arg
constructor. The other two constructors will be overloaded and
takes different
arguments, distinguished either by type, number
or order.
In a child class
constructor invoke one of the parent constructors that takes
arguments
using the keyword 'super'. Then in the child, use the
'this' keyword in another constructor
to invoke the constructor
that has used the super keyword. Add some symbolic accessory
features to the second constructor, even just comments or actions
represented by
System.out.println statements.
Using
Lang Classes
2) Create a class that
takes a name in at the command line. Use methods of the String
class
to convert the name to uppercase and pre- and postfix the name
with exclamation
marks. Then write to the command line the
'dressed' name in conjunction with a statement
something like
"!!! BOB !!! You have won a new car!"
3) Create two
wrapper classes that store a height and width of a right angled
triangle.
Pass
these values in at the command line when the program is invoked.
Store these
two
classes in a Vector. Access the Vector elements and retrieve the
wrapped values.
Figure
out the hypotenuse using Math methods and store this value in another
wrapper
class.
Access the third wrapper class and write the three values in a
statement to
screen.
(i.e. A triangle with a width of ___ and a height of ____ has a
hypontenuse
value
of ______ )
//
it would be tempting to just store the final value in the Vector but
for exercise
//
we take the long way around and store the two entered values in the
Vector
//
before accessing them to compute the hypotenuse.
PS.
If you forgot the Pythagorean theorem, it states that the sum of the
squares of
of
the sides of a right angled triangle is equal to the square of
the hypotenuse.
A 2
= B 2
+
C 2
Optional Approaches
Using Command Line IO
You can use the
String[] supplied by main to enter values to your program. There
are
a couple examples of this technique shown in the above note. This
functionality
would
typically be used to configure your application. For instance,
if your program
was
creating a net connection, you could enter a port number other than
the default.
You
may wish to use an 'inline' approach based classes in the io package
as in the
following
partial excerpt. Either way is good to practice. The following code
is pretty
primitive.
Making it more sophisticated has the disadvantage of making it
complex.
It does
show a formula for entering values at the command line.
import
java.io.*;
class AverageTwoNumbers
{
public static void main(String[]args)
{
String value = "";
int sum = 0;
int average = 0;
BufferedReader in = new
BufferedReader
(new
InputStreamReader(System.in));
System.out.println( " Enter a mark " );
try{
value =
in.readLine( );
int
holding = 0;
try{
holding = Integer.parseInt(value);
sum = sum + holding;
}
catch(NumberFormatException ne){
System.out.println( "Your number was not well
formed");
}
System.out.println(
"You have entered: " + value);
System.out.println(" Type in another value ");
value = in.readLine(
);
try{
holding = Integer.parseInt(value);
sum = sum + holding;
}
catch(NumberFormatException ne){
System.out.println( "Your number was not well formed. Run
again.");
return;
}
average = sum /2;
System.out.println("The average of the two numbers is: " +
average);
}
catch(IOException io){System.out.println("IOException
thrown");}
}
}
Using
JOptionPane
You
can also use the handy JOptionPane to do IO at the keyboard.
JOptionPane supplies
a handy lightweight GUI for entering and displaying data. Followng is
sample code showing
JOptionPane being used. The Double wrapper class is also used. To add a
degree of
robustness, we add exception catching for NumberFormatException.
JOptionPane Sample Code
import javax.swing.*;
public class
LightGUI {
public static
void main(String[]args){
try{
double
base;
double
height;
String
baseInput = JOptionPane.showInputDialog("What is the length of the base
of the triangle?");
base =
Double.parseDouble(baseInput);
String
heightInput = JOptionPane.showInputDialog("And what is the height of
the triangle?");
height =
Double.parseDouble(heightInput);
double
areaTriangle = base * height / 2 ;
JOptionPane.showMessageDialog(null, "The area of your triangle is " +
areaTriangle);
}
catch(NumberFormatException
nfe){
JOptionPane.showMessageDialog(null,
"Your number is too large or incorrectly formatted.");
}
System.exit(0);
}
}