In COMP101 the basic elements of the Java programming language were introduced. In the first part of COMP102 we will be concerned with the topic of
both in the sense of the abstract properties, organisation, and operations on the more important of these, and in the context of their specific realisations within the Java environment.
This brief description may raise a few questions:
Answers:
Answer:
Because Java is just a single programming language within a specific class (or paradigm) of programming languages. An understanding of the abstract organisation and operations on the more commonly occurring complex data structures provides a basis for both the ability to implement such structures within any sufficiently powerful language, e.g. BASIC, C, Pascal, even assembler; and gives a language independent context for studying algorithms that utilise such structures, cf COMP108 (again).
Over the next lectures the following structures will be examined:
In this lecture, we examine some general aspects of data structures.
If one considers different types of data structure, e.g. Strings which were introduced in COMP101, then it may appear that the only issue one has to be concerned with is how to implement the structure in terms of basic language types: having solved this , the question of how to implement different operations on the structure (and what type of operations to provide) is (in effect) directed by the chosen realisation.
Consider the String class as specified in java.lang.String.
This provides:
There are two important points to notice about this scheme:
Java, in common with all genuinely Object-Oriented programming languages, provides an environment for implementing compound data types (such as String) whereby the representation (in terms of Primitive Types and other structures) can only be manipulated by the operations (i.e. Method) that are defined to do so.
(These ideas have already been discussed when Objected-Oriented Programming principles were introduced earlier.)
In many programming languages (particularly older imperative languages such as Pascal, Fortran, C) there is no `clean' mechanism for enforcing such a regime.
[Note The philosophy that a data type embodies not only its internal organisation but also the operations that can be performed on it - hence data types are realised so that the former is only reachable via the latter - did not originate with Java or even Object-Oriented languages; it in fact was utilised in languages such as ML, and had been proposed by researchers by the late 1970s, e.g. Barbara Liskov's CLU programming language.].
By combining the definitions of
The organisation of Abstract Data Types (ADTs), as a collection of data and the operations acting upon the data, is known as Encapsulation, and is an important element of Object-Oriented Programming approaches.
You have already encountered an important compound data type in the form of
Simple Array Structures.
Java does not limit the use of Array structures to the basic types -
int, double, char,
boolean, etc, but allows arrays of Object Instances,
to be defined and manipulated.
This capability is particularly useful in the context of defining
tables of records, for example of the type
that would occur in a typical relational database.
As an example, consider the Triangle
Recognition Exercise that was set in COMP101.
The code below describes a Class Triangle
Example 1: Triangle Class Realisation
In this class there are 7 data fields:
In addition there are 3 Constructors: a default Constructor;
one which takes 3 side lengths (in any order) computes the correct
field values for these lengths, using the convention that one of the
vertices has co-ordinates (0,0) and one has co-ordinates (0,L).
The final Constructor computes field values given three points in the plane
representing triangle vertices.
There are 4 Methods:
The Class Diagram is shown below:
Suppose we wish to define an array of some number,
LEN say, Triangle objects. This is, done by a similar method to that used in declaring
any other array by:
Declaration of Array of Triangle Objects
Of course, since the type of element in TriArray
is not one of the basic types, this declaration will not instantiate any of
the individual components. In order to this an appropriate Constructor
as defined in the Triangle Class must be invoked.
For example we could do this by:
Instantiation of Array of Triangle Objects
We illustrate the use of an array of Objects, with respect to a simple example
involving the Triangle class introduced above.
This example concerns collecting and analysing data pertaining to triangles
satisfying certain restrictions.
We are given an integer bound on the length of any side of a triangle: 10 say,
The qualification `distinct' means that triangles
S and T with side lengths
(s1, s2, s3) and
(t1, t2, t3)
are counted separately if and only if at least one of the side
lengths in S differs from all of the side lengths in T.
There is no user supplied input necessary (we assume that the maximum
side length has been specified as 10). We need to consider the following:
Since the defining condition for three lengths (S,M,L) (with
S<=M<=L) to be valid is that S+M> L, the simplest method
to calculate the number of valid cases is:
Figure 1.1: Total number of Valid Triangles Computation
Once this number has been computed we know how many elements
the array of Triangle instances needs to hold. Thus,
having defined the identifier of the array the number of elements is
set using:
Figure 1.2: Instantiation of Triangle Array - i) Number of Elements
In the computational processing part, it remains to instantiate
the individual elements of the Triangle array,
and to realise the counting of each different type of triangle.
Since we have three types of triangle - equilateral, isosceles,
and scalene - we use three different integers to maintain these:
Figure 1.3: Counters For Different Triangle Types
The process of updating these and instantiating the individual Triangle
array elements can be carried out within the same nested for
loop structure: we know that a given triple of integer values - (i,j,k) - in which
i<=j<=k, can only be a valid triangle if i+j> k: - recall that this is the method by which
the total number of elements to allow in the array was determined. We can therefore
proceed by generating (i,j,k) (with i<=j<=k) in turn; testing if i+j> k; and
instantiating the next element of our array using the Constructor
Triangle(double,double,double)
provided by the class Triangle, i.e. this one. Hence
Figure 1.4: Instantiation of Triangle Array - ii) Individual Elements
The maintenance of the counters defined in Figure 1.3 can be carried out
whenever a valid triple (i,j,k) of side lengths is found,
via a switch statement triggered on the result
of the Instance method FormCode()
associated with the Triangle class. Thus,
Figure 1.5: Updating Triangle Type Counters
Finally we have to deal with the output requirements. There are two stages
to this: print out the statistics concerning the total numbers; and the
details of the specific triangles of each type
Figure 1.6: Output Total Numbers
For the second part we use a method within the application class that
is parameterised by a character describing the triangle form of interest:
Figure 1.7: Output Different Cases for the Specified Type of Triangle
This is invoked in the main() method by:
Figure 1.8: Final Output Stage
The complete implementation is given below:
Figure 1.9: Full Implementation: Array of Objects Example Program
When executed the output below results:
Figure 1.10: Output from Array of Triangle Objects Example Program
3. Arrays of Objects
Triangle Class Diagram
Triangle[] TriArray = new Triangle[LEN];
for (i=0; i< LEN; i++) TriArray[i] = new Triangle();
4. A Simple Example Program
4.1. Requirements
4.2. Analysis
final static int LEN_UPB = 10; // Longest Side Length
static int MAX_POSS = 0;
private static void Compute_Max ()
{
for (int i=1; i<=LEN_UPB; i++)
for (int j=i; j<=LEN_UPB; j++)
for (int k=j; k<=LEN_UPB; k++)
if (i+j>k) MAX_POSS++;
}
static Triangle[] TriArray; // The array of Triangle Objects
// to be instantiated in main()
....
public static void main( String[] args )
{
Compute_Max(); // Calculate number of valid triangles.
TriArray = new Triangle[MAX_POSS]; // Initiate array;
...
}
static int equi_tot=0;
static int iso_tot=0;
static int scal_tot=0;
static int IsTriangle = 0;
...
public static void main( String[] args )
{
for (int i=1; i<=LEN_UPB; i++)
for (int j=i; j<=LEN_UPB; j++)
for (int k=j; k<=LEN_UPB; k++)
if (i+j>k)
{
TriArray[IsTriangle] = new Triangle(i,j,k); // Instantiate specific element
//
// Determine which counter should increase
//
IsTriangle++; // Increase count of number of valid cases stored.
};
switch(TriArray[IsTriangle].FormCode())
{
case 'E': equi_tot++; break;
case 'I': iso_tot++; break;
case 'S': scal_tot++;
};
//
// Output Statistics
//
System.out.println("Triangles with integer side lengths at most " + LEN_UPB);
System.out.println("##################################################");
System.out.println("Well formed | " + IsTriangle);
System.out.println("Equilateral | " + equi_tot);
System.out.println("Isosceles | " + iso_tot);
System.out.println("Scalene | " + scal_tot);
System.out.println("##################################################");
System.out.println();
//
// Print the sides of all triangles of type
// EIS, where EIS is one of 'E'(quilateral) 'I'(sosceles) or 'S'(calene).
// Triangle output as (S,M,L): 5 to a line;
//
private static void ListTypes ( final char EIS, final int MAX, Triangle[] T )
{
int per_line = 0;
for (int i=0; i< MAX; i++)
{
if (T[i].FormCode()==EIS)
{
System.out.print("("+T[i].Sides()[0]+","+
T[i].Sides()[1]+","+
T[i].Sides()[2]+") ; ");
per_line++;
if (per_line==5)
{
per_line=0; System.out.println();
};
};
};
}
//
// List each found in the different categories.
//
System.out.println("Equilateral Triangles with Integer Side Length at most " + LEN_UPB);
System.out.println("############################################################");
ListTypes('E',IsTriangle,TriArray);
System.out.println();
System.out.println("Isosceles Triangles with Integer Side Length at most " + LEN_UPB);
System.out.println("############################################################");
ListTypes('I',IsTriangle,TriArray);
System.out.println();
System.out.println("Scalene Triangles with Integer Side Length at most " + LEN_UPB);
System.out.println("############################################################");
ListTypes('S',IsTriangle,TriArray);
System.out.println();
//
// COMP102
// Example 2: Array of Object Instances
// Triangle Data
//
// Paul E. Dunne 15/9/1999
//
import Triangle; // The Triangle Class
import java.io.*;
class TriConApp
{
// Fields
final static int LEN_UPB = 10; // Longest Side Length
static int MAX_POSS = 0;
static int equi_tot=0;
static int iso_tot=0;
static int scal_tot=0;
static int IsTriangle = 0;
static Triangle[] TriArray; // The array of Triangle Objects
// to be instantiated in main()
//
// Calculate how many possible triangles of side
// length at most LEN_UPB.
// Could do this directly, but would require opaque
// algebraic screed in initiating MAX_POSS.
//
private static void Compute_Max ()
{
for (int i=1; i<=LEN_UPB; i++)
for (int j=i; j<=LEN_UPB; j++)
for (int k=j; k<=LEN_UPB; k++)
if (i+j>k) MAX_POSS++;
}
//
// Print the sides of all triangles of type
// EIS, where EIS is one of 'E'(quilateral) 'I'(sosceles) or 'S'(calene).
// Triangle output as (S,M,L): 5 to a line;
//
private static void ListTypes ( final char EIS, final int MAX, Triangle[] T )
{
int per_line = 0;
for (int i=0; i< MAX; i++)
{
if (T[i].FormCode()==EIS)
{
System.out.print("("+T[i].Sides()[0]+","+
T[i].Sides()[1]+","+
T[i].Sides()[2]+") ; ");
per_line++;
if (per_line==5)
{
per_line=0; System.out.println();
};
};
};
}
public static void main( String[] args )
{
for (int i=1; i<=LEN_UPB; i++)
for (int j=i; j<=LEN_UPB; j++)
for (int k=j; k<=LEN_UPB; k++)
if (i+j>k)
{
TriArray[IsTriangle] = new Triangle(i,j,k); // Instantiate specific element
//
// Determine which counter should increase
//
switch(TriArray[IsTriangle].FormCode())
{
case 'E': equi_tot++; break;
case 'I': iso_tot++; break;
case 'S': scal_tot++;
};
IsTriangle++; // Increase count of number of valid cases stored.
};
//
// Output Statistics
//
System.out.println("Triangles with integer side lengths at most " + LEN_UPB);
System.out.println("##################################################");
System.out.println("Well formed | " + IsTriangle);
System.out.println("Equilateral | " + equi_tot);
System.out.println("Isosceles | " + iso_tot);
System.out.println("Scalene | " + scal_tot);
System.out.println("##################################################");
System.out.println();
//
// List each found in the different categories.
//
System.out.println("Equilateral Triangles with Integer Side Length at most " + LEN_UPB);
System.out.println("############################################################");
ListTypes('E',IsTriangle,TriArray);
System.out.println();
System.out.println("Isosceles Triangles with Integer Side Length at most " + LEN_UPB);
System.out.println("############################################################");
ListTypes('I',IsTriangle,TriArray);
System.out.println();
System.out.println("Scalene Triangles with Integer Side Length at most " + LEN_UPB);
System.out.println("############################################################");
ListTypes('S',IsTriangle,TriArray);
System.out.println();
}
}
Triangles with integer side lengths at most 10
##################################################
Well formed | 125
Equilateral | 10
Isosceles | 65
Scalene | 50
##################################################
Equilateral Triangles with Integer Side Length at most 10
############################################################
(1,1,1) ; (2,2,2) ; (3,3,3) ; (4,4,4) ; (5,5,5) ;
(6,6,6) ; (7,7,7) ; (8,8,8) ; (9,9,9) ; (10,10,10) ;
Isosceles Triangles with Integer Side Length at most 10
############################################################
(1,2,2) ; (1,3,3) ; (1,4,4) ; (1,5,5) ; (1,6,6) ;
(1,7,7) ; (1,8,8) ; (1,9,9) ; (1,10,10) ; (2,2,3) ;
(2,3,3) ; (2,4,4) ; (2,5,5) ; (2,6,6) ; (2,7,7) ;
(2,8,8) ; (2,9,9) ; (2,10,10) ; (3,3,4) ; (3,3,5) ;
(3,4,4) ; (3,5,5) ; (3,6,6) ; (3,7,7) ; (3,8,8) ;
(3,9,9) ; (3,10,10) ; (4,4,5) ; (4,4,6) ; (4,4,7) ;
(4,5,5) ; (4,6,6) ; (4,7,7) ; (4,8,8) ; (4,9,9) ;
(4,10,10) ; (5,5,6) ; (5,5,7) ; (5,5,8) ; (5,5,9) ;
(5,6,6) ; (5,7,7) ; (5,8,8) ; (5,9,9) ; (5,10,10) ;
(6,6,7) ; (6,6,8) ; (6,6,9) ; (6,6,10) ; (6,7,7) ;
(6,8,8) ; (6,9,9) ; (6,10,10) ; (7,7,8) ; (7,7,9) ;
(7,7,10) ; (7,8,8) ; (7,9,9) ; (7,10,10) ; (8,8,9) ;
(8,8,10) ; (8,9,9) ; (8,10,10) ; (9,9,10) ; (9,10,10) ;
Scalene Triangles with Integer Side Length at most 10
############################################################
(2,3,4) ; (2,4,5) ; (2,5,6) ; (2,6,7) ; (2,7,8) ;
(2,8,9) ; (2,9,10) ; (3,4,5) ; (3,4,6) ; (3,5,6) ;
(3,5,7) ; (3,6,7) ; (3,6,8) ; (3,7,8) ; (3,7,9) ;
(3,8,9) ; (3,8,10) ; (3,9,10) ; (4,5,6) ; (4,5,7) ;
(4,5,8) ; (4,6,7) ; (4,6,8) ; (4,6,9) ; (4,7,8) ;
(4,7,9) ; (4,7,10) ; (4,8,9) ; (4,8,10) ; (4,9,10) ;
(5,6,7) ; (5,6,8) ; (5,6,9) ; (5,6,10) ; (5,7,8) ;
(5,7,9) ; (5,7,10) ; (5,8,9) ; (5,8,10) ; (5,9,10) ;
(6,7,8) ; (6,7,9) ; (6,7,10) ; (6,8,9) ; (6,8,10) ;
(6,9,10) ; (7,8,9) ; (7,8,10) ; (7,9,10) ; (8,9,10) ;
5. Summary
NameOfClass.NameOfMethodInClass( parameters );
NameOfInstanceOfClass.NameOfMethodInClass( parameters );
(Notes prepared and maintained by Paul E. Dunne, October 1999)