0% found this document useful (0 votes)
25 views24 pages

Chap 9 Generics

Uploaded by

losvicdias101
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views24 pages

Chap 9 Generics

Uploaded by

losvicdias101
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 24

Generics in Java

Generics allow type (Integer, String, … etc


and user defined types) to be a parameter to
methods, classes and interfaces. For example,
classes like HashSet, ArrayList, HashMap, etc
use generics very well. We can use them for
any type.
Generic Class
 we use <> to specify parameter types in generic
class creation. To create objects of generic class,
we use following syntax.
 // To create an instance of generic class
 BaseType <Type> obj = new BaseType
<Type>()
 Note: In Parameter type we can not use primitives
like 'int','char' or 'double'.

 // A Simple Java program to show working of user defined
 // Generic classes

 // We use < > to specify Parameter type
 class Test<T>
 {
 // An object of type T is declared
 T obj;
 Test(T obj) { this.obj = obj; } // constructor
 public T getObject() { return this.obj; }
 }

class Main
{
public static void main (String[] args)
{
// instance of Integer type
Test <Integer> iObj = new Test<Integer>(15);
System.out.println(iObj.getObject());

// instance of String type


Test <String> sObj =new
Test<String>("GeeksForGeeks");
System.out.println(sObj.getObject());
}
}
Output:
15
We can also pass multiple Type parameters in Generic classes.

// A Simple Java program to show multiple type parameters in Java Generics


class Test<T, U>
{
T obj1; // An object of type T
U obj2; // An object of type U
Test(T obj1, U obj2)
{
this.obj1 = obj1;
this.obj2 = obj2;
}
public void print()
{
System.out.println(obj1);
System.out.println(obj2);
}
}
 // Driver class to test above
 class Main
 {
 public static void main (String[] args)
 {
 Test <String, Integer> obj = new Test<String, Integer>("GfG",
15);

 obj.print();
 }
 }
 Output:
 GfG
 15
Generic Functions:
 We can also write generic functions that can be called with different
types of arguments based on the type of arguments passed to generic
method, the compiler handles each method.

public class GenericMethodTest {


// generic method printArray
public static < E > void printArray( E[]
inputArray ) {
// Display array elements
for(E element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
 public static void main(String args[]) {
 // Create arrays of Integer, Double and Character
 Integer[] intArray = { 1, 2, 3, 4, 5 };
 Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
 Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

 System.out.println("Array integerArray contains:");
 printArray(intArray); // pass an Integer array

 System.out.println("\nArray doubleArray contains:");
 printArray(doubleArray); // pass a Double array

 System.out.println("\nArray characterArray contains:");
 printArray(charArray); // pass a Character array
 }
 }
 Advantages of Generics:

Programs that uses Generics has got many benefits over non-generic
code.
 1. Code Reuse: We can write a method/class/interface once and use for
any type we want.

 2. Type Safety : Generics make errors to appear compile time than at


run time (It’s always better to know problems in your code at compile
time rather than making your code fail at run time). Suppose you want
to create an ArrayList that store name of students and if by mistake
programmer adds an integer object instead of string, compiler allows it.
But, when we retrieve this data from ArrayList, it causes problems at
runtime.

 // A Simple Java program to demonstrate that NOT using generics can cause run time
exceptions
 import java.util.*;
 class Test {
 public static void main(String[] args)
 {
 // Creatinga an ArrayList without any type specified
 ArrayList al = new ArrayList();
 al.add("Sachin");
 al.add("Rahul");
 al.add(10); // Compiler allows this
 String s1 = (String)al.get(0);
 String s2 = (String)al.get(1);
 String s3 = (String)al.get(2); // Causes Runtime Exception
 }
 How generics solve this problem?
At the time of defining ArrayList, we can specify that this list can take only
String objects.
 Using generics converts run time exceptions into compile time exception.
 class Test
 {
 public static void main(String[] args)
 {
 ArrayList <String> al = new ArrayList<String> (); // Creating a an ArrayList with
String specified
 al.add("Sachin");
 al.add("Rahul");
 al.add(10); // Now Compiler doesn't allow this
 String s1 = (String)al.get(0);
 String s2 = (String)al.get(1);
 String s3 = (String)al.get(2); } }
 Individual Type Casting is not needed: If we do not use generics, then, in the above example every-time we
retrieve data from ArrayList, we have to typecast it. Typecasting at every retrieval operation is a big
headache. If we already know that our list only holds string data then we need not to typecast it every time.
 // We don't need to typecast individual members of ArrayList
 import java.util.*;

 class Test
 {
 public static void main(String[] args)
 {
 // Creating a an ArrayList with String specified
 ArrayList <String> al = new ArrayList<String> ();

 al.add("Sachin");
 al.add("Rahul");

 // Typecasting is not needed
 String s1 = al.get(0);
 String s2 = al.get(1);
 }
 }

 Implementing generic algorithms: By using generics, we can implement algorithms that work on
different types of objects and at the same they are type safe too.
 Example program to sort string, integers and emp objects using Colletions.sort
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class GenClass {
public static void main(String[] args) {
List<String> names= Arrays.asList("mango","banana","apple","orange");
List<Integer> intergs= Arrays.asList(3,5,2,4,7,1);
Collections.sort (names);
System.out.println(names);
Collections.reverse(names);
System.out.println(names);
Collections.sort (intergs);
System.out.println(intergs);
List<Emp> emps= new ArrayList<Emp>();
emps.add(new Emp(”kim",45,”Mar"));
emps.add(new Emp("jim",20,"cort"));
emps.add(new Emp("sim",12,”Pan"));
emps.add(new Emp("tim",35,”Que"));
Collections.sort(emps);
System.out.println(emps);
}
class Emp implements Comparable<Emp>{
String name;
int age;
String addr;
public Emp(String n, int a, String ad) {
name=n;
age=a;
addr=ad;
}
public String toString()
{
return String.format ("[%s,%d,%s]",name,age,addr);
}
@Override
public int compareTo(Emp o) {

return this.age-o.age; //to sort on age


//return this.name.compareTo(o.name); // to sort on name
field
}
}
The output
[apple, banana, mango, orange]
[orange, mango, banana, apple]
[1, 2, 3, 4, 5, 7]
[[sim,12,Pan], [jim,20,Cort], [tim,35,Que], [kim,45,Mar]]
The Java Collections Framework
 The Java collections framework gives the programmer access to
prepackaged data structures as well as to algorithms for manipulating
them.
 A collection is an object that can hold references to other objects. The
collection interfaces declare the operations that can be performed on
each type of collection.
 The classes and interfaces of the collections framework are in package
java.util.
 The collections framework was designed to meet several goals, such as −
 The framework had to be high-performance. The implementations for the
fundamental collections (dynamic arrays, linked lists, trees, and
hashtables) were to be highly efficient.
 The framework had to allow different types of collections to work in a
similar manner and with a high degree of interoperability .
 The framework had to extend and/or adapt a collection easily.
 Towards this end, the entire collections framework is designed around a
set of standard interfaces. Several standard implementations(i.e. classes)
of these interfaces such as LinkedList (implements List), HashSet
(implements Set), and TreeSet (implements Set), are provided that
you may use as-is and you may also implement your own collection, if
you choose.
 A collections framework is a unified architecture for representing and
manipulating collections. All collections frameworks contain the following

 Interfaces − These are abstract data types that represent collections.
Interfaces allow collections to be manipulated independently of the details
of their representation.
 Implementations, i.e., Classes − These are the concrete
implementations of the collection interfaces. In essence, they are reusable
data structures.
 Algorithms − These are the methods that perform useful computations,
such as searching and sorting, on objects that implement collection
interfaces
 In addition to collections, the framework defines several map interfaces
and classes. Maps store key/value pairs. Although maps are
not collections in the proper use of the term, but they are fully integrated
with collections.
The Collection Interfaces
 The collections framework defines several interfaces. Some examples
include:
 The Collection Interface This enables you to work with groups of
objects; it is at the top of the collections hierarchy. The Collection
interface is the foundation upon which the collections framework is
built. It declares the core methods such as add(Object O),
remove(Object O), clear(), etc that all collections will have.
 The List interface extends Collection and declares the behavior of a
collection that stores a sequence of elements.
 The Set This extends Collection to handle sets, which must contain
unique elements.
 The SortedSet This extends Set to handle sorted sets.
 The Map This maps unique keys to values.
The Collection Classes
 Java provides a set of standard collection classes that implement Collection interfaces.
Examples include the follwing:
 LinkedList - The LinkedList class extends AbstractSequentialList and implements the List
interface. It provides a linked-list data structure.
 ArrayList - The ArrayList class extends AbstractList and implements the List interface. ArrayList
supports dynamic arrays that can grow as needed.
 Standard Java arrays are of a fixed length. After arrays are created, they cannot grow or shrink,
which means that you must know in advance how many elements an array will hold.
 Array lists are created with an initial size. When this size is exceeded, the collection is
automatically enlarged. When objects are removed, the array may be shrunk.
 HashMap - The HashMap class uses a hashtable to implement the Map interface. This allows
the execution time of basic operations, such as get( ) and put( ), to remain constant even for
large sets.
Example: ArrayList,LinkedList,HashSet and
HashMap
import java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
// ArrayList
List a1 = new ArrayList();
a1.add("Zara");
a1.add("Mahnaz");
a1.add("Ayan");
System.out.println(" ArrayList Elements");
System.out.print("\t" + a1);
// Remove elements from the array list
al.remove(" Mahnaz ");
al.remove(2);
System.out.print("\t" + a1);
// LinkedList
LinkedList l1 = new LinkedList();
l1.add("Zara");
l1.add("Mahnaz");
l1.add("Ayan");
System.out.println(" LinkedList Elements");
System.out.print("\t" + l1);
l1.addFirst(“B”)
l1.addLast(“P”);
l1.add(3,”C”);
l1.remove(”P”);
l1.remove(2);
System.out.print("\t" + l1);

// HashMap
Map m1 = new HashMap();
m1.put("Zara", "8");
m1.put("Mahnaz", "31");
m1.put("Ayan", "12");
m1.put("Daisy", "14");
System.out.println();
System.out.println(" Map Elements");
System.out.print("\t" + m1);
System.out.println(“Zara’s value:” + m1.get(“Zara”));
}
}

You might also like