You are on page 1of 20

Collections in Java

The Collection in Java is a framework that provides an architecture to store and manipulate


the group of objects.
Java Collections can achieve all the operations that you perform on a data such as searching,
sorting, insertion, manipulation, and deletion.
Java Collection means a single unit of objects. Java Collection framework provides many
interfaces (Set, List, Queue, Deque) and classes (ArrayList,
Vector, LinkedList, PriorityQueue, HashSet, LinkedHashSet, TreeSet).

What is Collection in Java


A Collection represents a single unit of objects, i.e., a group.

What is a framework in Java


It provides readymade architecture.
It represents a set of classes and interfaces.
It is optional.
What is Collection framework?
The Collection framework represents a unified architecture for storing and manipulating a
group of objects. It has:
Interfaces and its implementations, i.e., classes Algorithm

Hierarchy of Collection Framework


Let us see the hierarchy of Collection framework. The java.util package contains all
the classes and interfaces for the Collection framework.
Methods of Collection interface
There are many methods declared in the Collection interface. They are as follows:

No Method Description
.

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

2 public boolean addAll(Collection<? It is used to insert the specified collection elements


extends E> c) in the invoking collection.

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


element)

4 public boolean It is used to delete all the elements of the specified


removeAll(Collection<?> c) collection from the invoking collection.

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

6 public boolean retainAll(Collection<? It is used to delete all the elements of invoking


> c) collection except the specified collection.

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


collection.

8 public void clear() It removes the total number of elements from the
collection.

9 public boolean contains(Object It is used to search an element.


element)

10 public boolean It is used to search the specified collection in the


containsAll(Collection<?> c) collection.

11 public Iterator iterator() It returns an iterator.

12 public Object[] toArray() It converts collection into array.

13 public <T> T[] toArray(T[] a) It converts collection into array. Here, the runtime
type of the returned array is that of the specified
array.

14 public boolean isEmpty() It checks if collection is empty.

15 default Stream<E> parallelStream() It returns a possibly parallel Stream with the


collection as its source.
16 default Stream<E> stream() It returns a sequential Stream with the collection as
its source.

17 default Spliterator<E> spliterator() It generates a Spliterator over the specified


elements in the collection.

18 public boolean equals(Object It matches two collections.


element)

19 public int hashCode() It returns the hash code number of the collection.

Iterator interface
Iterator interface provides the facility of iterating the elements in a forward direction only.

Methods of Iterator interface


There are only three methods in the Iterator interface. They are:

No. Method Description

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

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

3 public void remove() It removes the last elements returned by the iterator. It is less used.
Iterable Interface
The Iterable interface is the root interface for all the collection classes. The Collection
interface extends the Iterable interface and therefore all the subclasses of Collection interface
also implement the Iterable interface.
It contains only one abstract method. i.e.,
Iterator<T> iterator()  
It returns the iterator over the elements of type T.

Collection Interface
The Collection interface is the interface which is implemented by all the classes in the
collection framework. It declares the methods that every collection will have. In other words,
we can say that the Collection interface builds the foundation on which the collection
framework depends.
Some of the methods of Collection interface are Boolean add ( Object obj), Boolean addAll
( Collection c), void clear(), etc. which are implemented by all the subclasses of Collection
interface.

List Interface
List interface is the child interface of Collection interface. It inhibits a list type data structure
in which we can store the ordered collection of objects. It can have duplicate values.
List interface is implemented by the classes ArrayList, LinkedList, Vector, and Stack.
To instantiate the List interface, we must use :
List <data-type> list1= new ArrayList();  
List <data-type> list2 = new LinkedList();  
List <data-type> list3 = new Vector();  
List <data-type> list4 = new Stack();  
There are various methods in List interface that can be used to insert, delete, and access the
elements from the list.
The classes that implement the List interface are given below.

ArrayList
The ArrayList class implements the List interface. It uses a dynamic array to store the
duplicate element of different data types. The ArrayList class maintains the insertion order
and is non-synchronized. The elements stored in the ArrayList class can be randomly
accessed. Consider the following example.
import java.util.*;  
class TestJavaCollection1{  
public static void main(String args[]){  
ArrayList<String> list=new ArrayList<String>();//Creating arraylist  
list.add("Ravi");//Adding object in arraylist  
list.add("Vijay");  
list.add("Ravi");  
list.add("Ajay");  
//Traversing list through Iterator  
Iterator itr=list.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
}  
}  
Output:
Ravi
Vijay
Ravi
Ajay
LinkedList
LinkedList implements the Collection interface. It uses a doubly linked list internally to store
the elements. It can store the duplicate elements. It maintains the insertion order and is not
synchronized. In LinkedList, the manipulation is fast because no shifting is required.
Consider the following example.
import java.util.*;  
public class TestJavaCollection2{  
public static void main(String args[]){  
LinkedList<String> al=new LinkedList<String>();  
al.add("Ravi");  
al.add("Vijay");  
al.add("Ravi");  
al.add("Ajay");  
Iterator<String> itr=al.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
}  
}  
Output:
Ravi
Vijay
Ravi
Ajay
Vector
Vector uses a dynamic array to store the data elements. It is similar to ArrayList. However, It
is synchronized and contains many methods that are not the part of Collection framework.
Consider the following example.
import java.util.*;  
public class TestJavaCollection3{  
public static void main(String args[]){  
Vector<String> v=new Vector<String>();  
v.add("Ayush");  
v.add("Amit");  
v.add("Ashish");  
v.add("Garima");  
Iterator<String> itr=v.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
}  
}  
Output:
Ayush
Amit
Ashish
Garima
Stack
The stack is the subclass of Vector. It implements the last-in-first-out data structure, i.e.,
Stack. The stack contains all of the methods of Vector class and also provides its methods
like boolean push(), boolean peek(), boolean push(object o), which defines its properties.
Consider the following example.
import java.util.*;  
public class TestJavaCollection4{  
public static void main(String args[]){  
Stack<String> stack = new Stack<String>();  
stack.push("Ayush");  
stack.push("Garvit");  
stack.push("Amit");  
stack.push("Ashish");  
stack.push("Garima");  
stack.pop();  
Iterator<String> itr=stack.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
}  
}  
Output:
Ayush
Garvit
Amit
Ashish
Queue Interface
Queue interface maintains the first-in-first-out order. It can be defined as an ordered list that
is used to hold the elements which are about to be processed. There are various classes like
PriorityQueue, Deque, and ArrayDeque which implements the Queue interface.
Queue interface can be instantiated as:
Queue<String> q1 = new PriorityQueue();  
Queue<String> q2 = new ArrayDeque();  
There are various classes that implement the Queue interface, some of them are given below.

PriorityQueue
The PriorityQueue class implements the Queue interface. It holds the elements or objects
which are to be processed by their priorities. PriorityQueue doesn't allow null values to be
stored in the queue.
Consider the following example.
import java.util.*;  
public class TestJavaCollection5{  
public static void main(String args[]){  
PriorityQueue<String> queue=new PriorityQueue<String>();  
queue.add("Amit Sharma");  
queue.add("Vijay Raj");  
queue.add("JaiShankar");  
queue.add("Raj");  
System.out.println("head:"+queue.element());  
System.out.println("head:"+queue.peek());  
System.out.println("iterating the queue elements:");  
Iterator itr=queue.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
queue.remove();  
queue.poll();  
System.out.println("after removing two elements:");  
Iterator<String> itr2=queue.iterator();  
while(itr2.hasNext()){  
System.out.println(itr2.next());  
}  
}  
}  
Output:
head:Amit Sharma
head:Amit Sharma
iterating the queue elements:
Amit Sharma
Raj
JaiShankar
Vijay Raj
after removing two elements:
Raj
Vijay Raj
Deque Interface
Deque interface extends the Queue interface. In Deque, we can remove and add the elements
from both the side. Deque stands for a double-ended queue which enables us to perform the
operations at both the ends.
Deque can be instantiated as:
Deque d = new ArrayDeque();  
ArrayDeque
ArrayDeque class implements the Deque interface. It facilitates us to use the Deque. Unlike
queue, we can add or delete the elements from both the ends.
ArrayDeque is faster than ArrayList and Stack and has no capacity restrictions.
Consider the following example.
import java.util.*;  
public class TestJavaCollection6{  
public static void main(String[] args) {  
//Creating Deque and adding elements  
Deque<String> deque = new ArrayDeque<String>();  
deque.add("Gautam");  
deque.add("Karan");  
deque.add("Ajay");  
//Traversing elements  
for (String str : deque) {  
System.out.println(str);  
}  
}  
}  
Output:
Gautam
Karan
Ajay
Set Interface
Set Interface in Java is present in java.util package. It extends the Collection interface. It
represents the unordered set of elements which doesn't allow us to store the duplicate items.
We can store at most one null value in Set. Set is implemented by HashSet, LinkedHashSet,
and TreeSet.
Set can be instantiated as:
Set<data-type> s1 = new HashSet<data-type>();  
Set<data-type> s2 = new LinkedHashSet<data-type>();  
Set<data-type> s3 = new TreeSet<data-type>();  
HashSet
HashSet class implements Set Interface. It represents the collection that uses a hash table for
storage. Hashing is used to store the elements in the HashSet. It contains unique items.
Consider the following example.
import java.util.*;  
public class TestJavaCollection7{  
public static void main(String args[]){  
//Creating HashSet and adding elements  
HashSet<String> set=new HashSet<String>();  
set.add("Ravi");  
set.add("Vijay");  
set.add("Ravi");  
set.add("Ajay");  
//Traversing elements  
Iterator<String> itr=set.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
}  
}  
Output:
Vijay
Ravi
Ajay
LinkedHashSet
LinkedHashSet class represents the LinkedList implementation of Set Interface. It extends the
HashSet class and implements Set interface. Like HashSet, It also contains unique elements.
It maintains the insertion order and permits null elements.
Consider the following example.
import java.util.*;  
public class TestJavaCollection8{  
public static void main(String args[]){  
LinkedHashSet<String> set=new LinkedHashSet<String>();  
set.add("Ravi");  
set.add("Vijay");  
set.add("Ravi");  
set.add("Ajay");  
Iterator<String> itr=set.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
}  
}  
Output:
Ravi
Vijay
Ajay
SortedSet Interface
SortedSet is the alternate of Set interface that provides a total ordering on its elements. The
elements of the SortedSet are arranged in the increasing (ascending) order. The SortedSet
provides the additional methods that inhibit the natural ordering of the elements.
The SortedSet can be instantiated as:
SortedSet<data-type> set = new TreeSet();  
TreeSet
Java TreeSet class implements the Set interface that uses a tree for storage. Like HashSet,
TreeSet also contains unique elements. However, the access and retrieval time of TreeSet is
quite fast. The elements in TreeSet stored in ascending order.
Consider the following example:
import java.util.*;  
public class TestJavaCollection9{  
public static void main(String args[]){  
//Creating and adding elements  
TreeSet<String> set=new TreeSet<String>();  
set.add("Ravi");  
set.add("Vijay");  
set.add("Ravi");  
set.add("Ajay");  
//traversing elements  
Iterator<String> itr=set.iterator();  
while(itr.hasNext()){  
System.out.println(itr.next());  
}  
}  
}  
Output:
Ajay
Ravi
Vijay
Storing User-Defined Classes in Collections
 
For the sake of simplicity, the foregoing examples have stored built-in objects, such
as String or Integer, in a collection. Of course, collections are not limited to the storage
of built-in objects. Quite the contrary. The power of collections is that they can store any type
of object, including objects of classes that you create.

For example, consider the following example that uses a LinkedList to store mailing
addresses:
// A simple mailing list example.
import java.util.*;

class Address {/* ww w . d e m o 2 s . c o m*/


private String name;
private String street;
private String city;
private String state;
private String code;

Address(String n, String s, String c,


String st, String cd) {
name = n;
street = s;
city = c;
state = st;
code = cd;
}

public String toString() {


return name + "\n" + street + "\n" +
city + " " + state + " " + code;
}
}
public class Main {
public static void main(String args[]) {
LinkedList<Address> ml = new LinkedList<Address>();

// Add elements to the linked list.


ml.add(new Address("CSS", "11 Main Ave",
"New York", "IL", "12345"));
ml.add(new Address("HTML", "1234 Main Lane",
"New London", "IL", "23456"));
ml.add(new Address("Java", "123 Main St",
"New City", "IL", "98765"));

// Display the mailing list.


for(Address element : ml)
System.out.println(element + "\n");

System.out.println();
}
}

The output from the program is shown here:


Aside from storing a user-defined class in a collection, another important thing to notice
about the preceding program is that it is quite short. When you consider that it sets up a
linked list that can store, retrieve, and process mailing addresses in about 50 lines of code, the
power of the Collections Framework begins to become apparent. As most readers know, if all
of this functionality had to be coded manually, the program would be several times longer.
Collections offer off-the-shelf solutions to a wide variety of programming problems. You
should use them whenever the situation presents itself.

The RandomAccess Interface


SDK 1.4 introduced a java.util.RandomAccess interface for optimizing List performance, but
it has no methods.

What is the purpose of this interface?


What Does RandomAccess Mean?

RandomAccess is a marker interface, like the Serializable and Cloneable interfaces. All these


marker interfaces do not define methods. Instead, they identify a class as having a particular
capability. In the case of Serializable, the interface specifies that if the class is serialized
using the serialization I/O classes, a NotSerializableException will not be thrown (unless the
object contains some other class that cannot be serialized). Cloneable similarly indicates that
the use of the Object.clone( ) method for a Cloneable class will not throw
a CloneNotSupportedException.

The RandomAccess interface identifies that a particular java.util.List implementation has fast


random access. (A more accurate name for the interface would have been
"FastRandomAccess.") This interface tries to define an imprecise concept: what exactly is
fast? The documentation provides a simple guide: if repeated access using
the List.get( ) method is faster than repeated access using the Iterator.next( ) method, then
the List has fast random access. The two types of access are shown in the following code
examples.
Repeated access using List.get( ):
Object o;
for (int i=0, n=list.size( ); i < n; i++)
o = list.get(i);
Repeated access using Iterator.next( ):
Object o;
for (Iterator itr=list.iterator( ); itr.hasNext( ); )
o = itr.next( );
A third loop combines the previous two loops to avoid the repeated Iterator.hasNext( ) test on
each loop iteration:
Object o;
Iterator itr=list.iterator( );
for (int i=0, n=list.size( ); i < n; i++)
o = itr.next( );
This last loop relies on the normal situation where List objects cannot change in size while
they are being iterated through without an exception of some sort occurring. So, because the
loop size remains the same, you can simply count the accessed elements without testing at
each iteration whether the end of the list has been reached. This last loop is generally faster
than the previous loop with the Iterator.hasNext( ) test. In the context of
the RandomAccess interface, the first loop using List.get( ) should be faster than both the
other loops that use Iterator.next( ) for a list to implement RandomAccess.

11.6.2 How Is RandomAccess Used?


So now that we know what RandomAccess means, how do we use it? There are two aspects
to using the other marker interfaces, Serializable and Cloneable: defining classes that
implement them and using their capabilities
via ObjectInput /ObjectOutput and Object.clone( ), respectively. RandomAccess is a little
different. Of course, we still need to decide whether any particular class implements it, but
the possible classes are severely restricted: RandomAccess should be implemented only
in java.util.List classes. And most such classes are created outside of projects. The SDK
provides the most frequently used implementations, and subclasses of the SDK classes do not
need to implement RandomAccess because they automatically inherit the capability where
appropriate.
The second aspect, using the RandomAccess capability, is also different. Whether a class
is Serializable or Cloneable is automatically detected when you
use ObjectInput/ObjectOutput and Object.clone( ). But RandomAccess has no such automatic
support. Instead, you need to explicitly check whether a class
implements RandomAccess using the instanceof operator:
if (listObject instanceof RandomAccess)
...
You must then explicitly choose the appropriate access method, List.get( ) or Iterator.next( ).
Clearly, if we test for RandomAccess on every loop iteration, we would be making a lot of
redundant calls and probably losing the benefit of RandomAccess as well. So the pattern to
follow in using RandomAccess makes the test outside the loop. The canonical pattern looks
like this:
Object o;
if (listObject instanceof RandomAccess)
{
for (int i=0, n=list.size( ); i < n; i++)
{
o = list.get(i);
//do something with object o
}

}
else
{
Iterator itr = list.iterator( );
for (int i=0, n=list.size( ); i < n; i++)
{
o = itr.next( );
//do something with object o
}
}
11.6.3 Speedup from RandomAccess
I tested the four code loops shown in this section, using the 1.4 release, separately testing
the -client (default) and -server options. To test the effect of the RandomAccess interface, I
used
the java.util.ArrayList and java.util.LinkedList classes. ArrayList implements RandomAccess
, while LinkedList does not. ArrayList has an underlying implementation consisting of an
array with constant access time for any element, so using the ArrayList iterator is equivalent
to using the ArrayList.get( ) method but with some additional overhead. LinkedList has an
underlying implementation consisting of linked node objects with access time proportional to
the shortest distance of the element from either end of the list, whereas iterating sequentially
through the list can shortcut the access time by traversing one node after another.
Times shown are the average of three runs, and all times have been normalized to the first
table cell, i.e., the time taken by the ArrayList to iterate the list using the List.get( ) method in
client mode.
Loop type (loop test) andArrayList javaLinkedList javaArrayList javaLinkedList java
access method -client -client -server -server
loop counter (i<n) and
100% too long 77.5% too long
List.get( )
iterator (Iterator.hasNext( ))
141% 219% 109% 213%
and Iterator.next( )
iterator (i<n) and Iterator.next(
121% 205% 98% 193%
)
RandomAccess test with loop
100% 205% 77.5% 193%
from row 1 or 3
The most important results are in the last two rows. The last line shows the times obtained by
making full use of the RandomAccess interface, and the line before that shows the most
optimal general technique for iterating lists if RandomAccess is not available. The size of the
lists I used for the test (and consequently the number of loop iterations required to access
every element) was sufficiently large that the instanceof test had no measurable cost in
comparison to the time taken to run the loop. Consequently, we can see that there was no cost
(but also no benefit) in adding the instanceof RandomAccess test when iterating
the LinkedList, whereas the ArrayList was iterated more than 20% quicker when
the instanceof test was included.
11.6.4 Forward and Backward Compatibility
Can you use RandomAccess and maintain backward compatibility with VM versions prior to
1.4?
There are three aspects to using RandomAccess:

You may want to include code referencing RandomAccess without moving to 1.4.


Many projects need their code to be able to run in any VM, so the code needs to be
backward-compatible to run in VMs using releases earlier than 1.4,
where RandomAccess does not exist.
You will want to make your code forward-compatible so that it automatically takes advantage
of RandomAccess when running in a 1.4+ JVM.
Making RandomAccess available to your development environment is the first issue, and if
you are using an environment prior to 1.4, this can be as simple as adding
the RandomAccess interface to your classpath. Any version of the SDK can create
the RandomAccess interface. The definition for RandomAccess is:
package java.util;
public interface RandomAccess { }
We also need to handle RandomAccess in the runtime environment. For pre-1.4
environments, the test:
if (listObject instanceof RandomAccess)
generates a NoClassDefFoundError at runtime when the JVM tries to load
the RandomAccess class (for the instanceof test to be evaluated, the class has to be loaded).
However, we can guard the test so that it is executed only if RandomAccess is available. The
simplest way to do this is to check whether RandomAccess exists, setting a boolean guard as
the outcome of that test:
static boolean RandomAccessExists;
...

//execute this as early as possible after the application starts


try
{
Class c = Class.forName("java.util.RandomAccess");
RandomAccessExists = true;
}
catch (ClassNotFoundException e)
{
RandomAccessExists = false;
}
Finally, we need to change our instanceof tests to use the RandomAccessExists variable as a
guard:
if (RandomAccessExists && (listObject instanceof RandomAccess) )
With the guarded instanceof test, the code automatically reverts to the Iterator loop
if RandomAccess does not exist and should avoid throwing a NoClassDefFoundError in pre-
1.4 JVMs. And, of course, the guarded instanceof test also automatically uses the faster loop
branch when RandomAccess does exist and the list object implements it.

Working of Map
In Java, elements of Map are stored in key/value pairs. Keys are unique values associated
with individual Values.
A map cannot contain duplicate keys. And, each key is associated with a single value.
We can access and modify values using the keys associated with them.
In the above diagram, we have values: United States, Brazil, and Spain. And we have
corresponding keys: us, br, and es.
Now, we can access those values using their corresponding keys.
Note: The Map interface maintains 3 different sets:
the set of keys
the set of values
the set of key/value associations (mapping).
Hence we can access keys, values, and associations individually.

Classes that implement Map


Since Map is an interface, we cannot create objects from it.
In order to use functionalities of the Map interface, we can use these classes:
HashMap
EnumMap
LinkedHashMap
WeakHashMap
TreeMap
These classes are defined in the collections framework and implement the Map interface.

Java Map Subclasses

Interfaces that extend Map


The Map interface is also extended by these subinterfaces:
SortedMap
NavigableMap
ConcurrentMap

Java Map Sub interfaces


How to use Map?
In Java, we must import the java.util.Map package in order to use Map. Once we import the
package, here's how we can create a map.
// Map implementation using HashMap
Map<Key, Value> numbers = new HashMap<>();
In the above code, we have created a Map named numbers. We have used the HashMap class
to implement the Map interface.
Here,
Key - a unique identifier used to associate each element (value) in a map
Value - elements associated by keys in a map

Methods of Map
The Map interface includes all the methods of the Collection interface. It is
because Collection is a super interface of Map.
Besides methods available in the Collection interface, the Map interface also includes the
following methods:
put(K, V) - Inserts the association of a key K and a value V into the map. If the key is already
present, the new value replaces the old value.
putAll() - Inserts all the entries from the specified map to this map.
putIfAbsent(K, V) - Inserts the association if the key K is not already associated with the
value V.
get(K) - Returns the value associated with the specified key K. If the key is not found, it
returns null.
getOrDefault(K, defaultValue) - Returns the value associated with the specified key K. If the
key is not found, it returns the defaultValue.
containsKey(K) - Checks if the specified key K is present in the map or not.
containsValue(V) - Checks if the specified value V is present in the map or not.
replace(K, V) - Replace the value of the key K with the new specified value V.
replace(K, oldValue, newValue) - Replaces the value of the key K with the new
value newValue only if the key K is associated with the value oldValue.
remove(K) - Removes the entry from the map represented by the key K.
remove(K, V) - Removes the entry from the map that has key K associated with value V.
keySet() - Returns a set of all the keys present in a map.
values() - Returns a set of all the values present in a map.
entrySet() - Returns a set of all the key/value mapping present in a map.
Implementation of the Map Interface
1. Implementing HashMap Class
import java.util.Map;
import java.util.HashMap;

class Main {

public static void main(String[] args) {


// Creating a map using the HashMap
Map<String, Integer> numbers = new HashMap<>();

// Insert elements to the map


numbers.put("One", 1);
numbers.put("Two", 2);
System.out.println("Map: " + numbers);

// Access keys of the map


System.out.println("Keys: " + numbers.keySet());

// Access values of the map


System.out.println("Values: " + numbers.values());

// Access entries of the map


System.out.println("Entries: " + numbers.entrySet());

// Remove Elements from the map


int value = numbers.remove("Two");
System.out.println("Removed Value: " + value);
}
}
Output
Map: {One=1, Two=2}
Keys: [One, Two]
Values: [1, 2]
Entries: [One=1, Two=2]
Removed Value: 2
To learn more about HashMap, visit Java HashMap.

2. Implementing TreeMap Class


import java.util.Map;
import java.util.TreeMap;

class Main {

public static void main(String[] args) {


// Creating Map using TreeMap
Map<String, Integer> values = new TreeMap<>();

// Insert elements to map


values.put("Second", 2);
values.put("First", 1);
System.out.println("Map using TreeMap: " + values);

// Replacing the values


values.replace("First", 11);
values.replace("Second", 22);
System.out.println("New Map: " + values);

// Remove elements from the map


int removedValue = values.remove("First");
System.out.println("Removed Value: " + removedValue);
}
}
Output
Map using TreeMap: {First=1, Second=2}
New Map: {First=11, Second=22}
Removed Value: 11

Comparators:

Please go through the link : Comparator Interface in Java with Examples - GeeksforGeeks

Collection algorithm:

Please go through the link: Java - The Collection Algorithms (tutorialspoint.com)

Arrays:
Please go through the link: Java Array - Javatpoint

Generic Collections:
Please go through the link: Generics in Java - javatpoint

Client server architecture :


Please go through the link: Client-Server Architectures (sjsu.edu)

Java servlets:
Please go through the link: Introduction to Java Servlets - GeeksforGeeks

JDBC:
Please go through the link: JDBC Tutorial | What is Java Database Connectivity(JDBC) -
javatpoint

You might also like