Você está na página 1de 13

8966480.

doc FBE – Computer Science Dept

Mekelle University Faculty of Business & Economics

Computer Science Department

Comp 262: Internet Programming with Java

Handout 6 – Objects and some useful Java Classes

Reference:
For more information on the material covered in this handout, you should take some
time to look at the Sun Java Tutorial, for which there is a link on the intranet, under
the materials listing for this course. See in particular the topics 'Object Basics and
Simple Data Objects', under 'Learning the Java Language'. See also the 'Collections'
topic, under 'Specialized Trails'. Some of the code examples in this handout are taken
from this tutorial.

1 Overview
This handout covers some important information about the life cycle of objects
(garbage collection and finalisers) and also briefly describes some useful built-in Java
classes (for working with strings and collections).

2 Memory Management in Java (Garbage Collection)


Unlike other languages, such as C, objects do not have to be explicitly destroyed in
Java. Because of this, management of memory resources is less of a problem in Java
and memory leaks1 are less likely to occur.

This is because Java automatically carries out a process called garbage collection.
An object becomes eligible for garbage collection when there are no longer any
references to it.
References held in a variable are usually dropped when the variable goes out of scope.
It is also possible to explicitly drop an object reference in code by setting the variable
to the special value null.

The Java interpreter keeps track of objects and arrays that it allocates to memory
addresses. It also tracks the objects and arrays that local variables refer to and what
objects and arrays refer to other objects and arrays.

Because it tracks all this information, the interpreter can determine when an allocated
object is no longer referred to by any other object or variable.

When the interpreter finds an object that is no longer referenced by any other object
or variable, it can safely destroy the object and release any resources used by the
object. It can also detect where there is a circular reference between objects not
referenced anywhere else i.e. where object A refers to object B and object B refers to
object A and destroy those objects.

1
A memory leak occurs when memory is allocated and never reclaimed. Many memory leaks in a
program could lead to worsening performance.

Page 1 of 13
8966480.doc FBE – Computer Science Dept

The garbage collector runs in the background – doing most of its work when other
processes are not using system resources. This means that the process of garbage
collection does not generally slow down the system.

It is possible to explicitly run the garbage collector e.g. after a piece of code that is
known to create a large amount of garbage. It can be run by calling the gc method of
the System class.

3 Finalizers
The Java garbage collector is efficient and is usually sufficient to ensure that all
allocated resources are released back to the system.
However, there are some resources that are not automatically released by the garbage
collector. These are resources that are outside the control of Java, for example if an
object opens a file or a network connection.
In these cases, it is necessary to explicitly release the resources in the code.
This is done using a finalizer method (which is similar to a destructor in C++).

The finalizer method takes no arguments and does not return a value. Finalizer
methods are usually declared protected but can also be public.

Every object inherits a standard finalize method from the Object super class. If a class
needs to explicitly release resources, it overrides this method and should call
super.finalize() as part of the implementation, to ensure that the Object.finalize()
method is eventually called.
For example, a class that may have created a text file that is used only by this class
should delete the file when it is finished. The finalizer method for this class might
look like the following.

protected void finalize() {


super.finalize();

/*assume this class created a temporary text file, which was


referenced by the variable theFile. The code should delete this
file rather than leaving it on the file system.
*/
theFile.delete();
}

You should note that generally, you do not need to worry about finalizer methods but
if your class deals with files or network objects, then it is necessary.

Note that the finalizer method is invoked at some time after the object becomes
unused (i.e. no references remain to the object) but before the garbage collector
destroys the object.

4 Some Useful Classes


This section covers a few useful classes from the java.lang and java.util packages.
You will come across many different classes as you look at code examples provided in
the labs. These are just some classes that you will find useful and easy to use at this
stage.

Page 2 of 13
8966480.doc FBE – Computer Science Dept

4.1 java.lang.String / java.lang.StringBuffer


The String class represents a read-only string of characters. Any time the Java
compiler encounters a string in double quotes, a String object is created. This means
that it is not necessary to explicitly call the String constructor. So, for example

String s = "13 Months of Sunshine";


Is the same as
String s = new String ("13 Months of Sunshine");

Both result in a new string object containing the characters '13 Months of Sunshine'
being created.

String objects are immutable – that is, once a String object is created, it does not
change. If you assign a different set of characters to a variable of type String, a new
object is created. The String object is not very efficient for working with changing
strings.

The StringBuffer class represents a string of characters that can change i.e. the
characters can be changed, added to and removed from the string. Therefore it is said
that a StringBuffer is mutable.
If you are writing code that needs to manipulate the data in a string e.g. adding more
characters to a string, changing the order of the characters, then you should use a
StringBuffer as it is more efficient (using the String class would result in more objects
being allocated to memory).
The StringBuffer class has different constructors – one that takes a string value and
one that takes an integer value that specifies the length i.e. the number of characters
the object can hold. The signatures for these constructors are as follows:

public StringBuffer (String str)


public StringBuffer (int length)

It is better to specify the length of the object if possible, or at least to provide a


reasonable estimate of the length of it. This minimises the number of times memory
must be allocated for the object.
If the second of the above constructors is used, strings can be placed into the
StringBuffer using the append method. For example:

StringBuffer msg = new StringBuffer (100);


String username;
//omitted code – get the user name from input

msg.append ("Welcome, ");


msg.append (username);
msg.append (", to the game!");
System.out.println (msg);

The table below lists some useful methods on String and StringBuffer classes.

Method Class Description


length() String, StringBuffer Returns the number of characters in the object
capacity() StringBuffer Returns the number of character spaces that

Page 3 of 13
8966480.doc FBE – Computer Science Dept

have been allocated for the object – may be


greater than the length of the object.
charAt(int index) String, StringBuffer Returns the character at position index (the
string is a 0-based array of characters so the
first character is at index 0).
subString(int String, StringBuffer Returns a string that consists of the characters
startIndex, int from (and including) the specified startIndex up
endIndex) to (but not including) the specified endIndex.
subString(int
startIndex)
indexOf(String String, StringBuffer Returns the index (in the array of characters) of
str) the first occurrence of the specified string in the
string, searching from the beginning of the
string.
The parameter can also be a single character.
Returns –1 if it is not found.
lastIndexOf(String String, StringBuffer Returns the index (in the array of characters) of
str) the first occurrence of the specified string in the
string, searching from the end of the string.
The parameter can also be a single character.
Returns –1 if it is not found.
insert(int offset, StringBuffer Inserts the string str into the string at the
String str) position after offset.
The parameter value to insert can also be an
Object or a primitive data type – it is converted
to a string before inserting.
append (String str) StringBuffer Adds the string str to the end of the string.
The parameter can also be an Object or a
primitive data type – it is converted to a string
before appending.
setCharAt(int StringBuffer Replaces the character at position index with
index, char ch) the character ch

toUpperCase() String Converts all characters in the string to upper


case
toLowerCase() String Converts all characters in the string to lower
case

4.1.1 Comparing Strings

The comparison operator for equality is = =. However, when used with reference data
types, this tests whether the operands refer to the same object or array. When used
with primitive data types, it tests whether the operand values themselves are identical.
Using = = with strings can lead to unexpected results.

To compare the actual characters of String objects, the equals() method of the String
class should be used. For example:

String string1 = "a string";


String string2 = "a string";

//to compare the strings


boolean areTheyEqual = string1.equals (string2);

Page 4 of 13
8966480.doc FBE – Computer Science Dept

See the class DemoEquality in Code Examples\Demos for an example showing where
= = returns an unexpected result for two strings that contain the same characters.

4.1.2 Converting Objects to Strings

All Java objects have a method toString(), inherited from the super class Object, that
converts the object to a string representation. For example, to convert a StringBuffer
to a String:

StringBuffer msg = new StringBuffer ("This is a message");


//if the class has a method displayMsg(String msg) that requires a
String parameter, need to convert to a String
displayMsg (msg.toString());

For many objects, the default string representation is not very meaningful – it may
consist of an internal identifier assigned by the Java interpreter. Many classes in the
java.lang package override toString() to provide more meaningful representations e.g.
the Exception classes and the wrapper classes for the primitive data types (Boolean,
Character, Integer etc)
You can override the toString() method on your classes also, which can be useful for
passing references as String parameters or for debugging.

Note: when the System.out.print or System.out.println method is called, the parameter


can be an object, rather than a string. If the parameter is an object, then the toString()
method that object is automatically invoked and the returned string is what is printed
to the output.

The String class also has a class (static) method valueOf() that can be used to convert
variables of different types to strings. For example, to print the value of pi:

System.out.println(String.valueOf(Math.PI));

4.2 java.util.StringTokenizer
The StringTokenizer class can be used to break a string of text into the words that
make up the text. The default behaviour is for the tokenizer to separate words at space
characters. It can be set to look for a different separator character e.g. a colon.

A tokenizer is often required to parse entered data e.g. a program that accepts
commands from the input needs to be able to parse the command string.

String aString = "13 Months of Sunshine";


java.util.StringTokenizer st = new
java.util.StringTokenizer(aString);

//use the hasMoreTokens method to check for there being another


token
while (st.hasMoreTokens() ) {
//nextToken returns a String
System.out.println (st.nextToken());
}

Page 5 of 13
8966480.doc FBE – Computer Science Dept

The above program would output each token on a new line, like this:
13
Months
of
Sunshine

4.3 Collections
Java has a number of classes that can be used when working with collections of
objects. These are the Collection classes; they are all part of the java.util package.
A collection can hold an arbitrary number of elements, with each element being
another object.
There are various collection objects that provide different types of functionality, such
as storing the objects in order, sorting and preventing duplicate entries.
The elements in a collection are zero-index based i.e. the first element is always at
index 0.

There are a number of different collection interfaces that can be implemented by


classes. The Collection interface is at the top of the class hierarchy. The List and Set
interfaces extend the Collection interface. Most collection classes implement the List
or Set interfaces, and some implement the Map interface. These are all described
below.

The Collection interface represents a general collection of objects. Generally, we use


one of the sub-interfaces, List and Set as they provide more functionality. The
diagram below shows the various collection interfaces available (from Java 1.3). The
Set and List interfaces extend the Collection interface; SortedSet extends Set. Map is
a separate interface but is part of the Collections framework of Java, so it is also
discussed here. The SortedMap interface extends the Map interface.

Figure 1 – the hierarchy of Collection interfaces in Java

The List interface represents an ordered collection of objects – each element in a List
has an index, or position, in the list. When elements are inserted into the List, the

Page 6 of 13
8966480.doc FBE – Computer Science Dept

order of the elements is maintained in the List – when the elements are returned from
the List, they are in the same order in which they were added into it. Elements can be
inserted, queried and removed by index.

The Set interface represents an unordered collection of objects that contains no


duplicate elements - i.e. two elements that are references to the same object cannot be
placed in the Set (if element1.equals(element2), they are duplicates). The order of the
elements in the set can change i.e. it is not fixed – when the elements are returned
from the set, they may be in a different order from when they were added into it. A Set
can contain at most one null element (because it cannot contain duplicate objects – a
null is a duplicate of another null).
The SortedSet interface extends Set and provides a way of ordering the set.

Another interface, Map, does not extend the Collection interface but is another class
often used for handling collections of objects. Each item in a Map consists of two
objects - a key object and a value object. Items in a Map can be referenced by their
key values. The set of key objects in a Map cannot contain duplicates, but the value
objects can. Each key object can map to at most one value object.
An example of a map is a list of names and phone numbers. When you want to find a
phone number, you look up the name in a phone book and then read the number for
that name.

The SortedMap interface extends the Map interface and keeps its set of key objects
in sorted order.

The Iterator interface defines methods for iterating (looping) through a collection
from the first element to the last element. Any class that implements the Collection
interface (or one of its sub-interfaces) implements an iterator() method that returns an
iterator for that collection. The iterator can be used to loop through all the elements in
the collection.
Methods on an Iterator object are shown in the table below.

Method Description
hasNext() Returns true if there is another element in the collection
next() Returns the next object (element) in the collection
remove() Deletes from the collection the last item that was returned using next()

4.3.1 A List Class: java.util.ArrayList

In earlier versions of Java (prior to 1.2), the Vector class provided similar
functionality to an ArrayList. Vector may still be used, but generally, an ArrayList is
better.
The ArrayList class is an implementation of the List interface, so it inherits various
methods from the interface and implements them. Objects of any class can be placed
into an ArrayList.
Unlike an array, the type of objects that will be placed into the ArrayList does not
have to be declared, and the object types can be different.

Page 7 of 13
8966480.doc FBE – Computer Science Dept

The constructor for an ArrayList can take no parameters, or it can take a value for the
capacity (how many elements it can hold) of the ArrayList or it can take another
Collection object.
If the capacity is not specifed, the ArrayList will grow automatically as new elements
are added. However, this means that a new array to hold the values is created when it
is grown. Therefore, it is more efficient to specify the capacity if it is known.

ArrayList items = new ArrayList(); //ArrayList with unknown capacity

ArrayList items2 = new ArrayList (100); //ArrayList that will hold


up to 100 items

Useful methods on the ArrayList class are shown below. The column 'Inherited From'
shows which methods are inherited from the Collection interface and which from the
List interface. Methods inherited from the Collection interface are also available on
classes that implement the Set interface, as Set extends Collection also.
Note that because a List is ordered, elements can be referenced by their position in the
collection i.e. by index e.g. set(), get(), remove() methods can all take an index value
as a parameter. This is not possible with a Set.

Method Description Inherited from


add(Object element) Adds the given object element to Collection
the ArrayList
set(int index, Object element) Sets the object at position index to List
be the given element (replacing
any object that was there
previously)
get(int index) Returns the object that is a List
position index in the ArrayList.
remove(int index) Removes the object at position Collection
index, returning that object.
remove (Object o) Removes the object o from the
ArrayList, returning a boolean.
size() Returns the number of elements Collection
in the ArrayList
indexOf(Object element) Returns the index of the first List
occurrence in the ArrayList of the
object element
lastIndexOf (Object element) Returns the index of the last List
occurrence in the ArrayList of the
object element
contains(Object o) Returns true if the ArrayList Collection
contains the specified object o
toArray() Returns an array containing all Collection
the objects in the ArrayList – this
is useful if you need to pass the
collection of objects to some
other method, as an array can be
more efficient
isEmpty() Returns true if the ArrayList is Collection
empty i.e. if it has no elements in
it
iterator() Returns an Iterator object for the Collection
collection; as a List is ordered, the
order of the elements in the
iterator is the same as the order in

Page 8 of 13
8966480.doc FBE – Computer Science Dept

which they were added.

For example, to create an ArrayList named items and to add an object (from some
class, let us call it SomeClass – its declaration is not shown here) as the first element:

ArrayList items = new ArrayList(); //ArrayList with unknown capacity


SomeClass obj1 = new SomeClass();
SomeClass obj2 = new SomeClass();

items.add (obj1); //add an object to the list


items.add ("another name"); //add another object to the list

To use an iterator to loop through all the elements in the list:

//the termination condition in the for loop is if the Iterator has


//not got another element
for(Iterator iter = items.iterator(); iter.hasNext(); )
{
Object item = iter.next();
//do something e.g. print out
System.out.println (item);
}

Note that in the iteration above, the type declared for the item variable is Object – this
should be used if there are different types of object in the array. However, if the
objects are all of the same type i.e. from the same class or super class, then that type
can be used. Remember also that System.out.println will invoke the toString() method
of the item parameter if it is not a String object.

4.3.2 A Set Class: java.util.HashSet

The HashSet class is an implementation of the Set interface. Any type of object can be
added to a HashSet and null objects can also be added.
Unlike the ArrayList, it does not allow duplicate elements i.e. two objects that are the
same. The add(Object o) method returns a boolean – true if the object is successfully
added, false if not (because the object already exists in the set).
As a Set is an unordered collection, the order in which the items in the set are returned
by the iterator() method may not be the same as the order in which the objects were
added.

Some of the methods of the HashSet class are shown in the table below. The interface
from which they are inherited is also shown. Note that the methods inherited from the
Set interface implement the standard mathematical set operations such as union,
intersection, subset and difference.

Method Description Inherited from


add(Object o) Adds the given object o to the Collection
HashSet; returns true if added,
false if not (not added if a
duplicate object already exists)
remove (Object o) Removes the object o from the Collection
HashSet, returning a boolean.
size() Returns the number of elements Collection

Page 9 of 13
8966480.doc FBE – Computer Science Dept

in the HashSet
contains(Object o) Returns true if the HashSet Collection
contains the specified object o
toArray() Returns an array containing all Collection
the objects in the HashSet – this is
useful if you need to pass the
collection of objects to some
other method, as an array can be
more efficient
isEmpty() Returns true if the HashSet is Collection
empty i.e. if it has no elements in
it
iterator() Returns an Iterator object for the Collection
collection; as a List is ordered, the
order of the elements in the
iterator is the same as the order in
which they were added.
containsAll (Collection c) Returns true if the HashSet Set
contains all the objects in c i.e. if
c is a subset of the HashSet
addAll(Collection c) Adds the objects in c to the Set
HashSet but does not add
duplicates i.e. performs set union
retainAll (Collection c) Retains in the HashSet only those Set
objects that are also in c i.e.
performs a set intersection
removeAll (Collection c) Removes from the HashSet any Set
objects that are in c i.e. performs
a set difference

The two examples below show some of the set methods in use on a HashSet object.
Note that this code declares the variable to be of the type Set (an interface) but creates
an object from the HashSet class (e.g. Set s = new HashSet()). Because HashSet
inherits from, or implements, Set, this is allowed. In this case, Set is the static type of
the variable and HashSet is the dynamic type of the variable.

Using the interface type (Set) as the variable type is a good idea because it allows the
programmer to change the implementation type from HashSet to some other
implementation of Set later on, if necessary.

Example 1 – using the add() method – run this class with a set of words on the
command line – it detects any duplicate words:

import java.util.*;

public class FindDups {


public static void main(String args[]) {
Set s = new HashSet();
for (int i=0; i<args.length; i++)
if (!s.add(args[i]))
System.out.println("Duplicate detected: "+args[i]);

System.out.println(s.size()+" distinct words detected: "+s);


}
}

Page 10 of 13
8966480.doc FBE – Computer Science Dept

Example 2 – uses the removeAll set operation to get set difference:

import java.util.*;

public class FindDups2 {


public static void main(String args[]) {
Set uniques = new HashSet();
Set dups = new HashSet();

for (int i=0; i<args.length; i++)


if (!uniques.add(args[i]))
dups.add(args[i]);

uniques.removeAll(dups); // Destructive set-difference

System.out.println("Unique words: " + uniques);


System.out.println("Duplicate words: " + dups);
}
}

4.3.3 A Map Class: java.util.HashMap

The HashMap class is an implementation of the Map interface. Java uses an internal
hashtable to store a hashmap. A key-value pair is added to a Map using the put()
method; the get() method returns the value object for a given key.
The Map interface provides three views that return different Collections – keySet,
values and entrySet – these can be used to iterate through the keys and/or the values.

The existence of a given key or value can be checked for using the containsKey() and
containsValue() methods.

Method Description Inherited From


put(Object key, Object Adds a key-value pair into the HashMap Set
value)
get (Object key) Returns the value object corresponding to key Set
remove(Object key) Removes the key-value pair for key Set
keySet() Returns a Set object containing all the keys in Set
the HashMap
values() Returns a Collection object containing all the Set
key values in the HashMap – it is not a Set
because multiple keys can map to the same
value
entrySet() Returns a Set object containing all the key-value Set
pairs in the HashMap
size() Returns the number of key-value pairs in the Set
HashMap
isEmpty() Returns true if the HashMap has no key-value Set
pairs in it
containsKey(Object key) Returns true if the key set contains key Set
containsValue(Object Returns true if the values set contains value Set
value)

A list of names and phone numbers is an example that can be implemented as a


HashMap.

Page 11 of 13
8966480.doc FBE – Computer Science Dept

See Code Examples\Demos\DemoHashMap.java for an example.

4.3.4 Collections Class

The Collections class defines various static methods and constants that are useful for
working with collections, for example methods to sort a collection.
See the DemoHashMap class for an example of usage of the Collections.sort()
method.

Method Description
Collections.sort Sorts the list object. This sort uses the natural order of the objects. For
(java.util.list list) strings, this is alphabetical, for numerical values it is the numerical
order.

For other classes, the class must implement the java.lang.Comparable


interface; this interface has one method, compareTo(Object o) that
must be implemented in the class. The compareTo method compares
the object to the given object O and returns a negative integer if the
object is 'less than' the object o; a positive integer if it is 'greater than'
the object o and 0 if they are 'equal'.
For example, for a CD class, the compareTo method might
alphabetically compare the Artist and then the CD Title values.
Collections.sort This sort method sorts using the supplied Comparator.
(java.util.list list, java.util.Comparator is an interface that can be used to specify the
Comparator c) ordering for a set of objects. It can be used to override the natural
ordering of the class or to specify an order other than that defined by
the Comparable interface.
Collections.max(Collection Returns the maximum object in the collection – based on the natural
coll) order.
Collections.max(Collection Returns the maximum object in the collection – based on the specified
coll, Comparator comp) Comparator.
Collections.min(Collection Returns the minimum object in the collection – based on the natural
coll) order.
Collections.min(Collection Returns the minimum object in the collection – based on the specified
coll, Comparator comp) Comparator.
Collections.shuffle Shuffles the items in a list i.e. puts them into random order. Useful if a
(java.util.List list) list has been sorted but subsequently needs to be in random order. This
is useful in games of chance.

4.4 java.util.Random
The Random class, part of the java.util package, is a class that can be used to generate
random numbers. Some of the methods on this class are shown below.

Method Description
Random() Constructor
nextInt() Returns a random integer value
nextInt(int n) Returns a random integer value between 0 and n (>=0, < n)
nextLong() Returns a random long value
nextBoolean() Returns a random boolean value

If you need to generate random numbers in a program, create one instance of the
Random class and use it each time you need to generate a number. If you create a new
instance each time, the numbers may not be very random.

Page 12 of 13
8966480.doc FBE – Computer Science Dept

For example:

Random randomGenerator;
randomGenerator = new Random();
int theNumber = randomGenerator.nextInt();
//use theNumber
………
//generate another random number
theNumber = randomGenerator.nextInt();

4.4.1 Random and pseudo-random

The implementation of the Random class in Java uses an algorithm that generates
pseudo-random numbers. This means that they are not truly random. This is because it
is difficult to generate truly random numbers on a computer – because computers
work in a way that is very well-defined and deterministic.
The algorithms often used to generate random numbers actually follow rules, but the
rules are very complicated. Unless you are working on a program that requires
extremely high security, the Random class should produce sufficiently random
numbers for you!

Notes prepared by: FBE Computer Science Department.

Page 13 of 13

Você também pode gostar