Chapter 9
Chapter 9
Debasis Samanta
Department of Computer Science & Engineering, IIT Kharagpur
class SpecificArrayInt {
// Declaring an array of integer values
// Constructor to load the array.
// Method to print the array elements.
// Method to reverse the array elements.
}
class MainClassInt {
/* This class utilize the class SpecificArrayInt to
manipulate some integer data */
}
Example 3.1 : Program to handle an array of integers
class SpecificArrayInt {
// Declaring an array of integer numbers
int a;
// Continued on ...
// Continued on ...
class MainClassInt {
//This class use the class SpecificArrayInt to manipulate data in it
a.printInt();
a.reverseInt();
a.printInt();
}
Why generic class?
Now, consider the case of processing a set of double values stored in an array.
class SpecificArrayDouble {
// Declaring an array of double values
// Constructor to load the array.
// Method to print the array elements.
// Method to reverse the array elements.
}
class MainClassDouble {
/* This class utilize the class SpecificArrayDouble to
manipulate some integer data. */
}
Example 3.2 : Program to handle an array of doubles
class SpecificArrayDouble {
// Declaring an array of double values
double b;
// Continued on ...
// Continued on ...
class MainClassDouble {
//This class use the class SpecificArrayInt to manipulate data in it
b.printDouble();
b.reverseDouble();
b.printDouble();
}
Why generic class?
Let us repeat the procedure, but a set of string elements stored in an array.
class SpecificArrayString {
// Declaring an array of string items.
// Constructor to load the array.
// Method to print the array elements.
// Method to reverse the array elements.
}
class MainClassString {
/* This class utilize the class SpecificArrayString to
manipulate some integer data. */
}
Example 3.3 : Program to handle an array of Strings
class SpecificArrayString {
// Declaring an array of double values
String c;
// Continued on ...
// Continued on ...
class MainClassString {
//This class use the class SpecificArrayInt to manipulate data in it
c.printString();
c.reverseString();
c.printString();
}
Why generic class?
• Observations
• Data are different.
• Different programs.
• Code duplications
Syntax of Defining Generic Class
Syntax for generic class definition
Here, is the full syntax for declaring a reference to a generic class and
instance creation:
// Constructor
public GenericClass(T t) {
x = t;
}
class GenericClassTest {
public static void main( String args[] ) {
// A data with the member as String
GenericClass<String> a = new GenericClass<String> ("Java");
a.printData();
// A data with the member as integer value
GenericClass<Integer> b = new GenericClass<Integer> (123);
b.printData();
// A data with the member as float value
GenericClass<Double> c = new GenericClass<Double> (3.142);
c.printData();
}
}
Example: Defining a Generic Class
with Array of Any Data Type
Example 3.5: Processing arrays with any data type
class GenericArrayClass {
// Declaring a generic array
// Constructor to load the array.
// Method to print the array elements
// Method to reverse the array elements
}
class MainClass {
//This class utilize the class GenericArrayClass to manipulate data of any type.
}
Example 3.5: Defining class to process arrays with any data type
class GenericArray<T> {
//Declaring an array, which should store any type T of data
T a[ ];
T getData(int i) { // To return the element stored in the i-th place in the array
return a[i];
}
void static reverseArray (T b) { // Generic method to reversed the order of elements in array b
int front = 0, rear = b.length-1;
T temp;
while( front < rear) {
temp = b[rear];
b[rear] = a[front];
a[front] = temp;
front++; rear--;
}
}
}
Example 3.5: Defining class to process arrays with any data type
class GenericClassArrayDemo {
public void static main(String args a[]) {
//Creating an array of integer data
Integer x[ ] = {10, 20, 30, 40, 50}; // It is an array of Integer numbers
// Continued on ...
// Continued on ...
//Define a class Student class GenericClass<T> { // Use < > to specify class type
class Student { T obj; // An object of type T is declared
String name; GenericClass(T obj) { // Constructor of the generic class
float marks; this.obj = obj;
}
Student(String name, float marks) { public T getObject() { // A Method in the class
this.name = name; return this.obj;
this.marks = marks; }
} }
Example 3.6: Working with user defined class
https://nptel.ac.in/noc/faqnew.php
Data Structures and Algorithms Using Java
Debasis Samanta
Department of Computer Science & Engineering, IIT Kharagpur
T a = new T[5];
class GenericStaticDemo {
// Defining a static generic method to print any data type
static void gPrint (T t) {
System.out.println (t);
Example 4.1
}
}
class GenericStaticDemo2 {
public void static main(String args a[]) {
GenericClass<Integer> a = new GenericClass<Integer>(new Integer x[ ] {10, 20, 30, 40, 50});
}
class GenericClassDemo3 {
public void static main(String args a[]) {
GenericClass<Integer> a = new GenericClass<Integer>(123); // Okay
GenericClass<int> a = new GenericClass<int>(234); // ERROR!
}
}
Important Notes
5. A generic class can be defined with multiple type parameters.
• We can create a generic class with one or more type parameters so that more
than one types of data to be manipulated in a generic program.
Example 4.5: Generic class with two parameters
// Constructor
public PairData(T a, V b) {
x = a;
y = b;
}
// Continued on ...
// A pair data with the first member as String and other as Integer
PairData<String, Integer> b = new PairData<String, Integer> (“Debasis”, 789);
b.printData();
// A pair data with the first member as Integer and other as String
PairData<Integer, String> c = new PairData<Integer, String> (943, “Samanta”);
c.printData();
// A pair data with the first member as Integer and other as Double
PairData<Integer, Double> d = new PairData<Integer, Double> (555, 12.34);
d.printData();
}
}
Example 4.7: Generic class with method overloading
// Continued on...
T getDataT(int i) {// To return the element stored in i-th place in the array
return a[i];
}
S getDataS(int i) { //To return the element stored in i-th place in the array
return b[i];
}
// Continued on...
// Continued on...
// Continued on...
GenericError<T> {
T[ ] array; // an array of type T
array = t;
}
https://nptel.ac.in/noc/faqnew.php
Data Structures and Algorithms Using Java
Debasis Samanta
Department of Computer Science & Engineering, IIT Kharagpur
• When specifying a type parameter, you can create an upper bound that
declares the super class from which all type arguments must be derived.
• This is accomplished through the use of an extends clause when specifying
the type parameter
• This specifies that T can only be replaced by super class, or sub classes of
super class. Thus, super class defines an inclusive, upper limit.
Example 5.2 : Upper bound of argument in generic class definition
class GenericBoundDemo {
public static void main(String args[]) {
Integer intArray[] = { 1, 2, 3, 4, 5 };
GenericBound <Integer> intData = new GenericBound
<Integer>(intArray);
double avgInt = intData.average();
System.out.println("Average is " + avgInt);
• The question mark symbol (?) is known as the wildcard in generic programming in Java.
• Whenever you need to represent an unknown type, you can do that with ?.
• Java generic's wildcard is a mechanism to cast a collection of a certain class.
Example 5.3: Generic class with another limitation
The following class definition is to make a program so that a student’s marks can be stored in
any number format, that is, Integer, Short, Double, Float, Long, etc.
// Continued on...
// Continued on...
// Driver class while instantiating the Student generic class with different number format.
class GenericLimitationDemo {
public static void main(String args[]) {
Integer intMarks1[] = { 44, 55, 33, 66, 77 }; // Marks stored in integer for s1
Student<Integer> s1IntMarks = new Student<Integer>(intMarks1);
System.out.println("Total marks " + s1IntMarks.total());
// Continued on...
Double doubleMarks[] = { 43.5, 55.5, 32.5, 66.5, 77.0 }; // Marks stored in double for s3
Student<Double> s3DoubleMarks = new Student<Double>(doubleMarks);
System.out.println("Total marks " + s3DoubleMarks.total());
Float floatMarks[] = { 50.0F, 40.0F, 60.0F, 65.0F }; // Marks stored in float for s4
Student<Float> s4FloatMarks = new Student<Float>(floatMarks);
System.out.println("Total marks " + s4FloatMarks.total());
Notes:
1. There is no error when s1 is compared with s2;
2. The same is not true for s2 and s3 or s3 and s4. The reason is that the
si.compareMarks (sj) method works only when the type of the object sj is
same as the invoking object si.
Wildcard argument in Java
• Such a problem can be solved by using another feature of Java generics called the
wildcard argument.
• The wildcard argument is specified by the ?, and it just work as the type casting.
• Thus, with reference to program in Example 5.3, we have to change the boolean
compareMarks (Student <T> t) method with wildcard as boolean
compareMarks(Student<?> t).
Example 5.4: Generic class with wildcard argument
The following class definition is to make a program so that a student’s marks can be stored in any number
format, that is, Integer, Short, Double, Float, Long, etc. modified with wildcard argument.
// Continued on...
Object
Animal
o long lifespan;
o float weight;
o print();
Aquatic Land
o Boolean scale; o short vision;
o print();
Pet Wild
o String name; o float speed;
Bounded wildcard arguments Object
There are other three different ways that wildcard features are useful. o
Animal
long lifespan;
o float weight;
o print();
Syntax: o
Pet
String name; o
Wild
float speed;
To declare an upper-bounded wildcard, use the wildcard character
?, followed by the extends keyword, followed by its upper
bound class name. For example, say A denotes the upper bound of
the class. Then the wildcard uses for the method bounded up to A
is
<type> methodUBA(? extends A) { … }
In other words, the call of this method is valid for any object of the
class A or any of its child class.
Bounded wildcard arguments Object
Animal
o long lifespan;
2. Lower bound wildcard o
o
float weight;
print();
If you want to limit the call of a method defined in class A and its
parent classes only, then you can use lower bound wildcard. Aquatic Land
o Boolean scale; o short vision;
Syntax:
o print();
Animal
o long lifespan;
3. Unbound wildcard o
o
float weight;
print();
• When the code is using methods in the generic class that don’t o
Pet
String name; o
Wild
float speed;
Syntax:
It is expressed using the wildcard character ?, followed by nothing.
<type> methodNBA(?) { … }
Examples of Bounded Wildcard
Example 5.4: Bounded wildcard arguments Object
Animal
o long lifespan;
o float weight;
The objective of this example is to illustrate how different o print();
Animal
o long lifespan;
o float weight;
The objective of this example is to illustrate how different o print();
Animal
o long lifespan;
o float weight;
o print();
class Animal {
long lifespan; Aquatic Land
o Boolean scale; o short vision;
float weigh; o print();
Animal(long years, float kg) {
lifespan = years; Pet Wild
weight = kg;
o String name; o float speed;
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
Aquatic Land
class Aquatic extends Animal { o Boolean scale; o short vision;
o print();
boolean scale; // true: has scale, false: no scale
Aquatic(long years, float kg, boolean skin) {
super(years, kgs); // Super class constructor o
Pet
String name; o
Wild
float speed;
scale = skin;
}
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
}
} // End of class Land
// Continued to next...
Example 5.5: Definition of all the classes in animals Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
Aquatic Land
o Boolean scale; o short vision;
String name;
Pet(long years, float kg, short vision, String name) { o
Pet
String name; o
Wild
float speed;
super(years, kgs, vision, name); // Super class constructor
this.name = name;
}
} // End of class Pet
// Continued to next...
Example 5.5: Definition of all the classes in animals Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
}
} // End of class Wild
// Continued to next...
Example 5.5: Defining generic class to maintain lists of animals
Object
Animal
// Continued on... o
o
long lifespan;
float weight;
o print();
// Continued to next...
Example 5.5: Defining different methods with different bounds Object
of arguments Animal
o long lifespan;
o float weight;
o print();
// Continued on...
class BoundedWildcards {
Aquatic Land
o Boolean scale; o short vision;
print();
//Case 1: Unbound wildcard: Any object can be passed as its argument. o
// Continued to next...
Example 5.5: Defining different methods with different bounds Object
of arguments Animal
o long lifespan;
o float weight;
// Continued on... o print();
obj.print();
// Call the method defined in Animal/ Aquatic class
System.out.println();
}
// Continued to next...
Example 5.5: Defining different methods with different bounds Object
of arguments Animal
o long lifespan;
o float weight;
o print();
// Continued on...
Aquatic Land
// Case 3a: Upper bounded wildcard: Any object of Land/ Pet/ Wild can // be o Boolean scale; o short vision;
passed as its argument. o print();
// Continued to next...
Example 5.5: Defining different methods with different bounds Object
of arguments Animal
o long lifespan;
o float weight;
o print();
// Continued on...
// Case 3b: Upper bounded wildcard: Any object of only Pet class can // be
Aquatic Land
passed as its argument. o Boolean scale; o short vision;
o print();
// Continued to next...
Example 5.5: Defining different methods with different bounds Object
of arguments Animal
o long lifespan;
o float weight;
o print();
// Continued on...
// Case 3c: Upper bounded wildcard: Any object of only Wild class can // be Aquatic Land
passed as its argument. o
o
Boolean scale;
print();
o short vision;
Animal
o long lifespan;
// Continued on... o float weight;
o print();
class BoundedWildcardArgumentsDemo {
public static void main(String args[]) {
Aquatic Land
o Boolean scale; o short vision;
// Create a list of unknown animals of class Animal o print();
// Continued to next...
Example 5.5: Main program utilizing the above-defined classes Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
Aquatic Land
// Create a list of land animals o Boolean scale; o short vision;
o print();
Land owl = new Land(3, 1, 0);
// A land owl object is created
Land l [] = { owl };
Pet Wild
// An array of land objects is created o String name; o float speed;
AnimalWorld<Land> lList = new AnimalWorld<Land>(l);
// Place the animals into a list
// Continued to next...
Example 5.5: Main program utilizing the above-defined classes Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
// Continued to next...
Example 5.5: Main program utilizing the above-defined classes Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
Aquatic Land
// Call the methods and see the outcomes o Boolean scale; o short vision;
o print();
// vitality(…) is with unlimited wildcard argument and
// hence we can pass argument of any type
vitality (uList); // OK o
Pet
String name; o
Wild
float speed;
vitality (qList); // OK
vitality (lList); // OK
vitality (pList); // OK
vitality (wList); // OK
// Continued to next...
Example 5.5: Main program utilizing the above-defined classes
Object
Animal
o long lifespan;
o float weight;
o print();
// Continued to next...
Example 5.5: Main program utilizing the above-defined classes Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
Aquatic Land
o Boolean scale; o short vision;
o print();
// showLand(…) is with upper bound wildcard argument with
// class Land and its subclasses
showLand (uList); // Compile-time error o
Pet
String name; o
Wild
float speed;
showLand (qList); // Compile-time error
showLand (lList); // OK
showLand (pList); // OK
showLand (wList); // OK
// Continued to next...
Example 5.4: Main program utilizing the above-defined classes
Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
showPet (lList);
o String name; o float speed;
// Compile-time error
showPet (pList); // OK
showPet (wList); // Compile-time error
// Continued to next...
Example 5.5: Main program utilizing the above-defined classes Object
Animal
o long lifespan;
o float weight;
o print();
// Continued on...
Aquatic Land
o Boolean scale; o short vision;
// showWild(…) is with upper bound wildcard argument with o print();
Note:
• You can specify an upper bound for a wildcard, or you can specify a lower
bound, but you cannot specify both.
https://cse.iitkgp.ac.in/~dsamanta/javads/index.html