SDSU CS 596 Java Programming
Fall Semester, 1998
Some JDK 1.1 API
To Lecture Notes Index
© 1998, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 05-Oct-98

Contents of Doc 10, Some JDK 1.1 API


References


The Java Programming Language , 2 nd Ed. Chapter 12

Java in a Nutshell , 2 nd Edition, Flanagan, page 236

On-Line Java API documentation



Listen Here!S-sept30 4mins Doc 10, Some JDK 1.1 API Slide # 2

Containers

The Container Problem

Containers, like linked list, are independent of the data type they contain.

How to build a container class that holds any type?


C++/Ada Solution - Templates (Generic)

The C++/Ada solution to uses compile time type variables. In the example below the <class DataType> is a special type of parameter. You provide, at compile time, a type in place of "DataType" as is shown below.

template <class DataType>
class LinkedListNode
{
   DataType   theData;
   LinkedListNode* link;
   // more code here
}
void main( //blah)
{
   LinkedListNode<int> SampleNode;
}

Listen Here!S-sept30 1min Doc 10, Some JDK 1.1 API Slide # 3
Java/Smalltalk Solution
Make class "Object" the ancestor of all classes. This means all classes are a subtype of Object. Therefore, a field of type "Object" can hold a reference to any object. There are two important results of using a reference of type object. First, when one removes an object from a reference of type "Object", one has to cast the object to its actual type, as is done below with the Student object. Second, a container (like a linked list) can hold many different types of objects in the same container at the same time. Depending on your point of view this is either "very good" or "very bad".

class LinkedListNode
{
   Object   theData;
   LinkedListNode link;
}

class Student
{
   String  name;
}

class UseLinkedListNode 
{
   public static void main( String args[] ) 
   {
      LinkedListNode  aNode  = new LinkedListNode();
      Student  junior  =  new Student();
      aNode.theData  =  junior;
      Student senior  =  (Student) aNode.theData;
      LinkedListNode  aNumNode  = new LinkedListNode();
      aNumNode.theData  =  5;  //compile error, 
                            // 5 not an object
      aNode.link  =  aNumNode;
   }
}

Listen Here!S-sept30 2mins Doc 10, Some JDK 1.1 API Slide # 4

Numeric Classes



Why Numeric Classes?

“The numeric classes provide an object wrapper for numeric data values and serves as a place for numeric-oriented operations. A wrapper is useful because most of Java's utility classes require the use of objects. Since int, long, float and double are not objects in Java, they need to be wrapped in a class instance.”
Smalltalk avoids the need for wrapper classes by making numbers objects. Java did not go this route for several reasons. First, to maintain consistency with C. Second, for performance reasons. Third, there are some problems with precedence in Smalltalk's solution.

Listen Here!S-sept30 6mins, Q-oct1 6mins Doc 10, Some JDK 1.1 API Slide # 5
Numeric Classes Example

class NumericClassesExample 
{
   public static void main( String args[] ) 
   {
      Integer  height  =  new Integer( 10 );
      Integer  width  =  new Integer( 25 );
      Integer  depth  =  25;            // Compile error
      Integer area;
      area =  height * width;            // Compile error
      area =  new Integer(height.intValue() * width.intValue() );
      System.out.println(  area  );
      String  areaAsString  =  area.toString();
      int areaAsInt  =  area.intValue();
      long areaAsLong  =  area.longValue();
      System.out.println(  Integer.MAX_VALUE  );
   }
}

Doc 10, Some JDK 1.1 API Slide # 6
Some (not all) Numeric Operations

ClassIntegerLong
VariablesMAX_VALUEMAX_VALUE
MIN_VALUEMIN_VALUE
ConstructorsInteger(int)Long(long)
Integer(String)Long(String)
MethodsdoubleValue()doubleValue()
equals(Object)equals(Object)
floatValue()floatValue()
intValue()intValue()
longValue()longValue()
toString()toString()
valueOf(String)valueOf(String)


Listen Here!S-sept30 2mins Doc 10, Some JDK 1.1 API Slide # 7
Some Translation of Numbers
This example shows how to convert ints and floats to binary bits and hex representation. The method floatToIntBits returns an int representation of the float according to the IEEE 754 floating-point "single precision" bit layout. Bit 31 (numbered from right to left - so the left most bit is bit 31) represents the sign of the floating-point number. Bits 30-23 represent the exponent. Bits 22-0 represent the significand (sometimes called the mantissa) of the floating-point number.

public class Test {
   public static void main( String args[] ) throws Exception {
   
      int intSample = 4;
      String intSampleBits = Integer.toBinaryString( intSample );
      String intSampleHex = Integer.toHexString( intSample );
      System.out.println("" + intSample + " in bits " + intSampleBits );
      System.out.println("" + intSample + " in Hex " + intSampleHex);
      floatSample = 4.4F;
      floatSampleBits = 
         Integer.toBinaryString( Float.floatToIntBits( floatSample ));
      floatSampleHex = 
         Integer.toHexString( Float.floatToIntBits( floatSample ));
      System.out.println("" + floatSample + " in bits " + 
                                    floatSampleBits);
   }
}
Output
4 in bits 100
4 in Hex 4
4.4 in bits 1000000100011001100110011001101

Listen Here!S-sept30 7mins, Q-oct1 4mins Doc 10, Some JDK 1.1 API Slide # 8

java.util.Vector

Vector is an array that grows larger when needed. Since a vector is an object, we can not use the standard array "[index]" to access an element in the vector. Use "elementAt(index)" to access an existing element in the vector. This does not remove the element. Use "setElementAt (object, index)" to replace an existing element at the index with the given object. Indexing starts at zero. "new Vector()" creates vector with default capacity. "new Vector( K )" creates vector with capacity K. A vector's capacity refers to the number of elements the vector can hold, not the number of elements in the vector. "addElement(objectReference)",when sent to a vector object, adds the given object after the last element in the vector. Since the vector stores elements as object references: 1) you must wrap numbers in an object 2) when you remove the item from the vector need to cast it to its actual type. Both are shown below.

import java.util.Vector;
class SampleVector 
{
   public static void main( String args[] ) 
   {
      Vector  growableList  =  new Vector( 2 );
      String  myName  =  "Roger";
      growableList.addElement(  myName   );
      growableList.addElement(  new Float( 12.3F) );
      System.out.println(  growableList.toString()  );
      for ( int k = 0;  k < 500;  k++ )
         growableList.addElement(  new Integer( k )  );
      growableList.setElementAt(  "Hi",  2  );
      String  convert  = (String) growableList.elementAt( 2 );
      growableList.removeElementAt(  5  );
      System.out.println(  growableList.indexOf(  myName  )  );
   }
}
Output
[Roger, 12.3]
0

Listen Here!S-sept30 3mins, Q-oct1 7mins Doc 10, Some JDK 1.1 API Slide # 9
Beware! Vector setElementAt may not Mean What You Think!
You can only use setElementAt( object, index) to change an existing element of the vector. In the first example below, although we create a vector with the space or capacity for 200 elements, it does not contain any elements. "empty.setElementAt( "No one home", 2 );" then tries to access an element of the vector that has not been assigned to yet. This causes a runtime error.

import java.util.Vector;
class DoesNotWork  {
   public static void main( String args[] )  {
      Vector  empty  =  new Vector( 200 );
      empty.setElementAt( "No one home", 2 );
   }
}
Output
java.lang.ArrayIndexOutOfBoundsException: 2 >= 0
        at java.util.Vector.setElementAt(Vector.java)
        at DoesNotWork.main(All.java:8)
This Works with no Runtime Error
"setSize( K ) makes sure that the vector has K elements. If the vector does not have K elements already, it adds null elements until the vector has K elements.

import java.util.Vector;
class ThisWorks  {
   public static void main( String args[] )  {
      Vector  fillFirst  =  new Vector( );
      fillFirst.setSize( 200 );
      fillFirst.setElementAt( "Ok", 199 );
   }
}

Listen Here!S-sept30 6mins Doc 10, Some JDK 1.1 API Slide # 10

java.util.Enumeration


The Enumeration interface contains two methods that may be used to enumerate, or go through, a set of values. The enumeration is consumed by use; its values may only be counted once. The goal of an enumeration is to reduce the information one needs to go through a collection of items. Enumerations also give a uniform way to go through a collection. Enumerations have limitations; one can not traverse backwards. We will see later that JDK 1.2 iterators have more functionality than enumerations.


Enumeration Methods

hasMoreElements()
Returns true if the enumeration contains more elements; false if it's empty.
nextElement()
Returns the next element of the enumeration.

Listen Here!S-sept30 10mins, Q-oct1 4mins Doc 10, Some JDK 1.1 API Slide # 11
Vectors and Enumeration

This example shows how to get an enumeration from vector (with the elements() method). It shows how to use the enumeration. Note that the vector is changed after getting the enumeration. The change is reflected in elements from the enumeration.

import java.util.*;
class SampleVector 
{
   public static void main( String args[] ) 
   {
      Vector  monthyOutput  =  new Vector( );
      Random  dailyOutput  =  new Random();
      for ( int k = 0;  k < 4;  k++ )
         monthyOutput.addElement(  
                        new Integer(  dailyOutput.nextInt() ) );
      Enumeration  output  =  monthyOutput.elements();
      monthyOutput.setElementAt( "Hi Mom", 0);
      while ( output.hasMoreElements()   ) 
         System.out.print(  output.nextElement() + ", " );
      System.out.println(   );
   }
}
Output
Hi Mom, -2074956641, 593569866, 1475532102,

Listen Here!S-sept30 6mins, Q-oct1 7mins Doc 10, Some JDK 1.1 API Slide # 12

Implementing an Enumeration

This example shows how to implement an enumeration. The enumeration needs to keep track of the collection of elements it enumerates over and a reference to the current (or next) location in the collection. How this is done depends on the collection. In a tree structure one might keep a reference to the current node and information about how many times you have visited each node.
package whitney;
import java.util.Enumeration;
public class SimpleVector {
   Object[] elements = new Object[100];
   int elementCount = 0;
   
   public void addElement( Object element )    {
      elements[elementCount++] = element;
   }
   public Object elementAt( int index ) { return elements[ index ]; }
   
   public int size() {  return elementCount; }
   public Enumeration elements() {
      return new SimpleVectorEnumeration( this );
   }
}
class SimpleVectorEnumeration implements Enumeration {
   SimpleVector myVector;
   int nextElementIndex = 0;
   
   public SimpleVectorEnumeration( SimpleVector aVector ) {
      myVector = aVector;
   }
   
   public boolean hasMoreElements() {
      return nextElementIndex < myVector.size();
   }
   public Object nextElement() {
      return myVector.elementAt( nextElementIndex++ );
   }
}

Doc 10, Some JDK 1.1 API Slide # 13
Using the Enumeration

This is just to show you that the enumeration, defined on the last page, works. Note that a user of the SimpleVector does not know about SimpleVectorEnumeration, just Enumeration.

import java.util.Enumeration;
import whitney.SimpleVector;
public class Test {
   public static void main( String args[] ) throws Exception {
      SimpleVector  test  =  new SimpleVector( );
      test.addElement( "Hi" );
      test.addElement( "Dad" );
      test.addElement( new Integer( 5));
      Enumeration aList = test.elements();
      while ( aList.hasMoreElements() )
         System.out.println( aList.nextElement() );
      }
}
Output
Hi
Dad
5

Doc 10, Some JDK 1.1 API Slide # 14

java.util.Stack


Java has it own stack class. A Java stack holds references to objects. The operations on the stack are standard.

import  java.util.Stack;
class SampleStack 
{
   public static void main( String args[] ) 
   {
      Stack  test  =  new  Stack();
      test.push( new Integer( 5 ) );
      test.push( 5 );      //compile error - objects only
      test.push( new Student() );
      System.out.println( test.pop() );
      Student  fromStack  = (Student) test.pop();
   }
}

class Student
{
   public  String name;
}

Some Stack Methods
empty() 
peek() 
pop() 
push(Object) 
search(Object) 

Doc 10, Some JDK 1.1 API Slide # 15

java.util.Hashtable


One of the nice features of Java is that it has a Hashtable class. Sun violated its naming convention by calling the class Hashtable rather than HashTable. To place an item in a hash table one needs a key and a hash function to determine where the key belongs in the table. Any object can be used as a key in a Hashtable object. All objects inherit from the class "Object" the method hashCode(), which computes the hash function for that object. If the default hash function is not good enough for your application, override the hashCode(). In most cases the default hash function work well enough. If you do override the hashCode() you normally need to override the equals() method.

The example on the next slide shows how to perform some basic operations on a hash table.

Hashtable is your friend. Get to know it, and it will treat you very well.

Some Hashtable Methods
clear()get(Object)rehash()
clone()isEmpty()remove(Object)
contains(Object)keys()size()
containsKey(Object)put(Object, Object)toString()
elements()


Listen Here!Q-oct1 4mins Doc 10, Some JDK 1.1 API Slide # 16
Hashtable Example
This example shows adding items (use the put method), accessing the elements (use the get method), and getting the enumerations for the keys and the values in the hash table.

import  java.util.*;

class  Student {  String[]  courses;   }
class  SampleHash {
   public static void main( String args[] )  {
      Student  csPerson  =  new  Student();
      Hashtable sample = new Hashtable();
      sample.put( "Roger", "Good Job" );
      sample.put( "Mary", "Better Job" );
      sample.put( csPerson,  new Integer( 12 ) );
      String  myPerformance  = (String) sample.get( "Roger" );
      Enumeration  keys  =  sample.keys();
      while  ( keys.hasMoreElements()  ) {
         System.out.print(  keys.nextElement()  +  "\t" );
      }
      System.out.println();
      Enumeration  elements  =  sample.elements();
      while  ( elements.hasMoreElements()  ) {
         System.out.print(  elements.nextElement()  +  "\t" );
      }
      System.out.println();
      System.out.println( sample.containsKey( "Roger" ) );
   }
}
Output
Roger   Mary   Student@c4677b   
Good Job   Better Job   12   
true

Doc 10, Some JDK 1.1 API Slide # 17

java.util.Properties


The Properties class is a subclass of Hashtable. Properties are used to store/retrieve key-value (also called name-value pairs) pairs, where the keys and the values are strings. This class is heavily used to read/write configuration files in Java applications. This class is also used to store important system constants and pass key-value pairs from the command line to Java programs.

The next several slides will show some uses of the Properties class. Until we cover Java IO we can not show how to read/write configuration files.


Listen Here!Q-oct1 2mins Doc 10, Some JDK 1.1 API Slide # 18
Simple Property Example

getProperty( stringKey ) returns the string value stored at the given key or null if the key is not in the table.
getProperty( stringKey, defaultValue ) returns the string value stored at the given key, or defaultValue if the key is not in the table

import java.util.Properties;
public class Translate {
   public static void main( String args[] ) {
      Properties englishToGerman = new Properties();
      
      englishToGerman.put( "cat", "Katze" );
      englishToGerman.put( "dog", "Hund" );
      englishToGerman.put( "bird", "Vogel" );
      
      String noteNoCast = englishToGerman.getProperty( "dog" );
   
      String defaultValues = 
         englishToGerman.getProperty( "dog", "duh" );
      
      System.out.println( 
         englishToGerman.getProperty( "dog", "duh" ) );
      System.out.println( 
         englishToGerman.getProperty( "child", "duh" ) );
   }
}
Output
Hund
duh

Doc 10, Some JDK 1.1 API Slide # 19
More Default Options

You can provide a Properties object (englishToSpanish below) in the constructor of another Properties object (translator). This provides a set of default values for the new Properties object. Therefore, englishToSpanish contains the default values for the translator object. That means that when you ask for a value with getProperty( stringKey), if the translator object does not contain the key, then it will search the englishToSpanish object for the key. If englishToSpanish has the key, then its value is returned. If neither objects have the key, then null is returned. With getProperty( stringKey, defaultValue ), first the translator object is searched, then the englishToSpanish. If the key is not found then return the given defaultValue.

import java.util.Properties;
public class Test {
   public static void main( String args[] ) {
      Properties englishToSpanish = new Properties();
      
      englishToSpanish.put( "cat", "gato" );
      englishToSpanish.put( "mouse", "raton" );
      Properties translator = new Properties( englishToSpanish );
      
      translator.put( "cat", "Katze" );
      translator.put( "dog", "Hund" );
      translator.put( "bird", "Vogel" );
            
      System.out.println( translator.getProperty( "dog", "duh" ) );
      System.out.println( translator.getProperty( "mouse" ) );
      System.out.println( translator.getProperty( "child", "duh" ) );
   }
}
Output
Hund
raton
duh

Listen Here!Q-oct1 2mins Doc 10, Some JDK 1.1 API Slide # 20

System Properties


Java keeps important named resources in a special properties object. These named resources take the place of environment variables. Properties are used to provide a platform independent way to access this information. Each Java VM should support a standard list of system properties. However, a JVM can add more properties. Your program can also add to the system properties.

Accessing Some System Properties
public class SomeSystemProperties {
   public static void main( String args[] ) {
      System.out.println(  System.getProperty( "user.name") );
      System.out.println(  System.getProperty( "os.arch") );
      System.out.println(  System.getProperty( "user.language") );
   }
}
Output
Roger Whitney
PowerPC
en

Printing out all Your System Properties
import java.util.*;
public class AllSystemProperties {
   public static void main( String args[] ) {
      Properties mySystem = System.getProperties();
      
      Enumeration keys = mySystem.propertyNames();
      
      while ( keys.hasMoreElements() ){
         String aKey = (String)  keys.nextElement();
         System.out.println( aKey + " value: " + 
            mySystem.getProperty( aKey));
      }
   }
}

Listen Here!Q-oct1 26secs Doc 10, Some JDK 1.1 API Slide # 21

Standard System Properties


This list is from Java in a Nutshell, 2 nd Edition, Flanagan, page 236. Similar lists are in the Java API documentation in the java.lang.System class under the getProperties method and the Java Programming Language text. All JVM should contain all of the following properties.

file.encoding
Character encoding for default locale
file.encoding.pkg
Package for converters from local encoding to Unicode
file.separator
usual "/" or "\"
java.class.path
The classpath used by the JVM
java.class.version
Version of the Java API
java.compiler
The JIT compiler to use
java.home
The directory Java is installed in
java.vendor
Vender of the JVM
java.vendor.url
Vendor's URL
java.version
Version of the JDK 1.1.5
line.separator
Platform-dependent line separator, "\n", "\r\n", "\r", etc.
os.arch
Host hardware
os.name
Host OS
os.version
Host OS version
path.separator
Platform-dependent path separator, ":", ";"
user.dir
Current working directory
user.home
Home directory of user
user.language
2-letter language code of the default locale
user.name
Username of the current user
user.timezone
The default time zone
user.region
2-letter country code of the default locale


Listen Here!Q-oct1 6mins Doc 10, Some JDK 1.1 API Slide # 22
Specifying System Properties

You can specify system properties on the command line. Details of how to do this may be vary between different JVMs and platforms. For example, Macintosh computers do not have command lines. I will show how it works on UNIX using Sun's JVM. On the command line between the command "java" and before the name of the class you can place name-value pairs. This is done using the syntax "-Dname-value". These name-value pairs are added to the system properties. All text after the name of the class is passed to the string array parameter in the main of the class. If you place your name-value pairs after the name of the class, it will not be added to the system.properites.

public class SpecifyProperties {
   public static void main( String args[] ) {
      System.out.println(  System.getProperty( "user.name") );
      System.out.println(  System.getProperty( "courseGrade") );
      System.out.println(  "Now Print command line arguments" );
      
      for (int k = 0; k < args.length; k++ )
         System.out.println(  args[k] );
   }
}
Command Line
rohan 17-> java -Duser.name=Gates -DcourseGrade=A SpecifyProperties -DNotAProperty=notHere

Output
Gates
A
Now Print command line arguments
-DNotAProperty=notHere

Doc 10, Some JDK 1.1 API Slide # 23

sdsu.util.ProgramProperties

ProgramProperties provides a way to read and parse configuration files, command line arguments and default values in a program. The precedence order is command line arguments, configuration file, and then default values.

In a file called "config.labeledData" place:

# This is a sample config file, with a comment
remoteHost = fargo.sdsu.edu;
'key with spaces' = 'hi mom';  # a comment
port =    3245   ;  #note extra spaces/tabs
Program
import sdsu.util.ProgramProperties;
public class ConfigExample {
   public static void main( String args[] ) throws java.io.IOException {
      ProgramProperties configData = 
         new ProgramProperties( args, "config" );
      
      int portNumber = configData.getInt( "port" );
      int withDefault = configData.getInt( "port", 8080 );
      
      System.out.println( "port " + portNumber );
      System.out.println( "host " + configData.getString( "remoteHost" ) );
      System.out.println( "contains foo " + configData.containsKey( "foo" ) );
      System.out.println( "contains y " + configData.containsKey( "y" ) );
      System.out.println( "bar " + configData.getFloat( "bar", 0.0F ) );
   }
}
Command Line
java ConfigExample -port=6543   -bar  3.14  --xyz
Output
port 6543
host fargo.sdsu.edu
contains foo false
contains y true
bar 3.14

Doc 10, Some JDK 1.1 API Slide # 24

Some Useful Classes


java.util.Random


Random Constructors
Random()
Creates a new random number generator.
Random(long)
Creates a random number generator using a long as a seed.

import java.util.Random;
class  SampleRandom
{
   public  static  void  main( String  args[]  )
   {
      Random  data   =  new Random();
      System.out.println(  data.nextDouble()  );
      System.out.println(  data.nextFloat()  );
      System.out.println(  data.nextGaussian()  );
      System.out.println(  data.nextLong()  );
      System.out.println(  data.nextDouble()  );
   }
}
Output
0.941441
0.476748
-0.894882
-2651647369108839684
0.626033

Doc 10, Some JDK 1.1 API Slide # 25
java.util.StringTokenizer
The Stringtokenizer is useful in parsing strings into tokens.

import java.util.*;
class  Parse {
   public  static  void  main( String  args[]  ) {
      String  message  =  "this is a test";
      StringTokenizer  parser  =  
            new  StringTokenizer( message );
      
      System.out.println(  parser.countTokens()  ); 
      printTokens(  parser  );
      message  =  "Hi,Mom;this.is a funny, message";
      parser  =  new  StringTokenizer( message, ",;." );
      printTokens(  parser  );
      parser  =  new  StringTokenizer( message, ",;.", true );
      printTokens(  parser  );
   }
   static void printTokens(  StringTokenizer  input) {
      while (input.hasMoreTokens())  {
         System.out.println(  input.nextToken()  );
      }
   }
}
Output
Read the below output down the columns first, then read the colums from left to right

4HiHi
thisMom,
isthisMom
ais a funny;
test messagethis
.
is a funny
,
message


Doc 10, Some JDK 1.1 API Slide # 26
StringTokenizer Constructors

StringTokenizer(String, String, boolean)
Constructs a StringTokenizer on the specified String, using the specified delimiter set. If boolean is true, return delimiters with tokens.
StringTokenizer(String, String)
Constructs a StringTokenizer on the specified String, using the specified delimiter set.
StringTokenizer(String)
Constructs a StringTokenizer on the specified String, using the default delimiter set (which is " \t\n\r").

StringTokenizer Methods
countTokens() nextElement()
hasMoreElements() nextToken()
hasMoreTokens() nextToken(String)


Doc 10, Some JDK 1.1 API Slide # 27

java.util.BitSet


If you really miss working with bits, this class is for you


BitSet Constructors

BitSet()
Creates an empty set.
BitSet(int)
Creates an empty set with the specified size.


BitSet Methods
and(BitSet)or(BitSet)
clear(int)set(int)
clone()size()
equals(Object)toString()
get(int)xor(BitSet)
hashCode()


Doc 10, Some JDK 1.1 API Slide # 28

Some Useful SDSU Library Classes

Table - a two dimensional array


import sdsu.util.Table;
class TableExample
   {
   public static void main( String args[] ) throws 
                                    ConversionException
      {
      int rows = 2;
      int columns = 2;
      Table chart = new Table( rows, columns );
      
      chart.setElementAt( "Sandra", 0, 0 );
      chart.setElementAt( "John", 0, 1 );
      chart.setElementAt( "Jose", 1, 0 );
      chart.setElementAt( "Roger", 1, 1 );
      
      System.out.println( chart.rowAt( 0 ) );
      System.out.println( chart.columnAt( 0 ) );
      System.out.println( chart.elementAt( 0, 0 ) );
      
      String flattened =  chart.toString();
      
      Table recoveredChart = new Table();
      recoveredChart.fromString( flattened );
      System.out.println( recoveredChart );
      } 
   }
Output
[Sandra, John]
[Sandra, Jose]
Sandra
Sandra,John;
Jose,Roger

Doc 10, Some JDK 1.1 API Slide # 29

sdsu.util.SortedList


JDK 1.1.x did not include classes that would sort. sdsu.util.SortedList was added to the SDSU java library to correct that oversight. JDK 1.2 includes a sort method. We will cover that later. The following shows how to sort strings.

import  sdsu.util.SortedList;
class Sorting
   {
   public static void main( String args[] ) 
      {
      SortedList names = SortedList.stringSorter();
      names.addElement( "Roger");
      names.addElement( "Leopoldo");
      names.addElement( "Adam");
      System.out.println( names.elementAt( 1 ) );
      System.out.println( names );
      
      names = (SortedList) names.reversed();
      System.out.println( names );
      } 
   }

Output
Leopoldo
Adam,Leopoldo,Roger
Roger,Leopoldo,Adam

Listen Here!Q-oct1 3mins Doc 10, Some JDK 1.1 API Slide # 30
More Sorting

This example shows how to sort using different sorting criteria. Giving the SortedList a different comparer will resort the list.

import sdsu.util.SortedList;
import sdsu.compare.*;
public class MoreSorting {
   public static void main( String args[] ) {
      Comparer gradeComparer = LetterGradeComparer.getInstance();
      SortedList grades = new SortedList( gradeComparer );
      grades.addElement( "C-");
      grades.addElement( "B+");
      grades.addElement( "a");
      grades.addElement( "F");
      grades.addElement( "B");
      grades.addElement( "CR");
      System.out.println( "As grades:" + grades );
      grades.resort( StringComparer.getInstance() );
      System.out.println( "As strings:" + grades );
   }
}
Output
As grades:a,B+,B,CR,C-,F
As strings:B,B+,C-,CR,F,a

Doc 10, Some JDK 1.1 API Slide # 31
What Happens when Sorting Different Types?

The addElement method accepts any object. This means one can add incomparable types to the same SortedList object. What happens when this is done? What could happen? If the types are incomparable, then there is no way to sort them in the same list. A runtime exception is thrown.

import sdsu.util.SortedList;
public class TroubleHere {
   public static void main( String args[] ) {
      SortedList names = SortedList.stringSorter();
      names.addElement( "Roger");
      names.addElement( new Integer( 5 ) );
      System.out.println( names );
   }
}
Output
java.lang.ClassCastException: java.lang.Integer: cannot cast to java/lang/String
   at sdsu.compare.StringComparer.lessThan(StringComparer.java)
   at sdsu.util.SortedList.insertionIndexOf(SortedList.java)
   at sdsu.util.SortedList.addElement(SortedList.java)
   at TroubleHere.main(TroubleHere.java:14)


Listen Here!Q-oct1 7mins Doc 10, Some JDK 1.1 API Slide # 32

sdsu.compare.Comparer


In sorting its elements a SortedList object at sometime has to compare two elements in the list. It needs to know which element is smaller. To do this the SortedList object uses a Comparer object. The methods of a comparer object are listed below. By giving the SortedList object a different comparer, we can sort the list by different criteria. In C we would use a pointer to a function to do this. The comparer objects the object-oriented equivalent of a function pointer. In C++ and Java, there are language specific ways of creating function pointers. The comparer objects are language independent.

equals(Object, Object)
Returns true if the leftOperand is equal to the rightOperand.
greaterThan(Object, Object)

greaterThanOrEqual(Object, Object)

lessThan(Object, Object)

lessThanOrEqual(Object, Object)

Why StringComparer.getInstance() ?

Comparers doe not have any fields. This means there is no need to create more than one of them. Comparers use what is called the singleton. A unique single instance of a comparer is stored in a class field. See the next slide.


Doc 10, Some JDK 1.1 API Slide # 33
Some Comparer Code
Here is some of the source code for the StringComparer. It might be useful in talking about comparers. Note there is a better way to create the single instance. Note also how the lessThan insures that it deals with two object of type String.

public class StringComparer extends Comparer
   {
   private static Comparer singleInstance;
   
   private StringComparer() {};   
   
   public static Comparer getInstance()
      {
      if ( singleInstance == null)
         singleInstance = new StringComparer();
      
      return singleInstance;
      }
      
   public final boolean lessThan( Object leftOperand, 
                                    Object rightOperand ) 
      throws ClassCastException
      {      
      String left =  (String) leftOperand;
      if ( left.compareTo( (String) rightOperand ) < 0 )
         return true;
      else
         return false;
      }

Copyright © 1998 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
All rights reserved.

visitors since 30-Sep-98