You are on page 1of 74

CSE2005 - Object Oriented Programming

MODULE 4
Dr Divya Meena Sundaram
1
Sr. Asst Prof. Grade 1
SCOPE
VIT-AP University
MODULE NO. 4
THE COLLECTIONS FRAMEWORK AND
GENERIC PROGRAMMING
Collection overview - Collection interface – Collection Classes

List - Array List, Set - HashSet, Map - HashMap

Using an Iterator- For-Each- Comparators, Wrapper classes

Motivation for Generic Programming – Generic Classes and Methods – Bounded Types –

Wildcard Arguments –Generic Constructors and Interfaces.

Dr Divya Meena Sundaram 2


COLLECTIONS
 Collections are like containers that group multiple items in a single unit. For example, a jar of

chocolates, a list of names, etc.

 Java 1.2 provided Collections Framework that is the architecture to represent and manipulate

Collections in java in a standard way.

 Java Collections Framework consists of the following parts:

 Interfaces

 Implementation Class

 Algorithm
COLLECTION INTERFACE
1. Collection interface 6. Dequeue Interface

2. Iterator Interface 7. Map Interface

3. Set Interface 8. ListIterator Interface

4. List Interface 9. SortedSet Interface

5. Queue Interface 10. SortedMap Interface


COLLECTION INTERFACE
The Collection interface in Java is like a blueprint or template that defines a set of common methods for working
with collections of objects.

1. Adding Elements: add() and addAll() to add elements to the collection.

2. Removing Elements: remove() and removeAll() to remove elements from a collection.

3. Accessing Elements: contains() and isEmpty() methods help you check if a particular element exists in the
collection or determine if the collection is empty, respectively

4. Iterating over Elements: iterator() or enhanced for loop allows you to perform operations on each element
or process the collection as a whole.

5. Size and Manipulation: size() to get the number of elements in the collection; clear() to remove all
elements from the collection and retainAll() to retain only the elements specified in another collection.
 Collection Interface: The Collection interface is the foundation of the Java Collections Framework. It

defines common methods for working with collections, such as adding, removing, and accessing elements.

 List: A List is an ordered collection that allows duplicate elements. It maintains the insertion order, and you

can access elements by their index.

 Set: A Set is a collection that does not allow duplicate elements. It ensures uniqueness and does not maintain

a specific order for the elements.

 Map: A Map is an interface that maps unique keys to values. It stores key-value pairs and allows you to

retrieve a value based on its corresponding key.


 ArrayList: An ArrayList is an implementation of the List interface that uses an array internally to

store elements. It provides dynamic resizing and allows fast random access to elements.

 HashSet: HashSet is an implementation of the Set interface that uses a hash table to store elements. It

provides constant-time performance for basic operations but does not guarantee the order of elements.

 HashMap: HashMap is an implementation of the Map interface that uses a hash table to store key-

value pairs. It provides efficient key-based retrieval and allows null values and a single null key.
import java.util.ArrayList;

import java.util.Collection;

public class CollectionExample {

public static void main(String[] args) {

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

names.add("Alice"); names.add("Bob"); names.add("Charlie");

System.out.println("Contains Alice? " + names.contains("Alice"));

names.remove("Bob");

System.out.println("Collection after removing Bob: " + names);

System.out.println("Size of the collection: " + names.size());

names.clear();

System.out.println("Collection after clearing: " + names);

boolean isEmpty = names.isEmpty();

System.out.println("Is the collection empty? " + isEmpty);

}
LIST INTERFACE
The List interface in Java is a subinterface of the Collection interface. It represents an ordered collection of
elements where each element has an index associated with it.

1) Ordered Collection

2) Index-Based Access

3) Duplicates Allowed

4) Dynamic Size

5) Common Methods: These methods include get(int index) to retrieve an element at a specific index,
add(int index, E element) to insert an element at a specific index, remove(int index) to remove an
element at a specific index, and indexOf(Object element) to find the index of a specific element in
the list.

6) Implementations: ArrayList, LinkedList, and Vector.


import java.util.ArrayList;

import java.util.List;

public class ListExample {

public static void main(String[] args) {

List<Integer> numbers = new ArrayList<>();

numbers.add(10); numbers.add(20); numbers.add(30);

System.out.println("First number: " + numbers.get(0));

System.out.println("Modified list: " + numbers.set(1, 25));

System.out.println("Size of the list: " + numbers.size());

System.out.println("List elements:");

for (int number : numbers) {

System.out.println(number);

} } }
ARRAYLIST
 ArrayList is a Java class implemented using the List interface in the java.util package

 Java ArrayList, as the name suggests, provides the functionality of a dynamic array where the size is not

fixed as an array.

 As a part of the Collection framework, it has many features not available with arrays.
 Dynamic Size: An ArrayList can grow or shrink as you add or remove objects. You don't need

to decide on the size in advance, unlike arrays where you need to specify the size upfront.

 Ordered Elements: The objects you add to an ArrayList stay in the same order you added

them.

 Accessing Elements: Each object in an ArrayList has an index, starting from 0 for the first

object.

 Adding and Removing Objects: You can add objects to the ArrayList using the add()

method. You can also remove objects using the remove() method, which adjusts the size and
reorganizes the indices automatically.

 Objects of Any Type: ArrayList can store objects of any type, including numbers, strings, or

even custom objects that you create.


ADD ITEMS
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> cars = new ArrayList<String>();
cars.add("Volvo");
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");
System.out.println(cars);
}
}
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList cars = new ArrayList();
cars.add("Volvo");
cars.add("BMW");
cars.add(1);
cars.add(1.4);
System.out.println(cars);
}
}
 To access an element in the ArrayList, use the get() method and refer to the index number:

cars.get(0);

Array indexes start with 0: [0] is the first element. [1] is the second element, etc.

 To modify an element, use the set() method and refer to the index number:

cars.set(0, "Opel");

 To remove an element, use the remove() method and refer to the index number:

cars.remove(0);

 To remove all the elements in the ArrayList, use the clear() method:

cars.clear();

 To find out how many elements an ArrayList have, use the size method:

cars.size();
import java.util.ArrayList;

public class ArrayListExample {

public static void main(String[] args) {

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

numbers.add(10); numbers.add(20); numbers.add(30);

System.out.println("First number: " + numbers.get(0));

System.out.println("Modified list: " + numbers.set(1, 25));

numbers.remove(2);

System.out.println("List after removing an element: " + numbers);

}
SET INTERFACE
The Set interface in Java is a subinterface of the Collection interface. It represents a collection of unique
elements, meaning it doesn't allow duplicate values.

1. Unique Elements: If you try to add an element that already exists in the Set, it won't be added.

2. No Defined Order: The elements are stored in a way that makes the set efficient for searching and
eliminating duplicates.

3. Mathematical Set Operations: The Set interface provides methods to perform mathematical set
operations such as union, intersection, and difference between sets.

4. Fast Lookup: Sets are designed to provide fast lookup operations. You can quickly check whether
an element is present in the set using methods like contains().

5. Implementations: Java provides several classes that implement the Set interface, such as HashSet,
TreeSet, and LinkedHashSet.
import java.util.HashSet;

import java.util.Set;

public class SetExample {

public static void main(String[] args) {

Set<String> fruits = new HashSet<>();

fruits.add("Apple"); fruits.add("Banana");

fruits.add("Apple"); // Duplicate, won't be added

System.out.println("Set of fruits: " + fruits);

boolean containsBanana = fruits.contains("Banana");

System.out.println("Contains Banana? " + containsBanana);

System.out.println("Size of the set: " + fruits.size());

} }
HASH SET
 HashSet in Java is a class that implements the Set interface. It is designed to store a collection

of unique elements using a hashing technique.

1. Uniqueness of Elements

2. Hashing Technique: HashSet uses a hash table data structure internally. When you add
elements to a HashSet, each element's hashCode() method is called to generate a unique
numeric value associated with it. This value is used as an index to store the element in
the hash table.

3. Fast Lookup: When you want to check if an element exists in a HashSet, it calculates the
hash code of the element and directly looks for it in the corresponding index of the hash
table. This makes searching for elements efficient even for large collections.

4. No Defined Order: The elements are stored based on their hash codes
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
Set<String> uniqueNames = new HashSet<>();
uniqueNames.add("Alice");
uniqueNames.add("Bob");
uniqueNames.add("Alice"); // Duplicate, won't be added
System.out.println("HashSet of unique names: " + uniqueNames);
boolean containsBob = uniqueNames.contains("Bob");
System.out.println("Contains Bob? " + containsBob);
System.out.println("Size of the HashSet: " + uniqueNames.size());
}}
MAP INTERFACE
The Map interface in Java represents a collection of key-value pairs, where each key is unique and
maps to a corresponding value.

1. Key-Value Pairs: A Map consists of key-value pairs. Each key is unique within the Map, and it
maps to a specific value. You can think of the key as the word in a dictionary and the value as
its corresponding definition.

2. Fast Lookup: Maps provide fast lookup operations based on the keys.

3. No Duplicate Keys: Keys in a Map must be unique. If you try to add a key-value pair with a
key that already exists in the Map, it will replace the previous value with the new value.

4. Associative Storage: Maps provide an associative storage mechanism, allowing you to store
and retrieve values based on their associated keys. This makes Maps useful for tasks such as
caching, indexing, and data retrieval.
import java.util.HashMap;
import java.util.Map;
public class MapExample {
public static void main(String[] args) {
Map<String, Integer> grades = new HashMap<>();
grades.put("Alice", 85);
grades.put("Bob", 92);
grades.put("Charlie", 78);
System.out.println("Alice's grade: " + grades.get("Alice"));
grades.put("Bob", 95);
boolean hasCharlie = grades.containsKey("Charlie");
System.out.println("Has Charlie? " + hasCharlie);
grades.remove("Alice");
System.out.println("Size of the Map: " + grades.size());
} }
HASH MAP
 HashMap in Java is a class that implements the Map interface. It is a commonly used data

structure that stores key-value pairs in a way that allows for efficient lookup and retrieval.

1. Key-Value Pairs

2. Hashing Technique: When you add a key-value pair to a HashMap, the key's hashCode()
method is used to calculate a hash code, which is an integer representation of the key.
The hash code is used as an index to store the key-value pair in an internal array.

3. Fast Lookup

4. No Defined Order: The elements are stored based on their hash codes, so the iteration
order is not guaranteed to be the same as the insertion order.
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
Map<String, Integer> grades = new HashMap<>();
grades.put("Alice", 85); grades.put("Bob", 92); grades.put("Charlie", 78);
System.out.println("Alice's grade: " + grades.get("Alice"));
grades.put("Bob", 95);
boolean hasCharlie = grades.containsKey("Charlie");
System.out.println("Has Charlie? " + hasCharlie);
grades.remove("Alice");
} }
ITERATORS
LOOP THROUGH AN
ARRAYLIST
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> cars = new ArrayList<String>();
cars.add("Volvo");
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");
for (int i = 0; i < cars.size(); i++) {
System.out.println(cars.get(i));
}
}
}
FOR-EACH LOOP
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> cars = new ArrayList<String>();
cars.add("Volvo");
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");
for (String i : cars) {
System.out.println(i);
}
}
}
JAVA ITERATOR

 An Iterator is an object that can be used to loop through collections, like ArrayList and

HashSet.

 It is called an "iterator" because "iterating" is the technical term for looping.

 To use an Iterator, you must import it from the java.util package.


GETTING AN ITERATOR
import java.util.ArrayList;
import java.util.Iterator;
public class Main { The iterator() method can be
public static void main(String[] args) { used to get an Iterator for any
ArrayList<String> cars = new ArrayList<String>(); collection
cars.add("Volvo");
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");
Iterator<String> it = cars.iterator(); // Get the iterator
System.out.println(it.next()); // Print the first item
}
}
LOOPING THROUGH A
COLLECTION
To loop through a collection, use the hasNext() and next() methods of the Iterator:

Iterator<String> it = cars.iterator();
hasNext() - Returns true if the iteration has
while(it.hasNext())
more elements. 
{
next() - Returns the next element in the
System.out.println(it.next());
iteration.
}
REMOVING ITEMS FROM A
COLLECTION
import java.util.ArrayList;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<Integer>();
Iterators are designed to easily change the
numbers.add(12);
numbers.add(8); collections that they loop through.
numbers.add(2); The remove() method can remove items
numbers.add(23);
from a collection while looping.
Iterator<Integer> it = numbers.iterator();
while(it.hasNext()) {
Integer i = it.next();
if(i < 10) {
it.remove();
}
}
System.out.println(numbers);
}
}
WRAPPER CLASS
 Elements in an ArrayList are actually objects. In

the examples above, we created elements


(objects) of type "String".

 Wrapper classes provide a way to use primitive

data types (int, boolean, etc..) as objects.

 To use other types, such as int, you must specify

an equivalent wrapper class: Integer.


CREATING WRAPPER OBJECTS
public class Main {
public static void main(String[] args) {
Integer myInt = 5; To create a wrapper object, use the

Double myDouble = 5.99; wrapper class instead of the primitive


type.
Character myChar = 'A';
To get the value, you can just print the
System.out.println(myInt);
object
System.out.println(myDouble);
System.out.println(myChar);
}
}
public class Main {
 By working with objects, you can use
public static void main(String[] args) {
certain methods to get information
about the specific object. Integer myInt = 5;

 For example, the following methods Double myDouble = 5.99;


are used to get the value associated
Character myChar = 'A';
with the corresponding wrapper
System.out.println(myInt.intValue());
object: intValue(), byteValue(),
shortValue(), longValue(), System.out.println(myDouble.doubleValue());
floatValue(), doubleValue(),
System.out.println(myChar.charValue());
charValue(), booleanValue().
}

}
import java.util.ArrayList;
import java.util.Collections; // Import the Collections class
public class Main {
public static void main(String[] args) {
ArrayList<String> cars = new ArrayList<String>(); Sort() method fis used for sorting
cars.add("Volvo"); lists alphabetically or numerically
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");
Collections.sort(cars); // Sort cars
for (String i : cars) {
System.out.println(i);
}
}
}
TOSTRING METHOD - CONVERT
WRAPPER OBJECTS TO STRINGS
public class MainWC1 {
public static void main(String[] args) { Here, we convert an Integer to a String, and
Integer myInt = 100; use the length() method of the String class to
System.out.println(myInt); output the length of the "string":
String myString = myInt.toString();
System.out.println(myString);
System.out.println(myString.length());
}
}
 You must use wrapper classes, when working with Collection objects, such as ArrayList,

where primitive types cannot be used, because the list can only store objects and not elements.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> myNumbers = new ArrayList<Integer>();
myNumbers.add(10);
myNumbers.add(15);
myNumbers.add(20);
myNumbers.add(25);
for (int i : myNumbers) {
System.out.println(i);
}
}
}
COMPARATOR
 Java Comparator interface is used to order the objects of a user-defined class.

 This interface is found in java.util package and contains 2 methods compare(Object obj1,Object

obj2) and equals(Object element).

 It provides multiple sorting sequences, i.e., you can sort the elements on the basis of any data

member, for example, rollno, name, age or anything else.


COMPARE FUNCTION IN
COMPARATORS
EQUALS FUNCTION IN
COMPARATORS
SORTING LIST ELEMENTS USING
COMPARATOR
COMPARE FUNCTION
public void sort(List list, Comparator c)
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortingExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("John");
names.add("David");
names.add("Alice");
names.add("Bob");
Collections.sort(names, new StringLengthComparator()); // Sort the list using a custom comparator
for (String name : names) {
System.out.println(name);
} } }
class StringLengthComparator implements Comparator<String> {
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortingExample1 {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("John");
names.add("David");
names.add("Alice");
names.add("Bob");
Collections.sort(names, new StringLengthComparator());
for (String name : names) {
System.out.println(name);
} } }
class StringLengthComparator implements Comparator<String> {
public int compare(String s1, String s2) {
int result = Integer.compare(s1.length(), s2.length());
if (result == 0) {
result = s1.compareTo(s2); // Secondary comparison: lexicographic order
}
return result;
} }
GENERIC PROGRAMMING
 Generic programming is an approach to writing computer code that allows you to create flexible
and reusable programs.

 It involves designing code that can work with different data types without having to rewrite the
code for each specific type; this is achieved by using placeholders or generic types in the code.

 These placeholders can be replaced with specific data types when the code is used, allowing the
same code to work with different types of data.

 Java Generics allows us to create a single class, interface, and method that can be used with
different types of data (objects).
MOTIVATIONS
 Code Reusability

 Flexibility

 Abstraction

 Performance Optimization

 Type Safety

 Type casting is not required

 Compile-Time Checking

 Code clarity
GENERICS CLASS
 A class that can refer to any type is known as a

generic class. Here, we are using the T type


parameter to create the generic class of specific
type.

 Box is a generic class that has a type parameter T

declared within angle brackets (<>) after the class


name. This type parameter serves as a placeholder
for the actual type that will be used when creating
an instance of the class.
class Box <E> {
private E item;
public void setItem(E item)
{
this.item = item;
}
public E getItem()
{
return item;
}
}
public class genc
{
public static void main(String[] args)
{
Box<Integer> intBox = new Box<>();
intBox.setItem(42);
int value = intBox.getItem();
System.out.println("Value: " + value);
Box<String> stringBox = new Box<>();
stringBox.setItem("Hello");
String text = stringBox.getItem();
System.out.println("Text: " + text);
}
}
TYPE PARAMETERS
 T - Type: The letter "T" is used as a placeholder for any type. It is the most commonly used type parameter

and signifies a generic type.

 E - Element: The letter "E" is used to represent elements in a collection or container. It is commonly used in

generic classes or interfaces that deal with collections.

 K - Key: The letter "K" is often used to represent keys in a key-value pair or a map data structure.

 N - Number: The letter "N" is commonly used to represent numeric types, such as integers, floating-point

numbers, or any other numeric data type.

 V - Value: The letter "V" is often used to represent values in a key-value pair or a map data structure.
GENERICS METHOD
 Generic methods allow you to define type parameters specific to a method, rather than at the class

level.

 This gives you the flexibility to write methods that can operate on different types of data while

ensuring type safety.

 Like the generic class, we can create a generic method that can accept any type of arguments. Here,

the scope of arguments is limited to the method where it is declared.

 It allows static as well as non-static methods.


public class GenericMethodExample {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3, 4, 5};
Double[] doubleArray = {1.1, 2.2, 3.3, 4.4, 5.5};
String[] stringArray = {"Hello", "World"};

System.out.println("Integer Array:");
printArray(intArray);

System.out.println("Double Array:");
printArray(doubleArray);

System.out.println("String Array:");
printArray(stringArray);
} }
GENERICS INTERFACE
BOUNDED TYPES –WILDCARD
ARGUMENTS IN JAVA
GENERICS
 In Java generics, bounded type parameters allow you to restrict the types that can be used as type

arguments.

 If you just specify a type (class) as bounded parameter, only sub types of that particular class are

accepted by the current generic class.

 In Java generics, the wildcard (?) is a special type argument that represents an unknown type. It is

used to make your code more flexible by allowing it to work with different types within certain
bounds.
UPPER BOUNDED
WILDCARDS
 The purpose of upper bounded wildcards is to decrease the restrictions on a variable.

 It restricts the unknown type to be a specific type or a subtype of that type.

 It is used by declaring wildcard character ("?") followed by the extends (in case of, class) or implements (in

case of, interface) keyword, followed by its upper bound.

 ? is a wildcard character.

 extends, is a keyword.

 Number, is a class present in java.lang package


import java.util.ArrayList;
public class UpperBoundWildcard {
private static Double add(ArrayList<? extends Number> num) {
double sum=0.0;
for(Number n:num)
{
sum = sum+n.doubleValue();
}
return sum;
}
public static void main(String[] args) {
ArrayList<Integer> l1=new ArrayList<Integer>();
l1.add(10);
l1.add(20);
System.out.println("displaying the sum= "+add(l1));

ArrayList<Double> l2=new ArrayList<Double>();


l2.add(30.0);
l2.add(40.0);
System.out.println("displaying the sum= "+add(l2));
}
}
UNBOUNDED WILDCARDS

The unbounded wildcard type represents the list of an unknown type such as List<?>. This approach

can be useful in the following scenarios: -

 When the given method is implemented by using the functionality provided in the Object class.

 When the generic class contains the methods that don't depend on the type parameter.
import java.util.Arrays;
import java.util.List;
public class UnboundedWildcard {
public static void display(List<?> list)
{
for(Object o:list)
{
System.out.println(o);
}
}
public static void main(String[] args) {
List<Integer> l1=Arrays.asList(1,2,3);
System.out.println("displaying the Integer values");
display(l1);
List<String> l2=Arrays.asList("One","Two","Three");
System.out.println("displaying the String values");
display(l2);
}
}
LOWER BOUNDED
WILDCARDS
 The purpose of lower bounded wildcards is to restrict the unknown type to be a specific type or a

supertype of that type.

 It is used by declaring wildcard character ("?") followed by the super keyword, followed by its lower

bound.

 ? is a wildcard character.

 super, is a keyword.

 Integer, is a wrapper class.


import java.util.Arrays;
import java.util.List;
public class LowerBoundWildcard {
public static void addNumbers(List<? super Integer> list) {
for(Object n:list)
{
System.out.println(n);
}
}
public static void main(String[] args) {
List<Integer> l1=Arrays.asList(1,2,3);
System.out.println("displaying the Integer values");
addNumbers(l1);

List<Number> l2=Arrays.asList(1.0,2.0,3.0);
System.out.println("displaying the Number values");
addNumbers(l2);
}
}
class Sample <T extends Number>{
T data;
Sample(T data){
this.data = data;
}
public void display() {
System.out.println("Data value is: "+this.data);
}
}
public class BoundsExample {
public static void main(String args[]) {
Sample<Integer> obj1 = new Sample<Integer>(20);
obj1.display();
Sample<Double> obj2 = new Sample<Double>(20.22d);
obj2.display();
Sample<String> obj3 = new Sample<String>("Krishna");
obj3.display();
}
}

You might also like