0% found this document useful (0 votes)
52 views75 pages

Generics Slide

Generics in Java allow types (classes and interfaces) to be parameters when defining classes, interfaces, and methods. This provides compile-time type safety and eliminates the need for type casting. Generics add stability to code by making errors detectable at compile time rather than runtime. They enable code reuse by allowing the same code to operate on different types. Bounded types allow restricting the types that can be used as type arguments, while wildcards allow for more flexible subtyping relationships between parameterized types.

Uploaded by

SELF DISTRUCTURE
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)
52 views75 pages

Generics Slide

Generics in Java allow types (classes and interfaces) to be parameters when defining classes, interfaces, and methods. This provides compile-time type safety and eliminates the need for type casting. Generics add stability to code by making errors detectable at compile time rather than runtime. They enable code reuse by allowing the same code to operate on different types. Bounded types allow restricting the types that can be used as type arguments, while wildcards allow for more flexible subtyping relationships between parameterized types.

Uploaded by

SELF DISTRUCTURE
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/ 75

Generics

(Java Programming)
Generics in Java
• generics are a facility of generic programming
• these features were added to the Java programming language back in
2004 within version J2SE 5.0
• they were designed to extend Java's type system to allow a type or
method to operate on objects of various types while providing
compile-time type safety
Generics in Java
• in software engineering bugs are simply a fact of life
• but some bugs are easier to detect than others
• there are 2 main types of bugs and errors

1.) COMPILE TIME ERRORS

2.) RUN-TIME ERRORS


Generics in Java

RUN-TIME ERRORS COMPILE TIME ERRORS


run-time errors are more it is easy to detect them
problematic as the application will not compile

don’t always surface immediately cmpiler’s error messages


and it may be at a point in the help to figure out what
program that is far from the the problem is
actual cause of the problem
compile time errors can
be fixed easily
Why to Use Generics?
• generics add stability to your code
• it makes most of the bugs and errors to be detectable at compile time
and not at run-time

WE PREFER COMPILE TIME ERRORS


TO RUN-TIME ERRORS !!!
Why to Use Generics?
• generics enable types (classes and interfaces) to be parameters when
defining classes, interfaces and methods
• we can reuse the same code with different inputs
Why to Use Generics?
• generics enable types (classes and interfaces) to be parameters when
defining classes, interfaces and methods
• we can reuse the same code with different inputs

public void draw(Car car)

in this case the car


parameter is a value
Why to Use Generics?
• generics enable types (classes and interfaces) to be parameters when
defining classes, interfaces and methods
• we can reuse the same code with different inputs

public void draw(T t)

in this case the car


parameter is a generic type
Why to Use Generics?
Generics has many benefits over non-generic code

1.) STRONGER TYPE CHECKS AT COMPILE TIME

If our code violates type safety then the compiler warns us


and this is exactly why we prefer compile time errors
Why to Use Generics?
Generics has many benefits over non-generic code

2.) WE CAN ELIMINATE TYPE CASTING

It is not a good programming practise to do type castings – we should


use generics instead
Why to Use Generics?
Generics has many benefits over non-generic code

2.) WE CAN ELIMINATE TYPE CASTING

List list = new ArrayList();


String name = (String) list.get(0);

in this case we do not use generics which means


we have to cast the objects into Strings
(the JVM must test type castibility at run-time)
Why to Use Generics?
Generics has many benefits over non-generic code

2.) WE CAN ELIMINATE TYPE CASTING

List<String> list = new ArrayList<>();


String name = list.get(0);

in this case we use generics which means


we do not have to cast the objects into Strings
(the compiler knows the types so no need to check them)
Why to Use Generics?
Generics has many benefits over non-generic code

3.) GENERIC ALGORITHMS


We can implement generic algorithms and methods and
we can reuse them whenever we want

For example: sorting integers, floats or doubles

ANOTHER ADVANTAGE IS THAT IT IS EASIER


TO READ GENERIC CODE
Bounded Types
(Java Programming)
Bounded Generic Types
• sometimes we want to restrict the types that can be used as type
arguments in a parameterized type
• a method that operates on numbers (integers, floats or doubles) might
only want to accepts instances of the Number class or its subclasses
• this is exactly why there are bounded type parameters
• bounded types allow you to invoke methods defined in the bounds
Bounded Generic Types

<T extends Comparable>

it is misleading because no matter we are dealing with classes


or interfaces – we have to use the extends keyword

(now we can inoke the methods defined in the Comparable


Interface when dealing with the T generic variable)
Bounded Generic Types

<T extends B1 & B2 & B3>

it is misleading because no matter we are dealing with classes


or interfaces – we have to use the extends keyword

WE CAN DEFINE MULTIPLE BOUNDS !!!


Type Inference
(Java Programming)
Type Inference
• type inference is the ability of the compiler to look at each method
invocation and corresponding declaration
• in order to determine the type argument(s) – such as T generic type –
that make the invocation applicable

THE TYPE INFERENCE ALGORITHM DETERMINES THE


<T> TYPE OF THE ARGUMENTS

+ the type that the result is being assigned


or returned if available
Type Inference

public <T> T getData(T t1, T t2) {


return t1;
}

the type inference algorithm tries to most specific


type that works with all of the arguments

Serializable s = getData(”Hello World”, new ArrayList<>());


Type Inference

List<String> list = new ArrayList<>();

because of the type inference algorithm we can use


class instantiation like this

THERE IS NO NEED TO SPECIFY THE TYPE


BECAUSE OF TYPE INFERENCE !!!

type inference enables us to invoke a generic method


as an ordinary Java method without specifying the type
Wildcards
(Java Programming)
Subtyping
• subtyping is a fundamental principle in object-oriented programming
• one type is a subtype of another if they are related by an extends or
implements clause

Integer is a subtype of Number


ArrayList<E> is a subtype of List<E>
List<E> is a subtype of Collection<E>

• if one type is a subtype of another then it means that the second is a


supertype of the first
Subtyping

Integer is a subtype of Number


List<Integer> is NOT a subtype of List<Number>

despite the fact that Integer is a Number


because of inheritance

A LIST<INTEGER> IS NOT A SUBTYPE OF LIST<NUMBER> !!!

this is the reason why we need to


consider wildcards
Subtyping
public void print(Collection<Object> c) {
for(Object o : c)
System.out.println(o);
}

despite the fact that Integer is a Number


because of inheritance

A LIST<INTEGER> IS NOT A SUBTYPE OF LIST<NUMBER> !!!

this is the reason why we need to


consider wildcards – the supertype of all kinds of
collections are wildcards
Subtyping
public void print(Collection<?> c) {
for(Object o : c)
System.out.println(o);
}

despite the fact that Integer is a Number


because of inheritance

A LIST<INTEGER> IS A SUBTYPE OF COLLECTION<?> !!!

we can print anything we want (integers, doubles or strings)


but we can not insert into this collection because
we do not know the type
Upper Bounded Wildcards
(Java Programming)
Upper Bounded Wildcards
• we may want to use wildcards with subtypes so child classes
• for example we want to show the items in a List<Rectangle> when the
Rectangle is a Shape

printAll(List<? extends T>)

• this method can accept a list of any subclass of T


Upper Bounded Wildcards
• what if we want to add an item when using an upper bounded
wildcard?

addItem(List<? extends Number>)

• we can not add an Integer to the list because the type can not be
guaranteed – it may be a List<Double>
• we can not add a Double to the list because the type can not be
guaranteed – it may be a List<Integer>
Upper Bounded Wildcards

we can read items from a


List<? extends T>

we can not insert (add) items


Into a List<? extends T>

you can not add an item to a List<? Extends T> because you
can not guarantee what list it is really pointing to. The only thing you can do
for sure is to read the items
Lower Bounded Wildcards
(Java Programming)
Lower Bounded Wildcards
• we may want to use wildcards with supertypes so parent classes
• this is usually useful when we want to insert items into a generic data
structure or collection

printAll(List<? super T>)

• this method can accept a list of any superclass of T


Lower Bounded Wildcards
• what if we want to add an item when using an upper bounded
wildcard?

addItem(List<? super Integer>)

• we can add an Integer to the list without any problem


• we can add Numbers or even Objects to the list becuase Number and
Object are superclasses of Integer
Lower Bounded Wildcards

we can not read items from a


List<? super T> just Objects

we can insert (add) items


into a List<? super T>

you can not read items from a List<? super T> because you
can not guarantee what list it is really pointing to – we can read Objects exclusively.
We can insert subtypes of T into a List<? super T>
Wildcards and Bounded Types
(Java Programming)
Bounded Types and Wildcards
• there is the so-called get and put principle
• use upper bounded wildcard (extends) when you only get values out of
a structure or collection
• use lower bounded wildcard (super) when you only put values into a
structure or collection

DO NOT USE WILDCARDS (?) IF YOU WANT TO


DO READ AND WRITE AS WELL

• we can use bounded type parameters in these cases


Bounded Types and Wildcards
• there is a popular misconception about upper bounded wildcards
• it does not provide immutability

method(List<? extends T>)

It is true that we can not add items to this list


but we may add NULL or we may apply
other operations (for example sorting)
Bounded Types and Wildcards

WILDCARDS BOUNDED TYPES


we do not have access to the we can access the T
actual type (unknown type) generic type

wildcards can handle a single bounded type parameters


bound (extends or super) can handle multiple bounds

you should use wildcards you should use bounded type


whenever possible parameters if you want to
read and write as well
Type Erasure
(Java Programming)
Type Erasure
• Java uses type erasure to implement generics – this is how generic
code is handled
• it replaces all generic type parameters with their bounds or Object for
unbounded type parameters
• it is true for wildcards as well

SO THE FINAL BYTECODE WILL CONTAIN PLAIN


JAVA CLASSES AND OBJECTS !!!
Type Erasure
• it may happen that type erasure uses type casting
• sometimes it is needed to generate addition methods
• these are called bridge methods to maintain polymorphism with
generic types as well
Type Erasure

List<Integer> list = new ArrayList<>(); in the bytecode


list.add(3); the two code snippets
Integer num = list.get(0); are equvivalent

TYPE ERASURE

List list = new ArrayList(); there may be Objects


list.add(3); and type castings
Integer num = (Integer) list.get(0); in the bytecode
Collections
(Java Programming)
Collections Framework
• the Java collections framework is a set of classes and interfaces that
implement commonly reusable collection data structures
• for example lists, queues or maps
• the collections framework was designed and developed mainly by
Joshua Bloch and it was introduced in JDK 1.2
• we do not have to implement every algorithm and data structures
from scratch – these collections have been tested
Collections Framework
• almost all the collections (except for map) can be derived from
java.util.Collection interface
• the toArray() method can transform any Collection into a one-
dimensional array
• the Collection interface extends the java.lang.Iterable interface – this
is why we can use for-each loop
Collections Framework

List<String> names = new ArrayList<>();

names.add(”Adam”);
names.add(”Kevin”);
names.add(”Emily”);

Iterator<String> iter = list.iterator();

while(iter.hasNext())
System.out.println(iter.next());
Collections Framework

List<String> names = new ArrayList<>();

names.add(”Adam”);
names.add(”Kevin”);
names.add(”Emily”);

for(String name : names)


System.out.println(name);
Collections Framework
Iterable

Collection

List Queue Set

ArrayList PriorityQueue HashSet

LinkedList DEQUE LinkedHashSet

Vector ArrayDeque SortedSet

Stack TreeSet
Collections Framework
Map

HashTable

HashMap

LinkedHashMap

SortedMap

TreeMap
List
(Java Programming)
List
• the list interface is an ordered collection that allows us to store and
access items in a sequential manner
• it extends the Collection interface
• Lists can include duplicate elements (while sets can not)
• it gives the user full visibility and control over the ordering of its
elements
Maps Comparison
(Java Programming)
Maps Comparison
• HashMap and LinkedHashMap rely heavily on a one-dimensional
array and a hash-function
• this is why the average-case running time is O(1) that may be reduced
to O(N) because of collisions
• LinkedHashMap uses doubly-linked list data structure in addition to
maintain insertion order
• TreeMap uses balanced binary search tree
• there no collisions at all but running time is O(logN)
Maps Comparison
CHAINING: we store the items in the same bucket (with same indexes) in a
linked list data structure

KEY SPACE BUCKETS (array slots)


0
k1 h(k1) 1
v2 v4 v1 2
k5 k4 .
h(k2) .
k2 .
k3
m-2
h(k3) v3 m-1
Maps Comparison
CHAINING: we store the items in the same bucket (with same indexes) in a
linked list data structure

KEY SPACE BUCKETS (array slots)


0
k1 h(k1) 1
v2
k5 k4 .
h(k2) .
k2 .
k3
m-2
h(k3) v3 m-1
Maps Comparison

HashMap and
LinkedHashMap TreeMap
use arrays and hash-functions uses balanced binary
under the hood search trees + maintains order

we can achieve O(1) constant we can achieve guaranteed


running time O(logN) logarithmic running time

word case running time is can not store null keys


O(logN) + no parameters to tune !!!

can store null keys as well NEEDS LESS MEMORY !!!


Sets
(Java Programming)
Sets

„Sets are abstract data types that can store certain


values without any particular order and no
repeated values - no duplicates”
Sets
a common way of
visualizing sets is the
Venn-diagram approaches

WE CAN SHOW
A C A E
INTERACTIONS EASILY
WITH DIAGRAMS !!!
B D F D
there are several important
operations on sets such as
SET #1 SET #2 union or intersection
Sets
a common way of
visualizing sets is the
Venn-diagram approaches

WE CAN SHOW
C A E
INTERACTIONS EASILY
B D F WITH DIAGRAMS !!!

there are several important


operations on sets such as
SET #1 SET #2 union or intersection
Sets
a common way of
visualizing sets is the
Venn-diagram approaches

WE CAN SHOW
C A E
INTERACTIONS EASILY
B D F WITH DIAGRAMS !!!

there are several important


operations on sets such as
SET #1 SET #2 union or intersection
Sets
a common way of
visualizing sets is the
Venn-diagram approaches

WE CAN SHOW
C A E INTERACTIONS EASILY
B D F WITH DIAGRAMS !!!

there are several important


operations on sets such as
SET #1 SET #2 union or intersection
Sets
a common way of
visualizing sets is the
Venn-diagram approaches

WE CAN SHOW
C A E INTERACTIONS EASILY
B D F WITH DIAGRAMS !!!

there are several important


operations on sets such as
SET #1 SET #2 union or intersection
Sets Comparison
(Java Programming)
Sets Comparison
• HashSet and LinkedHashSet rely heavily on a one-dimensional array
and a hash-function
• this is why the average-case running time is O(1) that may be reduced
to O(N) because of collisions
• LinkedHashSet uses doubly-linked list data structure in addition to
maintain insertion order
• TreeSet uses balanced binary search tree
• there no collisions at all but running time is O(logN)
Sets Comparison
CHAINING: we store the items in the same bucket (with same indexes) in a
linked list data structure

KEY SPACE BUCKETS (array slots)


0
k1 h(k1) 1
v2 v4 v1 2
k5 k4 .
h(k2) .
k2 .
k3
m-2
h(k3) v3 m-1
Sets Comparison
CHAINING: we store the items in the same bucket (with same indexes) in a
linked list data structure

KEY SPACE BUCKETS (array slots)


0
k1 h(k1) 1
v2
k5 k4 .
h(k2) .
k2 .
k3
m-2
h(k3) v3 m-1
Sets Comparison

HashSet and
LinkedHashSet TreeSet
use arrays and hash-functions uses balanced binary
under the hood search trees + maintains order

we can achieve O(1) constant we can achieve guaranteed


running time O(logN) logarithmic running time

word case running time is can not store null keys


O(logN) + no parameters to tune !!!

can store null keys as well NEEDS LESS MEMORY !!!


Reflection
(Java Programming)
Reflection

“Reflection is a programming language’s ability to


inspect and dynamically call methods, classes etc.”
Reflection
• so we can inspect the source code dynamically at run-time
• because of object-oriented design (polymorphism) we may not know
the classes and methods at compile time
• we can get classes with getClass() method
Reflection

public interface Vehicle {



}

public class Bus implements Vehicle {



}

public class Car implements Vehicle {



}
Why to Use Reflection?
• reflection is important since it lets you write programs that do not
have to know everything at compile time
• such as inheritance relationships etc.
• this is how we can make dynamic programs as the classes and
methods may be tied together at run-time
• several frameworks use reflection - JUnit or Spring Framework
• for example JUnit looks for methods with the @Test annotations
• the framework will call these methods when we run the tests
Reflection in Frameworks
(Java Programming)
Spring Frameworks

<bean id="beanId" class="com.globalsoftwaresupport.Test">


<property name="name" value="Adam" />
<property name="age" value="36" />
</bean>

You might also like