0% found this document useful (0 votes)
4 views

Ajava Unit 1

It is java unit 1 of mca

Uploaded by

savlalita89
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Ajava Unit 1

It is java unit 1 of mca

Uploaded by

savlalita89
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 40

AJAVA: - Unit-1: Collection and Generics

COLLECTION AND GENERICS


Unit Structure
1.0 Objectives
1.1 Introduction to Generics
1.1.1 Advantages of Generics
1.1.2 Generic Classes
1.1.3 Generic Methods
1.1.4 Bounded Type Parameters
1.2 Wildcards
1.2.1 Types of Wildcards
1.3 Introduction to Java Collections
1.3.1 Java Collection Framework
1.3.2 Java Collection Hierarchy
1.3.3 Advantages of Collection
1.3.4 Framework Basic and Bulk Operations on Java Collection
1.4 List
1.4.1 Methods of List Interface
1.4.2 How to create List - ArrayList and LinkedList
1.4.3 Iterating through the List
1.5 Set
1.5.1 Methods of Set Interface
1.5.2 HashSet Class
1.5.3 TreeSet Class
1.6 Map
1.6.1 Methods of Map Interface
1.6.2 HashMap Class
1.6.2 LinkedHashMap Class
1.6.3 TreeMap Class
1.7 Lamda Expressions

1
1.1 Introduction to Generics

The Java Generics was added to JDK 1.5 which allowed programming
generically. It allows creating classes and methods that work in the same way on
different types of objects while providing type-safety right at the compile-time It
makes the code stable by detecting the bugs at compile time.
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.
1.1.1 ADVANTAGE OF GENERICS
There are mainly 3 advantages of generics. They are as follows:
1) Type-safety

We can hold only a single type of objects in generics. It doesn’t allow to


store other objects. Without Generics, we can store any type of objects.
Example:
List list = new ArrayList(); list.add(10);
//Storing an int value in list list.add("10");
//Storing a String value in list
With 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
2) Type casting is not required
There is no need to typecast the object. Before Generics, we need to type cast.
Example:
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0); //typecasting
After Generics, we don't need to typecast the object.

Example:
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0);

2
AJAVA-Unit 1: Collection and Generics
3) Compile-Time Checking: Type checking is done at compile time so errors
will not occur at runtime.
Example:
List<String> list = new ArrayList<String>();
list.add("hello");
list.add(32);//Compile Time Error
1.1.2 GENERIC CLASSES
Generics is not only limited to collection. It is also possible to use Generics with
classes. A generic class declaration looks like a non-generic class declaration,
except that the class name is followed by a type parameter section.
The type parameter section of a generic class can have one or more type parameters
separated by commas. These classes are known as parameterized classes or
parameterized types because they accept one or more parameters.
Example: Program that demonstrates Generic Classes
public class Shape<T>
{ private T t; public
void add(T t) {
this.t = t;
} public T
get() { return
t;
}
public static void main(String[] args) {
Shape<Integer> intShape = new Shape<Integer>();
Shape<String> strShape = new Box<String>();

intShape.add(new Integer(25));
strShape.add(new String("Generic Classes"));
System.out.printf("Integer Value :%d\n\n", intShape.get());
System.out.printf("String Value :%s\n", strShape.get());
}
}

Output
Integer Value :25
String Value : Generic Classes

3
In this program, Box is coded as a Generic Class. Technically, Box is a parametric
class and T is the type parameter. T serves as a placeholder for holding any type of
Object. We can use the above class by substituting any kind of object for the
placeholder T.
1.1.3 GENERIC METHODS
A generic method declaration can have arguments of different types. Based on the
types of the arguments passed to the generic method, the compiler handles each
method call appropriately. Unlike a Generic Class, a generic method containing
different parameters affects only that method. alone. Hence, a class which is not
generic can contain generic and non-generic methods.
Rules for defining Generic Methods
• All generic method declarations have a type parameter section delimited by
angle brackets (< and >) that precedes the method's return type < T >
• Each type parameter section contains one or more type parameters
separated by commas. A type parameter is an identifier that specifies a
generic type name.
• The type parameters can be used to declare the return type and act as
placeholders for the types of the arguments passed to the generic method,
which are known as actual type arguments.
• A generic method's body is declared like that of any other method.
• Note that type parameters can represent only reference types, not primitive
types (like int, double and char).
Example 1: Program that prints the type of data passed using a single Generic
method
public class GenericMethodsEx1 {
// generic method print
public static <T> void print(T t)
{ System.out.println(t.getClass().getName());
}
public static void main(String args[]) {
GenericMethodsEx1.print(“Hello World”);
GenericMethodsEx1.print(100);
}
}

Output;
java.lang.String java.lang.Integer

4
AJAVA-Unit 1: Collection and Generics
In this program, the static method print has a return type void and it takes a single
parameter called T. T stands for parametric type which can be substituted with any
of the Java types by a client application.
Example 2: Program that prints an array of different type using a single
Generic method
public class GenericMethodEx2 {
// generic method printArray
public static < T > void printArray( E[] i )
{
// Display array elements
for(T element : i) {
System.out.printf("%s ", element);
}
System.out.println();
}
public static void main(String args[]) {
// Create arrays of Integer, Double and Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
System.out.println("Array integerArray contains:");
printArray(intArray); // pass an Integer array
System.out.println("\nArray doubleArray contains:");
printArray(doubleArray); // pass a Double array
System.out.println("\nArray characterArray contains:");
printArray(charArray); // pass a Character array
}
}

Output
Array integerArray contains:
12345
Array doubleArray contains:
1.1 2.2 3.3 4.4
Array characterArray contains:

5
H EL L O
In this program, the static method printArray has a return type void and it takes a
single parameter called T. T stands for parametric type which can be substituted
with any of the Java types by a client application. The main method passes arrays
with different types and the single generic method is used to print all of the array
elements.
1.1.4 BOUNDED TYPE PARAMETERS
Sometimes it is required to restrict the kinds of types that are allowed to be passed
to a type parameter. Example, a method that operates on numbers might only want
to accept instances of Number or its subclasses. In such cases, bounded type
parameters can be used.
To declare a bounded type parameter, list the type parameter's name, followed by
the extends keyword, followed by its upper bound like below:
class Example <T extends Number>
Example: Program that calculates the average of numbers either integer or
double
package p1;
public class Test<T extends Number> {
T[] numArr; Test(T[]
numArr) { this.numArr
= numArr;
}
public double getAvg() { double
sum = 0.0; for (int i = 0; i <
numArr.length; i++) { sum +=
numArr[i].doubleValue();
}
double avg = sum / numArr.length;
return avg;
}
public static void main(String[] args) {

6
AJAVA-Unit 1: Collection and Generics

Integer i1[] = {12, 13, 14, 15, 16};


Double d[] = {1.0, 2.0, 3.0, 4.0};
Test<Integer> e1 = new
Test<Integer>(i1); Test<Double> e2 =
new Test<Double>(d); double ai =
e1.getAvg(); Double ad = e2.getAvg();
System.out.println("Average of Integers = " + ai);
System.out.println("Average of Double =" + ad);
}

Output
Average of Integers = 14.0
Average of Double =2.5

1.2 WILDCARD CHARACTER


• The question mark (?) is known as the wildcard in generic programming . It
represents an unknown type.
• The wildcard can be used in a variety of situations such as the type of a
parameter, field, or local variable; sometimes as a return type.
• Unlike arrays, different instantiations of a generic type are not compatible
with each other, not even explicitly. This incompatibility may be softened
by the wildcard if ? is used as an actual type parameter.
1.2.1 TYPES OF WILDCARDS
There are three types of wildcards: They are:
1. UPPER BOUNDED WILDCARDS
 These wildcards can be used when you want to relax the restrictions on a
variable.
 For example, say you want to write a method that works on List < Integer
>, List<Double > and List < Number > , you can do this using an upper
bounded wildcard.
 To declare an upper-bounded wildcard, use the wildcard character (‘?’),
followed by the extends keyword, followed by its upper bound
Ex: public static void add(List<? extends Number> list)

7
Example: Program that demonstrates Upper Bounded Wildcards
import java.util.Arrays; import
java.util.List;
class UpperBoundedWildcardDemo
{
public static void main(String[] args)
{
//Upper Bounded Integer List
List<Integer> list1= Arrays.asList(4,5,6,7);

//printing the sum of elements in list1


System.out.println("Total sum is:"+sum(list1));
//Upper Bounded Double list
List<Double> list2=Arrays.asList(4.1,5.1,6.1);

//printing the sum of elements in list2


System.out.print("Total sum is:"+sum(list2));
}
private static double sum(List<? extends Number> list)
{
double sum=0.0;
for (Number i:
list)
{
sum+=i.doubleValue();
}
return sum;
}
}

Output
Total sum is:22.0
Total sum is:15.299999999999999
Here, the sum method is used to calculate the sum of both Integer list and Double
list elements as it accepts list as a parameter whse upper bound is Number.

8
AJAVA-Unit 1: Collection and Generics

2. LOWER BOUNDED WILDCARDS


• If we use the lower-bounded wildcards you can restrict the type of the “?”
to a particular type or a super type of it.
• It is expressed using the wildcard character (‘?’), followed by the super
keyword, followed by its lower bound: <? super A> Syntax: Collectiontype
<? super A>
Example: Program that demonstrates Lower Bounded Wildcards
import java.util.Arrays; import
java.util.List;
class LowerBoundedWildcardDemo {
public static void main(String[] args) {
//Lower Bounded Integer List
List<Integer> list1 = Arrays.asList(1,2,3,4);
//Integer list object is being passed
print(list1);
//Lower Bounded Number list
List<Number> list2 = Arrays.asList(1,2,3,4);
//Integer list object is being passed
print(list2);
}

public static void print(List<? super Integer> list) {


System.out.println(list);
}
}

Output
[1, 2, 3, 4]
[1, 2, 3, 4]

Here, the print method is used to calculate the print both Integer list and Number
list elements as it accepts list as a parameter whse lower bound is Integer.

9
3. UNBOUNDED WILDCARDS
The unbounded wildcard type is specified using the wildcard character (?), for
example, List<?>. This is called a list of unknown type.

Consider the following method, printList:


public static void printList(List<Object> list) {
for (Object elem : list)
System.out.println(elem + " ");
System.out.println();
}
The goal of printList is to print a list of any type, but it fails to achieve that goal
— it prints only a list of Object instances; it cannot print List<Integer>,
List<String>, List<Double>, and so on, because they are not subtypes of
List<Object>.
To write a generic printList method, use List<?>:
Example: Program that demonstrates UnBounded Wildcards
import java.util.Arrays; import
java.util.List; public class
UnboundedWildcardDemo {
public static void printList(List<?> list) {
for (Object elem : list) {
System.out.println(elem + " ");
}
System.out.println();
}
public static void main(String args[]) {
List<Integer> li = Arrays.asList(1, 2, 3);
List<String> ls = Arrays.asList("one", "two",
"three"); printList(li); printList(ls);
}
}

10
AJAVA-Unit 1: Collection and Generics

Output
1
2 3
one
two
three
Here, li and ls are Integer and String lists created from Arrays and both lists are
printed using the generic method printList.

1.3 Introduction To Java Collections

Before Collections, the standard way used for grouping data was using the array,
Vector and HashTable. But all of these have different methods and syntax for
accessing data and performing operations on it. For example, Arrays uses the
square brackets symbol [] to access individual data members whereas Vector uses
the method elementAt(). These differences led to a lot of discrepancies. Thus, the
“Collection Framework” was introduced in JDK 1.2 to bring a unified mechanis m
to store and manipulate a group of objects.
1.3.1 JAVA COLLECTION FRAMEWORK
Any group of objects which are represented as a single unit is known as the
collection of the objects. In Java Collections, individual objects are called as
elements.
The “Collection Framework” holds all the collection classes and interface in it.
These classes and interfaces define all operations that you can perform unifor mly
on different types of data such as searching, sorting, insertion, manipulation, and
deletion.
The Java Collection framework has
1. Interfaces and its implementations, i.e., classes
2. Algorithm

11
1.3.2 JAVA COLLECTION HIERARCHY
The java.util package contains all the classes and interfaces for the Collection
framework.

The Collection interface is the root of the collection hierarchy and is


implemented by all the classes in the collection framework.
The Collections framework has a set of core interfaces. They are:

 List
 Set
 Map
 Queue
The Collection classes implement these interfaces and provide plenty of methods
for adding, removing and manipulating data.
1.3.3 ADVANTAGES OF COLLECTION FRAMEWORK
1. Consistent API: The API has a basic set of interfaces like Collection, Set,
List, or Map, all the classes (ArrayList , LinkedList, Vector, etc) that
implement these interfaces have some common set of methods.
2. Reduces programming effort: A programmer doesn’t have to worry about
the design of the Collection but rather he can focus on its best use in his
program. Therefore, the basic concept of Object-oriented programming (i.e.)
abstraction has been successfully implemented.
3. Increases program speed and quality: Increases performance by providing
high-performance implementations of useful data structures and algorithms.

12
AJAVA-Unit 1: Collection and Generics
4. Clean code – These APIs have been written with all good coding practices
and documented very well. They follow a certain standard across whole Java
collection framework. It makes the programmer code look good and clean.
1.3.4 BASIC AND BULK OPERATIONS ON JAVA COLLECTION
The Collection Interface provides methods that performs basic operations on data
such as:
Methods Description
boolean add(E element) Used to add an element in the collection

boolean remove(Object Used to delete an element from the collection


element)

int size() Returns the total number of elements in the


collection
Iterator<E> iterator() Returns an iterator over the elements in the
collection

boolean contains(Object Returns true if the collection contains the


element) specified element
boolean isEmpty() Returns true if the collection is empty

The Collection Interface also contains methods that performs operations on entire
collections which are also called as bulk operations.
Methods Description

boolean containsAll(Collection<?> c) Used to check if this collectio n


contains all the elements in the
invoked collection.
boolean addAll(Collection<? extends E> Used to insert the specified
c) collection elements in the invoking
collection.

boolean removeAll(Collection<?> c) Used to delete all the elements of


the specified collection from the
invoking collection.

boolean retainAll(Collection<?> c) Used to delete all the elements of


invoking collection except the
specified collection.

13
void clear() Removes all the elements from the
collection.
Iterator interface
It provides the facility of iterating the elements in a collection.
Method Description

public boolean hasNext() It returns true if the iterator has more


elements otherwise it returns false.

public Object next() It returns the element and moves the


cursor pointer to the next element.

public void remove() It removes the last elements returned


by the iterator. It is less used.

LIST

List in Java provides the facility to maintain the ordered collection. It contains the
index-based methods to insert, update, delete and search the elements. It can have
the duplicate elements also. We can also store the null elements in the list.
The List interface is found in the java.util package and inherits the Collec tio n
interface. It is a factory of ListIterator interface. Through the ListIterator, we can
iterate the list in forward and backward directions.

The List interface is declared as:


public interface List<E> extends Collection<E>
1.4.1 METHODS OF LIST INTERFACE
Method Description

void add(int index, E It is used to insert the specified element at the


element) specified position in a list.
It is used to append the specified element at the end
boolean add(E e) of a list.
It is used to remove all of the elements from this
void clear() list.

14
AJAVA-Unit 1: Collection and Generics

It is used to compare the specified object with the


boolean equals(Object o) elements of a list.

int hashcode() It is used to return the hash code value for a list.
boolean isEmpty() It returns true if the list is empty, otherwise false.
It is used to return the index in this list of the last
int lastIndexOf(Object occurrence of the specified element, or -1 if the list
o) does not contain this element.

1.4.2 HOW TO CREATE LIST?


Since List is an interface, a concrete implementation of the interface needs to be
instantiated, in order to use it.
The implementation classes of List interface are ArrayList, LinkedList, Stack and
Vector.
 //Creating a List of type String using java.util.ArrayList
List<String> list=new ArrayList<String>();
 //Creating a List of type String using LinkedList
List<String> list=new LinkedList<String>();
 java.util.Vector
List list1=new Vector();
 java.util.Stack
List list1=new Stack();
The ArrayList and LinkedList are widely used in Java programming.
ArrayList
ArrayList is a variable length array of object references.It can dynamically increase
or decrease in size. It can be created with an initial size. When this size is
exceeded,the collection is automatically enlarged. When objects are removed, the
array may be shrunk.

15
Example: Program that demonstrates List using ArrayList class

import java.util.*; public class


ArrayListDemo { public static void
main(String[] args) {
// Creating a list
List<Integer> l1= new ArrayList<Integer>();
// Adds 1 at 0 index
l1.add(0, 1);
// Adds 2 at 1 index
l1.add(1, 2);
System.out.println(l1);
// Creating another list
List<Integer> l2= new
ArrayList<Integer>(); l2.add(1);
l2.add(2); l2.add(3);
// Will add list l2 from 1 index
l1.addAll(1, l2);
System.out.println(l1);
// Removes element from index 1
l1.remove(1);
System.out.println(l1);
// Prints element at index 3
System.out.println(l1.get(3));
// Replace 0th element with 5
l1.set(0, 5);
System.out.println(l1);
}
}

Output:
[1, 2]
[1, 1, 2, 3, 2]
[1, 2, 3, 2]
2
[5, 2, 3, 2]

16
AJAVA-Unit 1: Collection and Generics
LinkedList
LinkedList is a class which is implemented in the collection framework which
inherently implements the linked list data structure. It is a linear data structure
where the elements are not stored in contiguous locations and every element is a
separate object with a data part and address part. The elements are linked using
pointers and addresses. Each element is known as a node. Linked List permits
insertion and deletion of nodes at any point in the list in constant time, but do not
allow random access. It permits all elements including null.
Example: Program that demonstrates List using LinkedList class
import java.io.*; import java.util.*;
class LinkedListDemo { public
static void main(String[] args)
{
// Size of the LinkedList
int n = 5;

// Declaring the List with initial size n


List<Integer> ll = new LinkedList<Integer>();

// Appending the new elements


// at the end of the list
for (int i = 1; i <= n; i++)
ll.add(i);

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

// Remove element at index 3


ll.remove(3);

// Displaying the list after deletion


System.out.println(ll);

// Printing elements one by one


for (int i = 0; i < ll.size(); i++)
System.out.print(ll.get(i) + " ");
}
}

17
Output:
[1, 2, 3, 4, 5]
[1, 2, 3, 5]
1235
1.4.3 ITERATING THROUGH THE LIST
There are multiple ways to iterate through the List. The most famous ways are by
using the basic for loop in combination with a get() method to get the element at
a specific index and the advanced for loop.
Example: Program that iterates through an ArrayList
import java.util.*; public class
ArrayListIteration { public static
void main(String args[])
{
List<String> al= new ArrayList<String>();

al.add("Ann");
al.add("Bill");
al.add(“Cathy”);

// Using the Get method and the for loop


for (int i = 0; i < al.size(); i++) {
System.out.print(al.get(i) + " ");
}

System.out.println();

// Using the for each loop


for (String str : al)
System.out.print(str + " ");
}
}

Output:
Ann Bill Cathy
Ann Bill Cathy

18
AJAVA-Unit 1: Collection and Generics

1.5 Set

The set extends the Collection interface is an unordered collection of objects in


which duplicate values cannot be stored. This interface is present in the java.util
package and contains the methods inherited from the Collection interface. The
most popular classes which implement the Set interface are HashSet and TreeSet.
The List interface is declared as:
public interface Set extends Collection
1.5.1 METHODS OF SET INTERFACE
Method Description
add(element) It is used to add a specific element to the set.
It is used to append all of the elements from the
addAll(collection) mentioned collection to the existing set
It is used to remove all the elements from the set but
clear() not delete the set. The reference for the set still
exists.

It is used to check whether a specific element is


contains(element) present in the Set or not.
isEmpty() It is used to check whether the set is empty or not.
It is used to return the ‹ – ‡ ” ƒ – ‘ ” of the set. The
iterator() elements from the set are returned in a random
order.

1.5.2 HASHSET CLASS


HashSet class which is implemented in the collection framework is an inherent
implementation of the hash table datastructure. This class does not allow storing
duplicate elements but permits NULL elements. The objects that we insert into the
hashset does not guarantee to be inserted in the same order. The objects are inserted
based on their hashcode.
Example: Program that demonstrates HashSet implementation
import java.util.*;
class HashSetDemo{
public static void main(String[] args)
{
Set<String> h = new HashSet<String>();

19
// Adding elements into the HashSet
h.add("India");
h.add("Australia");
h.add("South Africa");

// Adding the duplicate element


h.add("India");

// Displaying the HashSet


System.out.println(h);

// Removing items from HashSet


h.remove("Australia");
System.out.println("Set after removing "+ "Australia:" + h);

// Iterating over hash set items


System.out.println("Iterating over
set:"); Iterator<String> i = h.iterator();
while (i.hasNext())
System.out.println(i.next());
}
}
Output:
[South Africa, Australia, India]
Set after removing Australia:[South Africa, India] Iterating over set:
South Africa
India

1.5.3 TREESET CLASS


TreeSet class which is implemented in the collections framework and
implementation of the SortedSet Interface and SortedSet extends Set Interface. It
behaves like a simple set with the exception that it stores elements in a sorted
format. TreeSet uses a tree data structure for storage. Objects are stored in sorted,
ascending order.

20
AJAVA-Unit 1: Collection and Generics
Example: Program that demonstrates TreeSet implementation
import java.util.*;

class TreeSetDemo { public static


void main(String[] args)
{
Set<String> ts = new TreeSet<String>();

// Adding elements into the


TreeSet ts.add("India");
ts.add("Australia"); ts.add("South
Africa");

// Adding the duplicate element


ts.add("India");

// Displaying the TreeSet


System.out.println(ts);

// Removing items from TreeSet


ts.remove("Australia");
System.out.println("Set after removing "+ "Australia:" + ts);

// Iterating over Tree set items


System.out.println("Iterating over
set:"); Iterator<String> i = ts.iterator();
while (i.hasNext())
System.out.println(i.next());
}
}

Output:
[Australia, India, South Africa]
Set after removing Australia:[India, South Africa]
Iterating over set:
India
South Africa

21
1.6 Maps

The Map interface present in java.util package represents a mapping between a key
and a value. A map contains unique keys and each key can map to at most one
value. Some implementations allow null key and null value like the HashMap and
LinkedHashMap, but some do not like the TreeMap. The order of a map depends
on the specific implementations. For example, TreeMap and LinkedHashMap have
predictable order, while HashMap does not.
The Map interface is not a subtype of the Collection interface. Therefore, it
behaves a bit differently from the rest of the collection types.
The classes which implement the Map interface are HashMap, LinkedHashMap
and TreeMap.
1.6.1 METHODS OF MAP INTERFACE
Method Description

This method is used to clear and remove all of the


clear() elements or mappings from a specified Map
collection.

This method is used to check for equality between


two maps. It verifies whether the elements of one
equals(Object) map passed as a parameter is equal to the elements of
this map or not.

This method is used to retrieve or fetch the value


mapped by a particular key mentioned in the
get(Object) parameter. It returns NULL when the map contains
no such mapping for the key.

This method is used to generate a hashCode for the


hashCode() given map containing key and values.
This method is used to check if a map is having any
isEmpty() entry for key and value pairs. If no mapping exists,
then this returns true.

This method is used to clear and remove all of the


clear() elements or mappings from a specified Map
collection.

1.6.2 HASHMAP
HashMap class implements the Map interface which allows us to store key and
value pair, where keys should be unique. If you try to insert the duplicate key, it

22
AJAVA-Unit 1: Collection and Generics
will replace the element of the corresponding key. It is easy to perform operations
using the key index like updation, deletion, etc. HashMap class is found in the
java.util package.
HashMap in Java is like the legacy Hashtable class, but it is not synchronized. It
allows us to store the null elements as well, but there should be only one null key.
Since Java 5, it is denoted as HashMap<K,V>, where K stands for key and V for
value.

Example: Program that demonstrates HashMap implementation


import java.util.*; public
class HashMapDemo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("Angel", 10); map.put("Liza", 30);
map.put("Steve", 20); for (Map.Entry<String,
Integer> e : map.entrySet()) {
System.out.println(e.getKey() + " " + e.getValue());
}
}
}

Output:
vaibhav 20
vishal 10
sachin 30

1.6.3 LINKEDHASHMAP
LinkedHashMap is just like HashMap with an additional feature of maintaining the
order of elements inserted into it. HashMap provided the advantage of quick
insertion, search and deletion but it never maintained the track and order of
insertion which the LinkedHashMap provides where the elements can be accessed
in their insertion order.

23
Example: Program that demonstrates LinkedHashMap implementation
import java.util.*; public class
LinkedHashMapDemo {
public static void main(String[] args)
{
Map<String, Integer> map= new LinkedHashMap<>();

map.put("Angel", 10);
map.put("Liza", 30);
map.put("Steve", 20);

for (Map.Entry<String, Integer> e : map.entrySet())


System.out.println(e.getKey() + " "+ e.getValue());
}
}

Output:
Angel 10
Liza 30
Steve 20

1.6.4 TREEMAP
The TreeMap in Java is used to implement Map interface and NavigableMap along
with the Abstract Class. It provides an efficient means of storing key-value pairs
in sorted order. TreeMap contains only unique elements and cannot have a null
key but can have multiple null values.
TreeMap is non synchronized and maintains ascending order.
Example: Program that demonstrates TreeMap implementation
import java.util.*;
class TreeMapDemo {
public static void main(String args[]) {
TreeMap<Integer, String> map = new TreeMap<Integer, String>();

24
AJAVA-Unit 1: Collection and Generics

map.put(100, "Angel");
map.put(101, "Chris"); map.put(103,
"Bill"); map.put(102, "Steve");
for (Map.Entry m : map.entrySet()) {
System.out.println(m.getKey() + " " + m.getValue());
}
}
}

Output:
100 Angel
101 Chris
102 Steve
103 Bill

25
Lambda expressions

2.1 Introduction

Lambda expressions is a new and significant feature of Java which was


introduced in Java SE 8 and became very popular as it simplifies code
development. It provides a very clear and concise way to represent single method
interfaces using an expression. It is very useful in collection library. It helps to
iterate, filter and extract data from collection. Lambda Expressions is Java’s first
step towards functional programming. Lambda expression is treated as a functio n,
so compiler does not create .class file.
An interface having a single abstract method is called a Functional Interface or
Single Abstract Method Interface. Lambda expression is used to provide the
implementation of such a functional interface. In case of lambda expression, we
don't need to define the method again for providing the implementation. Here, we
just write the implementation code which saves a lot of code. Pre-Java 8, an
approach for implementing functional interfaces were anonymous inner classes.
However, syntax of anonymous inner classes may seem unclear and cumbersome
at times.
To better understand lambda expressions, let us first look into an example for
implementing functional interfaces with anonymous inner classes.
In the following program, we have an interface Square with a single abstract
method area() in it. We have a class AnonymousClassEx which implements the
method in interface Square using anonymous inner class.
Example: Program to demonstrate Functional Interface Using Anonymous
Classes

26
Chapter 2: Lambda Expressions

interface Square { //Functional Interface public void area();


} public class AnonymousClassEx {
public static void main(String[] args) {
int side = 10;
/* Without Lambda Expressions, Implementation of Square interface using
Anonymous Inner Class */
Square s = new Square() { //Anonymous Class
public void area()
{
System.out.println("Area of square = " + side * side);
}
};
s.area();
}
}

Output:
Area of square = 100
Here you can note that we are rewriting the method declaration code public void
area() written in the interface again in the anonymous inner class. This repetitive
code can be eliminated if we use Lambda Expressions.
2.1.1 WHAT IS LAMBDA EXPRESSION?
A lambda expression refers to a method that has no name and no access specifier
(private, public, or protected) and no return value declaration. This type of method
is also known as ‘Anonymous methods’, ‘Closures’ or simply ‘Lambdas’. It
provides a way to represent one method interface simply by using an expression

Like anonymous class, a lambda expression can be used for performing a task
without a name.
2.1.2 WHY TO USE LAMBDA EXPRESSIONS?

1. Lambda Expressions provides the ability to pass behaviours to methods


2. It provides simplified implementation of Functional Interfaces.
3. Clear and compact syntax
4. Reduces repetitive coding
5. Faster execution time
2.1.3 SYNTAX OF LAMBDA EXPRESSION

27
The basic structure of a lambda expression comprises:

(Parameters-list) -> {Expression body}

• Parameter list: It can be empty or non-empty as well. If non-empty, there


is no need to declare the type of the parameters. The compiler can inference
the same from the value of the parameter. Also, if there is only one
parameter, the parenthesis around the parameter list is optional.

• Arrow-token (->): It is used to link parameters-list and body of expression.


• Expression body: It contains body of lambda expression. If the body has
only one statement then curly braces are optional. You can also use a return
statement, but it should be enclosed in braces as it is not an expression.
Consider the following code snippet for understanding the concept of lambda
expression, in which a simple method is created for showing a message. Let’s first
declare a simple message as:
public void display() {
System.out.println(“Hello World”);
}

Now, we can convert the above method into a lambda expression by removing the
public access specifier, return type declaration, such as void, and the name of
method ‘display’.
The lambda expression is shown as follows:

() -> {
System.out.println(“Hello World”);
}

Thus, we have simplified the code.


Now since we know how to write a Lambda Expression, let’s rewrite Example 2.1
using Lambda Expressions:

Example: Program to demonstrate Functional Interface Implementation Using


Lambda Expressions

28
Chapter 2: Lambda Expressions

interface Square { //Functional Interface public void


area();
}
public class LambdaExpressionEx {
public static void main(String[] args) {
int side=10;

//Implementation of Square Interface using Lambda Expression


Square s= () -> {
System.out.println("Area of square= "+side*side);
};
s.area();
}
}}

Output:
Area of square = 100

Here, you can observe that we have not written the method declaration public void
area() present in the interface while implementing it in the class using lambda
expression. Thus reducing repetitive code.
2.1.4 WHERE CAN LAMBDA EXPRESSIONS BE USED?
Lambda Expressions can be written in any context that has a target datatype. The
contexts that have target type are:
• Variable declarations, assignments and array initializers
• Return statements
• Method or constructor arguments
• Ternary Conditional Expressions (?:)
2.2 LAMBDA TYPE INFERENCE
Type Inference means that the data type of any expression (for e.g., a method return
type or parameter type) can be understood automatically by the compiler. Lambda
Expressions support Type Inference. Type inference allows us to not specify
datatypes for lambda expression parameters. Types in the parameter list can be
omitted since java already know the types of the expected parameters for the single

29
abstract method of functional interface. The compiler infers the type of a
parameter by looking elsewhere for the type - in this case the method definition.
Syntax:
(parameter_name1, parameter_name2 …) -> { method body } Example:

interface Operation{
int add(int a,int b);
}

public class Addition {


public static void main(String[] args) {
Operation ad1=(a,b)->(a+b);
System.out.println(ad1.add(10,20));
}
}

Output:
30

Here, the compiler can infer that a and b must be int because the lambda
expression is assigned to a Operation reference variable.
2.3 LAMBDA PARAMETERS

• A lambda expression can be written with zero to any number of parameters.


• If there are no parameters to be passed, then empty parentheses can be
given.
For Example:

() -> { System.out.println(“Zero Parameter Lambda Expression”); }


Example: Program demonstrating Lambda Expression with no parameter

30
Chapter 2: Lambda Expressions

//Functional Interface interface


MyFunctionalInterface { //A
method with no parameter
public void say(); }

public class ZeroParamLambda {


public static void main(String args[]) {
// lambda expression
MyFunctionalInterface msg = () -> {
System.out.println("Hello");
};
msg.say();
}
}

Output
Hello
• When there is a single parameter, if its type is inferred, it is not mandatory
to use parentheses.
For Example:
(str) -> { System.out.println(“Single Parameter Lambda Expression” + str); }
Example: Program demonstrating Lambda Expression with Single Parameter
//Functional Interface interface
MyFunctionalInterface { //A
method with single parameter
public void say(String str);
} public class SingleParamLambda {
public static void main(String args[]) {
// lambda expression
MyFunctionalInterface msg = (str) -> {
System.out.println(str);
};
msg.say("Hello World");
}
}

31
Output
Hello World
• When there are multiple parameters, they are enclosed in parentheses and
separated by commas.
For Example:
(str1, str2) ->{
System.out.println(“Multiple Parameter Lambda Expression ” +str1+ str2); }
Example: Program demonstrating Lambda Expression with Multiple
Parameters
//Functional Interface interface
MyFunctionalInterface { //A method
with single parameter public void
say(String str1, String str2);
} public class SingleParamLambda {
public static void main(String args[]) {
// lambda expression
MyFunctionalInterface msg = (str1, str2) -> {
System.out.println(str1 +" "+ str2);
};
msg.say("Hello", "Java");
}
}

Output
Hello Java
2.4 LAMBDA FUNCTION BODY
• The body of a lambda expression, and thus the body of the function /
method it represents, is specified to the right of the -> in the lambda
declaration.
() -> {
System.out.println("Hello");
};
• A lambda Expression body can have zero to any number of statements.
• Statements should be enclosed in curly braces.
• If there is only one statement, curly brace is not needed.
• When there is more than one statement in body then these must be enclosed
in curly brackets and the return type of the anonymous function is the same

32
Chapter 2: Lambda Expressions
as the type of the value returned within the code block or void if nothing is
returned.

2.5 RETURNING A VALUE FROM A LAMBDA EXPRESSION


Java lambda expressions can return values , just like from a method. You just add
a return statement to the lambda function body, like this:
(param) -> {
System.out.println("param: " + param); return "return value";
}
In case all your lambda expression is doing is to calculate a return value and
return it, you can specify the return value in a shorter way. Instead of this:
(num1, num2) -> {return num1 > num2; }
You can write:
(num1, num2) -> num1 > num2;
The compiler then figures out that the expression a1 > a2 is the return value of
the lambda expression .
Note: A return statement is not an expression in a lambda expression. We must
enclose statements in curly braces ({}). However, we do not have to enclose a void
method invocation in braces.
Example: Program to demonstrate returning a value from lambda expression
interface Operation{
int add(int a,int b);
}

public class Addition { public static


void main(String[] args) {

// Lambda expression without return keyword.


Operation ad1=(a,b)->(a+b);
System.out.println(ad1.add(10,20));

// Lambda expression with return keyword.


Operation ad2=(int a,int b)->{
return (a+b);
};
System.out.println(ad2.add(30,40));
}

33
}
Output
30
70

2.6 LAMBDAS AS OBJECTS


A Java lambda expression is essentially an object. You can assign a lambda
expression to a variable and pass it around, like you do with any other object. Here
is an example:
public interface MyComparator { public boolean compare(int
num1, int num2);
}

MyComparator c = (num1, num2) -> num1 > num2;


boolean result = c.compare(2, 5);
The first code block shows the interface which the lambda expression impleme nts.
The second code block shows the definition of the lambda expression, how the
lambda expression is assigned to variable, and finally how the lambda expression
is invoked by invoking the interface method it implements.
2.6 LAMBDAS IN COLLECTIONS
Lambda Expressions can also be used with different collections such as
ArrayList, TreeSet, Treemap, etc… to sort elements in it.
Example: Program to sort numbers in an ArrayList using Lambda Expression

34
Chapter 2: Lambda Expressions

import java.util.*; public class Demo {


public static void main(String[] args)
{
ArrayList<Integer> al = new
ArrayList<Integer>(); al.add(205);
al.add(102); al.add(98); al.add(275);
al.add(203);
System.out.println("Elements of the ArrayList before sorting : " + al);

// using lambda expression in place of comparator object


Collections.sort(al, (o1, o2) -> (o1 > o2) ? -1 : (o1 < o2) ? 1 : 0);

System.out.println("Elements of the ArrayList after sorting : " + al);


}
}
Output:

Elements of the ArrayList before sorting : [205, 102, 98, 275, 203]
Elements of the ArrayList after sorting : [275, 205, 203, 102, 98]

2.7 MORE EXAMPLE PROGRAMS USING LAMBDA EXPRESSIONS


1. Write a program using Lambda expression to calculate average of 3
numbers.
interface Operation { double
average(int a, int b, int c);
} class
Calculate {
public static void main(String args[]) {
Operation opr = (a, b, c) -> {
double sum = a + b + c;
return (sum / 3);
};
System.out.println(opr.average(10, 20, 5));
}
}

Output
11.666666666666666

35
2. Write a program to store integer values 1 to 5 in an ArrayList and print all
numbers,even numbers and odd numbers using Lambda expression.
import java.util.ArrayList; class
Test
{ public static void main(String
args[])
{
// Creating an ArrayList with elements 1,2,3,4,5
ArrayList<Integer> arrL = new
ArrayList<Integer>(); arrL.add(1); arrL.add(2);
arrL.add(3); arrL.add(4); arrL.add(5);

System.out.println("Displaying all numbers");


// Using lambda expression to print all elements
arrL.forEach(n -> System.out.println(n));

System.out.println("Displaying even numbers");


// Using lambda expression to print even elements
arrL.forEach(n -> { if (n%2 == 0)
System.out.println(n);

}
);

System.out.println("Displaying odd numbers"); // Using lambda


expression to print odd elements arrL.forEach(n -> { if (n%2 != 0)
System.out.println(n);
}
);
}
}

Output

Displaying all numbers


1
2
3
4
5
Displaying even numbers

36
Chapter 2: Lambda Expressions
2
4
Displaying odd numbers
1
3
5
3. Write a program using Lambda Expressions to calculate the area of circle
with radius 5.
interface Area {
double calculate(int r);
} class
AreaofCircle {
public static void main(String args[])
{ Area a = (r) -> { double
area = 3.142 * r * r; return (area);
};
System.out.println(a.calculate(5));
}
}
Output:
Area of circle=78.55

4. Write a program to create a Student class to store student details such as


id,name and age.Sort student names on the basis of their first names and
age using Lambda Expression.

37
import java.util.ArrayList;
import java.util.List; class
Student { String name;
int age; int id;
public String getName() {
return name;
}
public int getAge() {
return age;
} public int
getId() { return
id;
}

Student(String n, int a, int


i){ name = n; age = a;
id = i;
}
@Override
public String toString() { return
("Student[ "+"Name:"+this.getName()+
" Age: "+ this.getAge() +
" Id: "+ this.getId()+"]");
} } public class
Test1 {
public static void main(String[] args) {
List<Student> studentlist = new ArrayList<Student>();
studentlist.add(new Student("John", 22, 1001));
studentlist.add(new Student("Steve", 19, 1003));
studentlist.add(new Student("Kevin", 23, 1005));
studentlist.add(new Student("Ron", 20, 1010));

38
Chapter 2: Lambda Expressions

studentlist.add(new Student("Chris", 18, 1111));

System.out.println("Before Sorting the student data:");


//forEach for printing the list using lambda expression
studentlist.forEach((s)->System.out.println(s));
System.out.println("\nAfter Sorting the student data by Age:");
//Lambda expression for sorting student data by age and printing it
studentlist.sort((Student s1, Student s2)->s1.getAge()-s2.getAge());
studentlist.forEach((s)->System.out.println(s));
System.out.println("\nAfter Sorting the student data by Name:");
//Lambda expression for sorting the list by student name and printing it
studentlist.sort((Student s1, Student
s2)>s1.getName().compareTo(s2.getName())); studentlist.forEach((s)-
>System.out.println(s));

}
}

Output:
Before Sorting the student data:
Student[ Name:John Age: 22 Id: 1001]
Student[ Name:Steve Age: 19 Id: 1003]
Student[ Name:Kevin Age: 23 Id: 1005]
Student[ Name:Ron Age: 20 Id: 1010]
Student[ Name:Chris Age: 18 Id: 1111] After Sorting the student data by Age:
Student[ Name:Chris Age: 18 Id: 1111]
Student[ Name:Steve Age: 19 Id: 1003]
Student[ Name:Ron Age: 20 Id: 1010]
Student[ Name:John Age: 22 Id: 1001]
Student[ Name:Kevin Age: 23 Id: 1005] After Sorting the student data by Name:
Student[ Name:Chris Age: 18 Id: 1111]
Student[ Name:John Age: 22 Id: 1001]
Student[ Name:Kevin Age: 23 Id: 1005]
Student[ Name:Ron Age: 20 Id: 1010]
Student[ Name:Steve Age: 19 Id: 1003]

39
40

You might also like