0% found this document useful (0 votes)
10 views64 pages

Dhdfs

Uploaded by

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

Dhdfs

Uploaded by

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

CSE-2005

Object Oriented Programming


– by
Dr. Chilukamari Rajesh
Assistant Professor, VIT-AP
Ph.D. (NIT Warangal)
M.Tech. (NIT Sikkim)
Module 5: The Collections Framework and Generic Programming

➢ Collection overview
➢ Collection interface - List, Set, Map
➢ Collection Classes - ArrayList, HashSet, HashMap
➢ Iterator-For-Each-Comparators
➢ Wrapper classes
➢ Motivation for Generic Programming – Generic Classes and Methods – Bounded
Types –Wildcard Arguments –Generic Constructors and Interfaces.
Arrays vs Collections
Collection & Collection Framework
● A Collection represents a group of individual objects that represent a single entity

What is a framework in Java


● It represents a set of classes and interfaces
● It provides readymade architecture
● It is optional

● The Collection framework represents a unified architecture for storing and


manipulating a group of objects.
Collections Framework
● Collection Framework is a group of classes and interfaces which can be used to
represent a group of objects as a single entity
● It contains prepackaged data structures, interfaces, algorithms for manipulating those
data structures
● It has:
○ Interfaces and its implementations, i.e., classes
○ Algorithm
● In C++, you can compare Collection with Containers and Collection Framework with
STL (Standard Template Library)
Collection interface
● It is the partial root interface of the Collection Framework
● Contains the most common methods (adding, removing, clearing, etc) which are
applicable to any Collection object
● These methods are implemented by all the classes irrespective of their style of
implementation
● This interface builds a foundation on which the collection classes are implemented
Common methods in Collection
SN Method Description

1 public boolean add(E e) It is used to insert an element in this collection.

2 public boolean addAll(Collection<? extends It is used to insert the specified collection elements in the invoking
E> c) collection.

3 public boolean remove(Object element) It is used to delete an element from the collection.

4 public boolean removeAll(Collection<?> c) It is used to delete all the elements of the specified collection from the
invoking collection.

5 default boolean removeIf(Predicate<? super It is used to delete all the elements of the collection that satisfy the
E> filter) specified predicate.

6 public boolean retainAll(Collection<?> c) It is used to delete all the elements of invoking collection except the
specified collection.

7 public int size() It returns the total number of elements in the collection.

8 public void clear() It removes the total number of elements from the collection.
Iterators
● Iterators in Java are used in the Collection framework to retrieve elements one by one.
● It is a universal iterator as we can apply it to any Collection object.
● By using Iterator, we can perform both read and remove operations.

S No. Method Description

1 public boolean hasNext() It returns true if the iterator has more elements otherwise it returns false.

2 public Object next() It returns the element and moves the cursor pointer to the next element.

3 public void remove() It removes the last elements returned by the iterator. It is less used.
Collections class
● Collections class is one of the utility classes in Java Collections Framework.
● The Collections class is present in the java.util package.
● Java Collections class is used with the static methods that operate on the collections
or return the collection.
● All the methods of this class throw the NullPointerException if the collection or
object passed to the methods is null.
Collection Class declaration
● The syntax of the Collection class declaration is mentioned below:
public class Collections extends Object
List
● It is a child interface of the collection interface.
● This interface is dedicated to the data of the list type in which we can store all the
ordered collections of the objects.
● It also allows duplicate data to be present in it.
● The list interface is implemented by various classes like ArrayList, Vector, Stack,
etc.
● Since all the subclasses implement the list, we can instantiate a list object with any
of these classes.
● For example:
List <T> al = new ArrayList<> ();
List <T> ll = new LinkedList<> ();
List <T> v = new Vector<> ();
Where T is the type of the object
Operations in a Java List Interface
● Since List is an interface, it can be used only with a class that implements this
interface.
● Some methods that frequently used on the List:
○ add(): used to add the elements to List class
○ set(): used to update the elements in List class
○ indexOf() / lastIndexOf: used to search for elements in List class
○ remove(): used to remove the elements from List class
○ get(): used to access the elements in List class
○ contains(): used to check if an element is present in the List class
ArrayList
● ArrayList provides us with dynamic arrays in Java.
● The size of an ArrayList is increased automatically if the collection grows or shrinks
if the objects are removed from the collection.
● Java ArrayList allows us to randomly access the list.
● ArrayList can not be used for primitive types, like int, char, etc. We will need a
wrapper class for such cases.
● Though, it may be slower than standard arrays but can be helpful in programs where
lots of manipulation in the array is needed.
Example 1
import java.io.*;
import java.util.*;
class ArrayListTest {
public static void main(String[] args) {

// Declaring the ArrayList with initial size n


ArrayList<Integer> al = new ArrayList<Integer>();

// Appending new elements at the end of the list


for (int i = 1; i <= 5; i++)
al.add(i);

// Printing elements
System.out.println(al);

// Remove element at index 3


al.remove( 3); //index

// Displaying the ArrayList after deletion


System.out.println(al); Output
[1, 2, 3, 4, 5]
// Printing elements one by one [1, 2, 3, 5]
for (int i = 0; i < al.size(); i++)
1 2 3 5
System.out.print(al.get(i) + " ");
}
}
Example 2
import java.util.*;
class ListExample {
public static void main(String args[]) {
List<String> al = new ArrayList<>(); // Creating an object of List interface
// Adding elements to object of List class
al.add("Object");
al.add(1, "Programming");

// Setting (updating) element at 1st index using set() method


al.set(1, "Oriented");

// use indexOf() to find the first occurrence of an element in the list


int index = al.indexOf(“Oriented”);
System.out.println("The first occurrence of Oriented is at index " + index);

// use lastIndexOf() to find the last occurrence of an element in the list


int lastIndex = al.lastIndexOf(“Oriented”);
System.out.println("The last occurrence of Oriented is at index " + lastIndex);

// Accessing elements using get() method


System.out.println(al.get(0));

// Checking if element is present using contains() method


System.out.println(al.contains("Object"));

// Now remove element from the above list present at 1st index
al.remove(1);
al.remove("Object"); // Now remove the current object from the updated List

System.out.println("ArrayList " + al); // Print and display the List


}
}
Example 2
import java.util.*;
class ListExample {
public static void main(String args[]) {
List<String> al = new ArrayList<>(); // Creating an object of List interface
// Adding elements to object of List class
al.add("Object");
al.add(1, "Programming");

// Setting (updating) element at 1st index using set() method


al.set(1, "Oriented");

// use indexOf() to find the first occurrence of an element in the list


int index = al.indexOf(“Oriented”);
System.out.println("The first occurrence of Oriented is at index " + index);

// use lastIndexOf() to find the last occurrence of an element in the list


int lastIndex = al.lastIndexOf(“Oriented”);
System.out.println("The last occurrence of Oriented is at index " + lastIndex);

// Accessing elements using get() method Output


System.out.println(al.get(0)); [Object, Oriented]
The first occurrence of Oriented is at index 1
// Checking if element is present using contains() method The last occurrence of Oriented is at index 1
System.out.println(al.contains("Object"));
Object
// Now remove element from the above list present at 1st index true
al.remove(1); ArrayList []
al.remove("Object"); // Now remove the current object from the updated List

System.out.println("ArrayList " + al); // Print and display the List


}
}
Set
● It is a child interface of the collection interface
● Insertion order is not preserved
● It not allows duplicate data to be present in it
● The Set interface is implemented by various classes like HashSet, TreeSet, SortedSet,
etc
● Since all the subclasses implement the set, we can instantiate a set object with any of
these classes
● For example:
Set <T> hs = new HashSet<> ();
Set <T> ts = new TreeSet<> ();
Set <T> ss = new SortedSet<> ();
Where T is the type of the object
HashSet
● Java HashSet class is used to create a collection that uses a hash table for storage.
● It inherits the AbstractSet class and implements Set interface.
● HashSet contains unique elements only and allows null value.
● HashSet stores the elements by using a mechanism called hashing.
● Hashing is a technique of converting a large String to a small String that represents
the same String.
● A shorter value helps in indexing and faster searches.
● HashSet doesn't maintain the insertion order. The elements are inserted on the basis
of their hashcode.
● HashSet is the best approach for search operations.
Constructors of Java HashSet class
SN Constructor Description

1) HashSet() It is used to construct a default HashSet.

2) HashSet(int capacity) It is used to initialize the capacity of the hash set to the given integer value

capacity. The capacity grows automatically as elements are added to the

HashSet.

3) HashSet(int capacity, float It is used to initialize the capacity of the hash set to the given integer value

loadFactor) capacity and the specified load factor.

4) HashSet(Collection<? extends E> c) It is used to initialize the hash set by using the elements of the collection c.
Example 1
import java.util.*;
class SetExample2 {
public static void main(String[] args) {
// Creating object of Set of type String
Set<String> h = new HashSet<String>();
// Adding elements into the HashSet using add() method
h.add("India");
h.add("Australia");
h.add("South Africa");
h.add("India");
// Displaying the HashSet
System.out.println(h);
// Removing items from HashSet using remove() method
h.remove("Australia"); //value
System.out.println("Set after removing " + "Australia:" + h);
// Iterating over hash set items
System.out.println("Iterating over set:");
// Iterating through iterators
Iterator<String> i = h.iterator();
// It holds true till there is a single element remaining in the object
while (i.hasNext())
System.out.println(i.next());
}
}
Example 1
import java.util.*;
class SetExample2 {
public static void main(String[] args) {
// Creating object of Set of type String
Set<String> h = new HashSet<String>();

// Adding elements into the HashSet using add() method


h.add("India");
h.add("Australia");
h.add("South Africa");
h.add("India");

// Displaying the HashSet


System.out.println(h);

// Removing items from HashSet using remove() method


h.remove("Australia");
Output
System.out.println("Set after removing " + "Australia:" + h); [South Africa, Australia, India]
Set after removing
// Iterating over hash set items Australia:[South Africa, India]
System.out.println("Iterating over set:");
Iterating over set:
// Iterating through iterators South Africa
Iterator<String> i = h.iterator(); India

// It holds true till there is a single element remaining in the object


while (i.hasNext())
System.out.println(i.next());
}
}
Example 2
import java.util.*;
public class SetExample {
public static void main(String args[]) {
// Creating an object of Set class // Declaring object of Integer type
Set<Integer> a = new HashSet<Integer>();
// Adding all elements to List
a.addAll(Arrays.asList( new Integer[] { 1, 3, 2, 4, 8, 9, 0 }));
// Again declaring object of Set class with reference to HashSet
Set<Integer> b = new HashSet<Integer>();
b.addAll(Arrays.asList( new Integer[] { 1, 3, 7, 5, 4, 0, 7, 5 }));
// To find union
Set<Integer> union = new HashSet<Integer>(a);
union.addAll(b);
System.out.print( "Union of the two Set" );
System.out.println(union);
// To find intersection
Set<Integer> intersection = new HashSet<Integer>(a);
intersection.retainAll(b);
System.out.print( "Intersection of the two Set" );
System.out.println(intersection);
// To find the symmetric difference
Set<Integer> difference = new HashSet<Integer>(a);
difference.removeAll(b);
System.out.print( "Difference of the two Set" );
System.out.println(difference);
}
}
Example 2
import java.util.*;
public class SetExample {
public static void main(String args[]) {
// Creating an object of Set class // Declaring object of Integer type
Set<Integer> a = new HashSet<Integer>();

// Adding all elements to List


a.addAll(Arrays.asList(new Integer[] { 1, 3, 2, 4, 8, 9, 0 }));

// Again declaring object of Set class with reference to HashSet


Set<Integer> b = new HashSet<Integer>();
b.addAll(Arrays.asList(new Integer[] { 1, 3, 7, 5, 4, 0, 7, 5 }));

// To find union
Set<Integer> union = new HashSet<Integer>(a);
union.addAll(b);
System.out.print("Union of the two Set");
System.out.println(union);

// To find intersection
Set<Integer> intersection = new HashSet<Integer>(a);
intersection.retainAll(b);
System.out.print("Intersection of the two Set"); Output
System.out.println(intersection); Union of the two Set[0, 1, 2, 3, 4, 5, 7, 8,
9]
// To find the symmetric difference
Set<Integer> difference = new HashSet<Integer>(a);
Intersection of the two Set[0, 1, 3, 4]
difference.removeAll(b); Difference of the two Set[2, 8, 9]
System.out.print("Difference of the two Set");
System.out.println(difference);
}
}
Map
● Map represents a mapping between a key and a value.
● Java Map interface is not a subtype of the Collection interface. Therefore it behaves a
bit differently from the rest of the collection types.
● Maps are perfect to use for key-value association mapping such as dictionaries.
● The maps are used to perform lookups by keys or when someone wants to retrieve
and update elements by keys.
● Some common scenarios are as follows:
○ A map of error codes and their descriptions.
○ A map of zip codes and cities.
○ A map of managers and employees. Each manager (key) is associated with a list
of employees (value) he manages.
○ A map of classes and students. Each class (key) is associated with a list of
students (value).
HashMap
● HashMap provides the basic implementation of the Map interface of Java.
● It stores the data in (Key, Value) pairs.
● To access a value one must know its key.
● It uses a technique called Hashing to store the data.
Iterating over a Map
● We cannot iterate a Map directly using iterators, because Map are not Collection.

Map.entrySet() using For-Each loop :


Map.entrySet() method returns a collection-view(Set<Map.Entry<K, V>>) of the mappings
contained in this map. So we can iterate over key-value pair using getKey() and getValue()
methods of Map.Entry<K, V>.
Example1
import java.util.*;

class HashMapExample {
public static void main(String args[]) {
// Creating an empty HashMap
Map<String, Integer> hm = new HashMap<String, Integer>();

// Inserting pairs in above Map using put() method


hm.put("a", 100);
hm.put("b", 200);
hm.put("c", 300);
hm.put("d", 400);

// Traversing through Map using for-each loop


for (Map.Entry<String, Integer> me : hm.entrySet()) {
// Printing keys
System.out.print(me.getKey() + ":");
System.out.println(me.getValue());
}
}
}
Example1
import java.util.*;

class HashMapExample {
public static void main(String args[]) {
// Creating an empty HashMap
Map<String, Integer> hm = new HashMap<String, Integer>();

// Inserting pairs in above Map using put() method


hm.put("a", 100);
hm.put("b", 200);
hm.put("c", 300);
hm.put("d", 400); Output:
a:100
// Traversing through Map using for-each loop b:200
for (Map.Entry<String, Integer> me : hm.entrySet()) { c:300
// Printing keys d:400
System.out.print(me.getKey() + ":");
System.out.println(me.getValue());
}
}
}
Example 2
import java.util.*;
class HashMapExample2 {
public static void main(String args[]) {
// Initialization of a Map using Generics
Map<Integer, String> hm1 = new HashMap<Integer, String>();

// Inserting the Elements


hm1.put(1, "VIT");
hm1.put(2, "AP");
hm1.put(3, "Amaravati");

// Initial Map
System.out.println("Initial Map " + hm1);

hm1.put(2, "Andhra Pradesh");


hm1.remove(3); //key

for (Map.Entry mapElement : hm1.entrySet()) {


int key = (int)mapElement.getKey();
// Finding the value
String value = (String)mapElement.getValue();
System.out.println(key + " : " + value);
}
}
}
Example 2
import java.util.*;
class HashMapExample2 {
public static void main(String args[]) {
// Initialization of a Map using Generics
Map<Integer, String> hm1 = new HashMap<Integer, String>();

// Inserting the Elements


hm1.put(1, "VIT");
hm1.put(2, "AP");
hm1.put(3, "Amaravati");

// Initial Map
System.out.println("Initial Map " + hm1); Output:
Initial Map {1=VIT, 2=AP, 3=Amaravati}
hm1.put(2, "Andhra Pradesh");
hm1.remove(3); //key
1 : VIT
for (Map.Entry mapElement : hm1.entrySet()) { 2 : Andhra Pradesh
int key = (int)mapElement.getKey();
// Finding the value
String value = (String)mapElement.getValue();
System.out.println(key + " : " + value);
}
}
}
Example 3
import java.util.*;
class Hash2{
public static void main(String args[]){
Map<Integer,String> map=new HashMap<Integer,String>();
map.put(1,"vijay");
map.put(4,"umesh");
map.put(2,"ankit");
//Map.Entry for Set and Iterator
Set<Map.Entry<Integer,String>> set=map.entrySet();
Output
Iterator<Map.Entry<Integer,String>> itr=set.iterator();
while(itr.hasNext()) { 1 vijay
2 ankit
Map.Entry e=itr.next();//no need to typecast
4 umesh
System.out.println(e.getKey()+" "+e.getValue());
}
}
}
Collection vs Collections
● Collection is an interface which can be used to represent a group of individual objects
as a single entity.
● Contains the most common methods which are applicable to any Collection object

● Collections is a utility class present in java.util package to define some utility


methods (like sorting, searching etc) for Collection objects.
Wrapper Class
● A wrapper class wraps (encloses) around a data type and gives it an object
appearance.
● Wrapper classes are final and immutable.
● Two concepts are there in the wrapper classes:
○ Autoboxing (Primitive -> Wrapper Class)
○ Unboxing (Wrapper Class -> Primitive)
Autoboxing
● Autoboxing is a procedure of converting a primitive value into an object of the
corresponding wrapper class.
● For example, converting int to Integer class.
● The Java compiler applies autoboxing when a primitive value is:
○ Passed as a parameter to a method that expects an object of the corresponding
wrapper class.
○ Assigned to a variable of the corresponding wrapper class.
Unboxing
● Unboxing is a procedure of converting an object of a wrapper type to its
corresponding primitive value.
● For example conversion of Integer to int.
● The Java compiler applies to unbox when an object of a wrapper class is:
○ Passed as a parameter to a method that expects a value of the corresponding
primitive type.
○ Assigned to a variable of the corresponding primitive type.
Features of Wrapper Classes
1. They convert primitive data types into objects. Objects are needed if we wish to
modify the arguments passed into a method (because primitive types are passed by
value).
2. The classes in java.util package handles only objects and hence wrapper classes help
in this case also.
3. Data structures in the Collection framework, such as ArrayList and Vector, store only
objects (reference types) and not primitive types.
4. An object is needed to support synchronization in multithreading.
5. Wrapper classes has a lot of utility methods.
Example 1
import java.io.*;

class WrapperClassExample1 {
public static void main(String[] args) {
// In java, in case of floating values they are stored as x = (y)f
// Conversion of float value to int
Float floatWrap = Float.valueOf(45.158f);

// Invoking the intValue() method over the stored float value to store
int floatToInt = floatWrap.intValue();

// Print the non-primitive(Integer) value


System.out.println(floatToInt);

// Convert the binary number to the integer value


Integer i = Integer.valueOf("101", 2); Output
45
// Print the number 5
System.out.println(i);
}
}
Generics
● The Java Generics programming is introduced in J2SE-5 to deal with type-safe
objects.
● Before generics, we can store any type of objects in the collection, i.e., non-generic.
Now generics force the java programmer to store a specific type of objects.
● Generics means parameterized types. The idea is to allow type (Integer, String, …
etc., and user-defined types) to be a parameter to methods, classes, and interfaces.
● Using Generics, it is possible to create classes that work with different data types.
● An entity such as class, interface, or method that operates on a parameterized type is a
generic entity.

● It makes the code stable by detecting the bugs at compile time.


Example 1
import java.io.*;
import java.util.*;

class ArrayListTest {
public static void main(String[] args) {

ArrayList al = new ArrayList();

al.add("Rajesh" );
al.add("Rahul" );
al.add(101 );
al.add(45.67 );

System.out.println(al);
}
}
Example 1
import java.io.*;
import java.util.*;

class ArrayListTest {
public static void main(String[] args) {

ArrayList al = new ArrayList();

al.add( "Rajesh");
al.add( "Rahul");
al.add( 101);
al.add( 45.67);

System.out.println(al);
}
}

Output
[Rajesh, Rahul, 101, 45.67]
Why Generics

Type-safety:
● We can hold only a single type of objects in generics.
● It doesn't allow to store other objects.

Before Generics, we can store any type of objects.


List list = new ArrayList();
list.add(10);
list.add("10");

After Generics, it is required to specify the type of object we need to store.


List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add("10");// compile-time error
Why Generics (Contd.)
● Type casting is not required: There is no need to typecast the object.
Before Generics, we need to type cast.
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0); // typecasting
After Generics, we don't need to typecast the object.
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0);

● Compile-Time Checking: It is checked at compile time so problem will not occur


at runtime.
List<String> list = new ArrayList<String>();
list.add("hello");
list.add(32); //Compile Time Error
Generic Programming
● Generics make a class, interface and, method, consider all (reference) types that are
given dynamically as parameters.
● Programmers can use the approach of generic programming to create code that is not
unique to any one data type.
● The code can instead be designed to deal with a variety of data types.
● The compiler takes care of the type of safety which enables programmers to code
easily since they do not have to perform long, individual type castings.
● Classes and methods are more adaptable and reusable when they may be
parameterized with one or more data types.
Type Parameters
● The type parameters naming conventions are important to learn generics thoroughly.
● The common type parameters are as follows:
1. T - Type
2. E - Element
3. K - Key
4. N - Number
5. V - Value
Generic Class
● A class that can refer to any type is known as a generic class.
● A generic class is implemented exactly like a non-generic class. The only difference is
that it contains a type parameter section.
● The classes, which accept one or more parameters, are known as parameterized
classes or parameterized types.
● There can be more than one type of parameter, separated by a comma.
● Generic class parameters are specified in angle brackets “<>” after the class name as
of the instance variable.
Generic Class (Contd.)
Creating a generic class:
class MyGen<T>{ }

● The ‘T’ type indicates that it can refer to any type (like String, Integer, and Employee). The type you
specify for the class will be used to store and retrieve the data.

Creating objects of a generic class:


MyGen <T> obj = new MyGen <T>()

Note: In Parameter type we can not use primitives like ‘int’,’char’ or ‘double’.
Example 1
// 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); Output
System.out.println(iObj.getObject()); 15
OOPs
// instance of String type
Test<String> sObj = new Test<String>("OOPs");
System.out.println(sObj.getObject());
}
}
Example 2
class MyGen<T> {
T obj;
void add(T obj){
this.obj=obj;
}
T get(){
return obj;
}
}

class TestGenerics {
public static void main(String args[]){
MyGen<Integer> m=new MyGen<Integer>();
m.add(2);
m.add("vivek");
System.out.println(m.get());
}
}
Example 2
class MyGen<T> {
T obj;
void add(T obj){
this.obj=obj;
}
T get(){
return obj;
}
}

class TestGenerics {
public static void main(String args[]){ Output
MyGen<Integer> m=new MyGen<Integer>();
m.add(2); Compile time error
m.add("vivek");
System.out.println(m.get());
}
}
Example 3
public class AddNumbers<T extends Number> {
T num1, T num2;
public AddNumbers(T num1, T num2) {
this.num1 = num1;
this.num2 = num2;
}
public T add() {
if (num1 instanceof Integer) {
return (T) (Integer) (num1.intValue() + num2.intValue());
} else if (num1 instanceof Double) {
return (T) (Double) (num1.doubleValue() + num2.doubleValue());
} else { return null; }
}
public static void main(String[] args) {
AddNumbers<Integer> intAdder = new AddNumbers<>(2, 3);
Integer intResult = intAdder.add();
System.out.println("Integer Result: " + intResult);
AddNumbers<Double> doubleAdder = new AddNumbers<>(2.5, 3.5);
Double doubleResult = doubleAdder.add();
System.out.println("Double Result: " + doubleResult);
}
}
Example 3
public class AddNumbers<T extends Number> {
T num1, T num2;
public AddNumbers(T num1, T num2) {
this.num1 = num1;
this.num2 = num2;
}
public T add() {
if (num1 instanceof Integer) {
return (T) (Integer) (num1.intValue() + num2.intValue());
} else if (num1 instanceof Double) {
return (T) (Double) (num1.doubleValue() + num2.doubleValue());
} else { return null; }
}
public static void main(String[] args) {
AddNumbers<Integer> intAdder = new AddNumbers<>(2, 3); Output:
Integer intResult = intAdder.add();
System.out.println("Integer Result: " + intResult); Integer Result: 5
AddNumbers<Double> doubleAdder = new AddNumbers<>(2.5, 3.5); Double Result: 6.0
Double doubleResult = doubleAdder.add();
System.out.println("Double Result: " + doubleResult);
}
}
Example 4
public class Pair<T, U> {
private T first;
private U second;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst() { return first; }
public U getSecond() { return second; }
public static void main(String[] args) {
Pair<Integer, String> intStrPair = new Pair<>(10, "hello");
System.out.println("First Value: " + intStrPair.getFirst());
System.out.println("Second Value: " + intStrPair.getSecond());
Pair<Double, Character> doubleCharPair = new Pair<>(3.14, 'a');
System.out.println("First Value: " + doubleCharPair.getFirst());
System.out.println("Second Value: " + doubleCharPair.getSecond());
}
}
Example 4
public class Pair<T, U> {
private T first;
private U second;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
public T getFirst() { return first; }
public U getSecond() { return second; }
public static void main(String[] args) {
Pair<Integer, String> intStrPair = new Pair<>(10, "hello");
Output:
System.out.println("First Value: " + intStrPair.getFirst());
System.out.println("Second Value: " + intStrPair.getSecond()); First Value: 10
Pair<Double, Character> doubleCharPair = new Pair<>(3.14, 'a'); Second Value: hello
System.out.println("First Value: " + doubleCharPair.getFirst()); First Value: 3.14
System.out.println("Second Value: " + doubleCharPair.getSecond()); Second Value: a
}
}
Generic Method
● Like the generic class, we can create a generic method that can accept any type of
arguments.
● It is exactly like a normal function, however, a generic method has type parameters
that are cited by actual type. This allows the generic method to be used in a more
general way.
● The type parameter must be placed after the public/static keyword and before the
return type of generic method.
● Here, the scope of arguments is limited to the method where it is declared.
● It allows static as well as non-static methods.
Example 1
class Test {

// A Generic method example


static <T> void genericDisplay(T element) {
System.out.println(element.getClass().getName() + " = " + element);
}

public static void main(String[] args) {


// Calling generic method with Integer argument
genericDisplay(11);

// Calling generic method with String argument


genericDisplay("OOPs");

// Calling generic method with double argument


Output
java.lang.Integer = 11
genericDisplay(1.0);
java.lang.String = OOPs
}
java.lang.Double = 1.0
}
Example 2
public class TestGenerics2 {
public static < E > void printArray(E[] elements) {
for ( E element : elements) { Output:
System.out.println(element ); Printing Integer Array
} 10
20
}
30
40
public static void main( String args[] ) { 50
Integer[] intArray = { 10, 20, 30, 40, 50 }; Printing Character Array
Character[] charArray = { 'J', 'A', 'V', 'A', 'T','P','O','I','N','T' }; J
A
V
System.out.println( "Printing Integer Array" ); A
printArray( intArray ); T
P
System.out.println( "Printing Character Array" ); O
printArray( charArray ); I
N
}
T
}
Example 3
import java.util.Arrays;
public class FindMax {
public static <T extends Comparable<T>> T findMax(T[] arr) {
Arrays.sort(arr);
return arr[arr.length - 1];
}

public static void main(String[] args) {


Integer[] intArr = {1, 5, 3, 2, 4};
String[] strArr = {"cat", "dog", "elephant", "bird"};

Integer maxInt = findMax(intArr); Output:


System.out.println("Max Integer: " + maxInt);
Max Integer: 5

String maxStr = findMax(strArr); Max String: elephant


System.out.println("Max String: " + maxStr);
}
}
Example 4
public class PrintArray {
public static <T> void printArray(T[] arr) {
for (T elem : arr) {
System.out.print(elem + " ");
}
}

public static void main(String[] args) {


Integer[] intArr = {1, 2, 3, 4, 5};
String[] strArr = {"cat", "dog", "elephant", "bird"};
System.out.print("Integer Array: ");
printArray(intArr); Output:
Integer Array: 1 2 3 4 5
System.out.print("String Array: ");
String Array: cat dog elephant bird
printArray(strArr);
}
}
Generic Constructors
● Generic constructors are the same as generic methods.
● The type parameter must be placed after the public keyword and before the class
name for generic constructors.
● Constructors can be invoked with any type of a parameter after defining a generic
constructor.
● Constructors can be Generic, despite its class is not Generic.
Example 1
import java.io.*;

class GenericConstructor {
private double v;
// Constructor of this class where T is typename and t is object
<T extends Number> GenericConstructor(T t) {
// Converting input number type to double using the doubleValue() method
v = t.doubleValue();
}
void show() {
System.out.println( "v: " + v);
}
}

class GenericConstructor {
public static void main(String[] args) {
System.out.println( "Number to Double Conversion:" );
// Creating objects of type GenericConstructor
GenericConstructor obj1 = new GenericConstructor( 10);
GenericConstructor obj2 = new GenericConstructor( 136.8F);

obj1.show(); Output
obj2.show(); Number to Double Conversion:
} v: 10.0
} v: 136.8000030517578
Generic Interfaces
● Generic Interfaces in Java are the interfaces that deal with different data types.
● It allows putting constraints i.e. bounds on data types for which interface is
implemented.

Syntax:
interface interface-Name < type-parameter-list > {//....}

class class-name <type-parameter-list> implements interface-name


<type-arguments-list> {//...}
Example 1
import java.io.*;

interface MinMax <T extends Comparable<T> > {


T min();
T max();
}

class MyClass <T extends Comparable<T> > implements MinMax<T> {


T[] values;
MyClass(T[] obj) { values = obj; } // Constructor
// Defining abstract min() method
public T min() {
// 'T' is typename and 'o1' is object_name
// main method
T o1 = values[0];
public static void main(String[] args) {
for (int i = 1; i < values.length; i++) Integer arr[] = { 3, 6, 2, 8, 6 };
if (values[i].compareTo(o1) < 0) MyClass<Integer> obj1 = new MyClass<Integer>(arr);
o1 = values[i]; System.out.println("Minimum value: " + obj1.min());
return o1; System.out.println("Maximum value: " + obj1.max());
} }
}
// Defining abstract max() method
public T max() {
// 'T' is typename and 'o1' is object_name
T o1 = values[0];
for (int i = 1; i < values.length; i++)
if (values[i].compareTo(o1) > 0)
o1 = values[i]; Output
return o1; Minimum value: 2
} Maximum value: 8
Example 2
import java.util.Arrays;
public interface Sortable<T> {
public int compare(T obj);
}

class Person implements Sortable<Person> {


private String name;
public static void main(String[] args) {
private int age;
Person[] people = { new Person("John", 20),
public Person(String name, int age) {
new Person("Mary", 25),
this.name = name;
new Person("David", 18),
this.age = age;
new Person("Sarah", 22) };
}
System.out.println("Before Sorting: " + Arrays.toString(people));
public int compare(Person other) {
Arrays.sort(people, (p1, p2) -> p1.compare(p2));
return this.age - other.age;
System.out.println("After Sorting: " + Arrays.toString(people));
}
}
public String toString() {
}
return "Name: " + name + ", Age: " + age;
}

Output:
Before Sorting: [Name: John, Age: 20, Name: Mary, Age: 25, Name: David, Age: 18, Name: Sarah, Age: 22]
After Sorting: [Name: David, Age: 18, Name: John, Age: 20, Name: Sarah, Age: 22, Name: Mary, Age: 25]

You might also like