0% found this document useful (0 votes)
9 views17 pages

UNIT IV Collections Framework in Java

The document provides comprehensive notes on Object Oriented Programming with Java, focusing on the Collection Framework, Generics, and various data structures like List, Set, Queue, and Map. It explains the importance of type safety with Generics, the functionality of the Collections Framework, and introduces the Stream API for data processing. Additionally, it includes examples for practical understanding of concepts such as Iterator, List Interface, and PriorityQueue.

Uploaded by

riyarastogi95
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)
9 views17 pages

UNIT IV Collections Framework in Java

The document provides comprehensive notes on Object Oriented Programming with Java, focusing on the Collection Framework, Generics, and various data structures like List, Set, Queue, and Map. It explains the importance of type safety with Generics, the functionality of the Collections Framework, and introduces the Stream API for data processing. Additionally, it includes examples for practical understanding of concepts such as Iterator, List Interface, and PriorityQueue.

Uploaded by

riyarastogi95
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/ 17

SRMS CET, BAREILLY (SESSION 2024-2025)

DEPT. OF IT
BCS403 OBJECT ORIENTED
PROGRAMMING WITH JAVA NOTES
UNIT IV
Prepared By:
Mr. Fardeen Ahmad Khan
Assistant Professor
Dept. of IT, SRMS CET

Topics: Collection in Java, Collection Framework in Java, Hierarchy of Collection Framework, Iterator
Interface, Collection Interface, List Interface, ArrayList, LinkedList, Vector, Stack, Queue Interface, Set
Interface, HashSet, LinkedHashSet, SortedSet Interface, TreeSet, Map Interface, HashMap Class,
LinkedHashMap Class, TreeMap Class, Hashtable Class, Sorting, Comparable Interface, Comparator
Interface, Properties Class in Java.

Introduction:
Generic Types in Java:
Generics in Java are a powerful feature that allow you to write code that works with any data type,
while still maintaining type safety. Introduced in Java 5, generics help avoid runtime errors by catching
type-related bugs at compile time. Generics in Java allow us to create classes, interfaces, and methods
where the type of the data is specified as a parameter. If we use generics, we do not need to write
multiple versions of the same code for different data types.

Example of Generic Types:

package GenericTypes;
public class GenericExample<Temp_Type> {
private Temp_Type temp_var;
public GenericExample(Temp_Type temp_var) {
this.temp_var = temp_var;
}
public Temp_Type getTemp()
{
return this.temp_var;
}

public static void main(String args[])


{
GenericExample<String> ge1 = new GenericExample<String>("HelloWorld");
System.out.println(ge1.getTemp());

GenericExample<Integer> ge2 = new GenericExample<Integer>(101);


System.out.println(ge2.getTemp());

GenericExample<Double> ge3 = new GenericExample<Double>(10.5);


System.out.println(ge3.getTemp());

GenericExample<Float> ge4 = new GenericExample<Float>(10.5f);


System.out.println(ge4.getTemp());

GenericExample<Character> ge5 = new GenericExample<Character>('A');


System.out.println(ge5.getTemp());

GenericExample<Boolean> ge6 = new GenericExample<Boolean>(true);


System.out.println(ge6.getTemp());

GenericExample<Long> ge7 = new GenericExample<Long>(10000000000L);


System.out.println(ge7.getTemp());

GenericExample<Byte> ge8 = new GenericExample<Byte>((byte) 10);


System.out.println(ge8.getTemp());

GenericExample<Short> ge9 = new GenericExample<Short>((short) 10);


System.out.println(ge9.getTemp());

GenericExample<Number> ge10 = new GenericExample<Number>(10.5);


System.out.println(ge10.getTemp());

}
}

Note: Notice how a single class GenericExample is now able to handle virtually any type of data we
specify in the main method. This is the power of using Generic Types in Java.

Type safety with Generics:


Type safety in Java means that the compiler ensures you only use variables and objects according to
their declared types. It prevents you from performing operations that are not allowed on a particular
type of data, reducing the risk of runtime errors, such as ClassCastException.

Before Generics:
If we create an Array List and try to pass two different types of value in it, it will not give any error
until the runtime.

List list = new ArrayList();


list.add("Hello");
list.add(100); // No error at compile time

String str = (String) list.get(1); // Runtime error: ClassCastException

After Generics:
This code can be re-written as follows:

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


list.add("Hello");
// list.add(100); // Compile-time error!

String str = list.get(0); // Safe, no casting needed

Notice how list.add(100) now gives an error at compile time, this helps the programmer write
code with type safety in Java.

Collections Framework in Java:


What is a Framework in Java?
A framework is a set of classes and interfaces which provide a ready-made architecture. In order to
implement a new feature or a class, there is no need to define a framework. However, an optimal
object-oriented design always includes a framework with a collection of classes such that all the classes
perform the same kind of task.

Collections Framework:
The Java Collections Framework is a set of tools and classes in Java that helps programmers work with
groups of data. It was added in Java 2 to make it easier to store, manage, and use data like lists, sets,
and maps. At the center of this framework are important interfaces such as List, Set, Queue, and Map.
These interfaces are like blueprints that show how different types of collections should behave. There
are many built-in classes that follow these blueprints, like ArrayList, LinkedList, HashSet, TreeSet,
HashMap, and TreeMap. Each one is useful in different situations. For example, ArrayList is good when
you want fast access to data by index, while LinkedList is better for adding or removing items in the
middle. The framework also includes helper classes like Collections, which give extra functions like
sorting or reversing a list. Since Java 8, the framework has become even more powerful with features
like lambda expressions and the Stream API, which help make the code shorter and easier to read
when working with data. In short, the Java Collections Framework makes it simple to handle large
amounts of data in a clean and organized way.
Iterator Interface:
Iterator interface in Java is used to go through elements in a collection one by one. The Iterator
interface has three main methods: hasNext(), which checks if there is another element to visit; next(),
which returns the next element; and remove(), which deletes the current element from the collection.

Example:

package CollectionsinJava;
import java.util.ArrayList;
import java.util.Iterator;
class IteratorExample{
public static void main(String[] args)
{
ArrayList<String> cities = new ArrayList<>();
cities.add("New York");
cities.add("Los Angeles");
cities.add("Chicago");

// Using an iterator to traverse the list


Iterator<String> iterator = cities.iterator();
while(iterator.hasNext()) {
System.out.println(" "+iterator.next());
}
}
}
Stream API:

The Stream API in Java 8 is a powerful feature introduced to process collections of data in a functional
and declarative style. It allows you to perform operations like filtering, mapping, and reducing on data
streams, making code more concise and readable.

Intermediate Operations: These are operations that return a new stream. They are lazy, meaning they
do not process the elements until a terminal operation is called. Example: filter(), map(), sorted().

Terminal Operations: These operations produce a result or an effect (like printing). After this, the
stream cannot be used again. Example: count(), toList(), reduce().

✓ Operates on data using functional-style methods like filter, map, reduce, etc.

✓ Streams are evaluated lazily, meaning intermediate operations are not executed until a
terminal operation is invoked.

✓ Streams can be processed in parallel using parallelStream() for better performance on multi-
core processors.

✓ Streams do not modify the original data source; they produce a new stream or result.

Example: Using List of Numbers

package CollectionsinJava;
import java.util.ArrayList;
import java.util.List;
public class StreamAPIExample {
public static void main(String[] args) {
// Example of using Stream API to filter even numbers from a list
List<Integer> numbers = new ArrayList<>();

// Adding numbers to the list


for (int i = 1; i <= 10; i++) {
numbers.add(i);
}

// Using Stream API to filter even numbers


List<Integer> evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.toList();

// Printing the doubled even numbers


System.out.println("Doubled Even Numbers: " + evenNumbers);
}
}

Output: Doubled Even Numbers: [4, 8, 12, 16, 20]


Here we are using filter() to filter out the even numbers from the List, map() to change ever number
into num*2 and finally toList() to convert the result into a List.

Example: Using List of Strings

package CollectionsinJava;
import java.util.ArrayList;
import java.util.List;
public class StreamAPIStringExample {
public static void main(String[] args) {
// Example of using Stream API to filter a list
List<String> names = new ArrayList<>();

// Adding names to the list


names.add(“Alisha”);
names.add(“Bob”);
names.add(“Adam”);
names.add(“David”);
names.add(“Anton”);

// Using Stream API to filter names that start with ‘A’ or ‘B’
List<String> filteredNames = names.stream()
.filter(name -> name.startsWith(“A))
.map(String::toUpperCase)
.toList();

// Printing the filtered names


System.out.println(“Filtered Names: “ + filteredNames);
}
}

Output: Filtered Names: [ALISHA, BOB, ADAM, BRIAN]

For Each Method:


The forEach method in Java is used to perform an action on each element of a collection. It was added
in Java 8 and works with all classes that implement the Iterable interface, like ArrayList, HashSet, and
LinkedList. The forEach method takes a function as a parameter, usually written using a lambda
expression, Instead of using a loop to go through all the elements one by one, you can use forEach to
do the same task in a single line of code.

Example:

package CollectionsinJava;
import java.util.ArrayList;
import java.util.List;
public class StreamAPIforEachExample {
public static void main(String[] args) {
// Example usage of forEach with a stream
List<String> names = new ArrayList<>();
names.add("Sameer");
names.add("Dan");
names.add("Chloe");
names.add("Daniel");
names.stream().forEach(name -> System.out.println("Hello! "+name));
}
}

Output:
Hello! Sameer
Hello! Dan
Hello! Chloe
Hello! Daniel

List Interface in Java:


The List interface in Java is a part of the Java Collections Framework and is used to store an ordered
collection of elements. It allows duplicate elements and keeps them in the same order in which they
were added. This means if you add items to a list, they are stored in a specific sequence, and you can
access them using their index (starting from 0). The List interface is implemented by popular classes
like ArrayList, LinkedList, Vector and Stack. You can add, remove, update, or retrieve elements using
various methods like add(), remove(), set(), and get(). Since List allows duplicates, you can store the
same element more than once.

1. ArrayList: ArrayList is a resizable array that allows fast access to elements using an index.
It is good for searching and reading data but slower for inserting or removing in the middle.

2. LinkedList: LinkedList stores elements as nodes connected to each other, making it fast for insertions
and deletions. However, accessing elements by index is slower compared to ArrayList.

3. Vector: Vector is similar to ArrayList but is synchronized, which means it is thread-safe.


It is slower in single-threaded environments due to the overhead of synchronization.

4. Stack: Stack is a subclass of Vector that follows the Last In, First Out (LIFO) principle.
You can add and remove elements using push() and pop() methods.

Example:

package CollectionsinJava;
import java.util.*;
public class ListsExample {
public static void main(String[] args)
{
// Example of ArrayList
List<String> list = new ArrayList<>();
list.add("Sameer");
list.add("Dan");
list.add("Chloe");
list.add("Daniel");
System.out.println("ArrayList: " + list);
list.reversed();
System.out.println("Reversed ArrayList: " + list);

// Example of LinkedList
List<String> linkedList = new LinkedList<>();
linkedList.add("Sameer");
linkedList.add("Dan");
linkedList.add("Chloe");
linkedList.add("Daniel");
System.out.println("LinkedList: " + linkedList);
linkedList.add(2, "NewElement");
System.out.println("LinkedList after adding NewElement: " +
linkedList);

// Example of Vector
List<String> vector = new Vector<>();
vector.add("Sameer");
vector.add("Dan");
vector.add("Chloe");
vector.add("Daniel");
System.out.println("Vector: " + vector);
System.out.println("Size of Vector: " + vector.size());

// Example of Stack
Stack<String> stack = new Stack<>();
stack.push("Sameer");
stack.push("Dan");
stack.push("Chloe");
stack.push("Daniel");
System.out.println("Stack: " + stack);
stack.pop();
System.out.println("Stack after pop: " + stack);
System.out.println("Top element of Stack: " + stack.peek());
System.out.println("Is Stack empty? " + stack.isEmpty());
}
}

Output:
ArrayList: [Sameer, Dan, Chloe, Daniel]
Reversed ArrayList: [Sameer, Dan, Chloe, Daniel]
LinkedList: [Sameer, Dan, Chloe, Daniel]
LinkedList after adding NewElement: [Sameer, Dan, NewElement, Chloe, Daniel]
Vector: [Sameer, Dan, Chloe, Daniel]
Size of Vector: 4
Stack: [Sameer, Dan, Chloe, Daniel]
Stack after pop: [Sameer, Dan, Chloe]
Top element of Stack: Chloe
Is Stack empty? false

Queue Interface in Java:


The Queue interface in Java is used to store elements using First In, First Out (FIFO). This means the
element added first is removed first, just like people standing in a line. It is implemented by classes like
LinkedList, PriorityQueue, etc. The Queue interface provides methods such as add(), offer() to insert
elements, and remove(), poll() to remove elements. add() and remove() throw exceptions if the queue
is full or empty, offer() and poll() return special values like false or null. Queues are commonly used in
programming for tasks like scheduling, buffering etc.

PriorityQueue

The PriorityQueue class in Java is a special type of queue where elements are ordered based on their
priority instead of just the order they were added. By default, it arranges elements in natural order
(for numbers, smallest to largest; for strings, alphabetical order), but you can also provide a custom
order using a comparator.

Example:

package CollectionsinJava;
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
// Create a PriorityQueue
PriorityQueue<Integer> pq = new PriorityQueue<>();

// Add elements to the PriorityQueue


pq.add(10);
pq.add(20);
pq.add(15);
pq.add(30);

// Display the elements in the PriorityQueue


System.out.println("PriorityQueue: " + pq);

// Remove the head of the PriorityQueue


int removedElement = pq.poll();
System.out.println("Removed Element: " + removedElement);

// Display the elements after removal


System.out.println("PriorityQueue after removal: " + pq);
}
}
Output:
PriorityQueue: [10, 20, 15, 30]
Removed Element: 10
PriorityQueue after removal: [15, 20, 30]

Set Interface in Java:


The Set interface in Java is a collection that does not allow duplicate elements. It is used when you
want to store unique items, such as usernames or IDs. Unlike a List, a Set does not maintain the order
in which elements were added. The most commonly used implementations of Set are HashSet,
LinkedHashSet, and TreeSet (which implements SortedSet)

HashSet:
HashSet stores elements in no particular order and does not allow duplicates. It is very fast for
operations like add, remove, and search, but it doesn't remember the order of insertion.

Example:

package CollectionsinJava;
import java.util.HashSet;
public class HashSetExample {
public static void main(String[] args) {
// Create a HashSet of Strings
HashSet<String> hs1 = new java.util.HashSet<>();

// Add elements to the HashSet


hs1.add("Apple");
hs1.add("Banana");
hs1.add("Orange"); // Here order of insertion will not be maintained
hs1.add("Apple"); // Duplicate element will not be added

// Display the HashSet


System.out.println("HashSet: " + hs1);

// Check if an element exists


if (hs1.contains("Banana")) {
System.out.println("Banana is in the HashSet.");
} else {
System.out.println("Banana is not in the HashSet.");
}

// Remove an element
hs1.remove("Apple");
System.out.println("After removing Apple: " + hs1);
}
}

Output:
HashSet: [Apple, Orange, Banana] // Here order of insertion was not maintained
Banana is in the HashSet.
After removing Apple: [Orange, Banana]

LinkedHashSet:
LinkedHashSet is like HashSet, but it remembers the order in which elements were added. It is
useful when you need uniqueness and also want to maintain the insertion order.

package CollectionsinJava;
import java.util.LinkedHashSet;
public class LinkedHashSetExample {
public static void main(String[] args) {
// Create a LinkedHashSet
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();

// Add elements to the LinkedHashSet


linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Cherry");
linkedHashSet.add("Date");

// Display the elements in the LinkedHashSet


System.out.println("LinkedHashSet with order of Insertion: " +
linkedHashSet);

// Check if an element exists


System.out.println("Contains 'Banana': " +
linkedHashSet.contains("Banana"));

// Remove an element
linkedHashSet.remove("Cherry");
System.out.println("After removing 'Cherry': " + linkedHashSet);
}
}

Output:
LinkedHashSet with order of Insertion: [Apple, Banana, Cherry, Date]
Contains 'Banana': true
After removing 'Cherry': [Apple, Banana, Date]

SortedSet Interface and TreeSet:


The SortedSet interface extends Set and keeps elements in sorted order. TreeSet is the class that
implements it. It automatically sorts the elements in natural order (like numbers from smallest to
largest or strings in alphabetical order) and also ensures no duplicates are stored.

Example:
package CollectionsinJava;
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String[] args)
{
// Create a TreeSet
TreeSet<String> treeSet = new TreeSet<>();

// Add elements to the TreeSet


treeSet.add("Apple");
treeSet.add("Banana");
treeSet.add("Cherry");
treeSet.add("Date");

// Display the elements in the TreeSet


System.out.println("TreeSet (sorted order): " + treeSet);

// Check if an element exists


System.out.println("Contains 'Banana': " +
treeSet.contains("Banana"));

// Remove an element
treeSet.remove("Cherry");
System.out.println("After removing 'Cherry': " + treeSet);
}
}

Output:
TreeSet (sorted order): [Apple, Banana, Cherry, Date]
Contains 'Banana': true
After removing 'Cherry': [Apple, Banana, Date]

Map Interface:
HashMap is the most commonly used implementation of the Map interface. It allows null keys and
values, and it does not maintain any order of the keys. It is very fast for basic operations like adding,
removing, and finding values.

HashMap:
HashMap is the most commonly used implementation of the Map interface. It allows null keys and
values, and it does not maintain any order of the keys. It is very fast for basic operations like adding,
removing, and finding values.

LinkedHashMap:
LinkedHashMap is like HashMap, but it remembers the order in which keys were added. Use this
when you want fast lookups and also want to maintain insertion order.
TreeMap:
TreeMap stores keys in sorted (ascending) order by default. It does not allow null keys. Use TreeMap
when you need your keys to be always sorted.

Hashtable:
Hashtable is similar to HashMap but is synchronized, which means it is thread-safe. It does not allow
null keys or null values and is generally slower in single-threaded applications.

Example HashMap, LinkedHashMap, TreeMap, Hashtable:

package CollectionsinJava;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.TreeMap;
import java.util.Hashtable;
public class MapExample {
public static void main(String[] args)
{
// HashMap example
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("Apple", 101);
hashMap.put("Orange", 202);
hashMap.put("Grapes", 303);
System.out.println("HashMap: " + hashMap);

// LinkedHashMap example
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("Apple", 101);
linkedHashMap.put("Orange", 202);
linkedHashMap.put("Grapes", 303);
System.out.println("LinkedHashMap: " + linkedHashMap);

// TreeMap example
TreeMap<String, Integer> treeMap = new TreeMap<>();
treeMap.put("Apple", 101);
treeMap.put("Orange", 202);
treeMap.put("Grapes", 303);
System.out.println("TreeMap: " + treeMap);

// Hashtable example
Hashtable<String, Integer> hashtable = new Hashtable<>();
hashtable.put("Apple", 101);
hashtable.put("Orange", 202);
hashtable.put("Grapes", 303);
System.out.println("Hashtable: " + hashtable);

}
}
Sorting in Java:
Comparable Interface:
The Comparable interface is used to define natural sorting order. A class that implements Comparable
must override the compareTo() method.

package CollectionsinJava;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
class Student implements Comparable<Student>
{
String name;
int rollNo;

public Student(String name,int rollNo)


{
this.name = name;
this.rollNo = rollNo;
}

@Override
public int compareTo(Student s)
{
return this.rollNo - s.rollNo;
}

@Override
public String toString()
{
return "Student{" +
"name='" + this.name + '\'' +
", rollNo=" + this.rollNo +
'}';
}
}
public class ComparableExample {
public static void main(String[] args)
{
List<Student> students = new ArrayList<>();
students.add(new Student("John", 301));
students.add(new Student("Alice", 101));
students.add(new Student("Bob", 201));

System.out.println("Students before sorting:");


for (Student student : students) {
System.out.println(student);
}

Collections.sort(students);

System.out.println("Sorted Students by Roll No:");


for (Student student : students) {
System.out.println(student);
}
}
}

Output:
Students before sorting:
Student{name='John', rollNo=301}
Student{name='Alice', rollNo=101}
Student{name='Bob', rollNo=201}
Sorted Students by Roll No:
Student{name='Alice', rollNo=101}
Student{name='Bob', rollNo=201}
Student{name='John', rollNo=301}

Comparator Interface:
The Comparator interface allows custom sorting logic by creating a separate class (or lambda
function). You override the compare() method.

package CollectionsinJava;

import java.util.List;
import java.util.ArrayList;

public class ComparatorExample {


public static void main(String[] args) {

List<Student> students = new ArrayList<>();


students.add(new Student("John", 301));
students.add(new Student("Alice", 101));
students.add(new Student("Bob", 201));
students.add(new Student("Charlie", 102));
students.add(new Student("David", 202));

System.out.println("Students before sorting: \n");


for (Student student : students) {
System.out.println(student);
}

// Sorting using Comparator


students.sort((s1, s2) -> s1.name.compareTo(s2.name));
System.out.println("\n \nSorted Students by Roll No: \n");

// Displaying sorted students


for (Student student : students) {
System.out.println(student);
}
}

Output:

Students before sorting:

Student{name='John', rollNo=301}
Student{name='Alice', rollNo=101}
Student{name='Bob', rollNo=201}
Student{name='Charlie', rollNo=102}
Student{name='David', rollNo=202}

Sorted Students by Roll No:

Student{name='Alice', rollNo=101}
Student{name='Bob', rollNo=201}
Student{name='Charlie', rollNo=102}
Student{name='David', rollNo=202}
Student{name='John', rollNo=301}

Properties in Java:
The Properties class is a part of the java.util package. It is used to store and retrieve configuration
values (like settings) in the form of key-value pairs.
Both the keys and values are strings.

It is commonly used for things like:

• App settings

• Database configurations

• Language translation files

• Loading from .properties files


package CollectionsinJava;
import java.util.Properties;
public class PropertiesExample {
public static void main(String[] args)
{
Properties properties = new Properties();
properties.setProperty("username", "admin");
properties.setProperty("password", "UserPass@123");
properties.setProperty("url", "http://example.com");
properties.setProperty("port", "8080");

// Retrieving properties
String username = properties.getProperty("username");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String port = properties.getProperty("port");

// Displaying properties
System.out.println("Username: " + username);
System.out.println("Password: " + password);
System.out.println("URL: " + url);
System.out.println("Port: " + port);

}
}

Output:
Username: admin
Password: UserPass@123
URL: http://example.com
Port: 8080

You might also like