Adv. Java Module-1 Notes
Adv. Java Module-1 Notes
Module 1
Collections Framework
Although we can use an array as a container to store a group of elements of the same type (primitives
or objects). The array, however, does not support so-called dynamic allocation - it has a fixed
length which cannot be changed o nce allocated. Furthermore, array is a simple linear structure. Many
applications may require more complex data structure such as linked list, stack, hash table, set, or tree.
A collection, as its name implied, is simply a container object that holds a collection of objects. Each
item in a collection is called an element. A framework, by definition, is a set of interfaces that force
you to adopt some design practices. A well-designed framework can improve your productivity and
provide ease of maintenance.
The collection framework provides a unified interface to store, retrieve and manip ulate the elements of
a collection, regardless of the underlying actual implementation. This allows the programmers to
program at the interface specification, instead of the actual implementation.
The Java Collection Framework package ([Link]) contains:
1. A set of interfaces,
Prior to JDK 1.2, Java's data structures consist of array, Vector, and Hashtable that were designed in a
non-unified way with inconsistent public interfaces. JDK 1.2 introduced the unified collection
framework, and retrofits the legacy classes (Vector and Hashtable) to conform to this
unified collection framework.
JDK 5 introduced Generics (which supports passing of types), and many related features (such as
auto-boxing/auto-unboxing and for-each loop). The collection framework is retrofitted to support
generics and takes full advantages of these new features.
Inheritance and Polymorphism, especially the upcasting and downcasting operations. See
"Inheritance, Substitution, Polymorphism and Type Casting" for a quick summary.
The Collection interface in Java is a core member of the Java Collections Framework located in
the [Link] package. It is one of the root interfaces of the Java Collection Hierarchy.
The Collection interface is not directly implemented by any class. Instead, it is implemented
indirectly through its sub-interfaces like List, Queue, and Set.
For Example, the ArrayList class implements the List interface, a sub-interface of the Collection
interface.
The Collection interface is the foundation upon which the Collections Framework is built because it
must be implemented by any class that defines a collection. Collection is a generic interface that has
this declaration: interface Collection<E>
Here, E specifies the type of objects that the collection will hold. Collection extends the Iterable
interface.
The List interface extends Collection and declares the behavior of a collection that stores a sequence
of elements. Elements can be inserted or accessed by their position in the list, using a zero-based
index. A list may contain duplicate elements. List is a generic interface that has this declaration:
interface List<E>
Here, E specifies the type of objects that the list will hold.
The SortedSet interface extends Set and declares the behavior of a set sorted in ascending order.
SortedSet is a generic interface that has this declaration:
interface SortedSet<E>
Here, E specifies the type of objects that the set will hold.
The NavigableSet interface was added by Java SE 6. It extends SortedSet and declares the behavior of
a collection that supports the retrieval of elements based on the closest match to a given value or
values. NavigableSet is a generic interface that has this declaration:
interface NavigableSet<E>
Here, E specifies the type of objects that the set will hold.
The Queue interface extends Collection and declares the behavior of a queue, which is often a first-in,
first-out list. However, there are types of queues in which the ordering is based upon other criteria.
Queue is a generic interface that has this declaration:
interface Queue<E>
The Deque interface was added by Java SE 6. It extends Queue and declares the behavior of a double-
ended queue. Double-ended queues can function as standard, first-in, first-out queues or as last-in,
first-out stacks. Deque is a generic interface that has this declaration:
interface Deque<E>
Here, E specifies the type of objects that the deque will hold.
The ArrayList class extends AbstractList and implements the List interface. ArrayList is a generic class
that has this declaration:
class ArrayList<E>
Here, E specifies the type of objects that the list will hold.
ArrayList( )
ArrayList(Collection c)
ArrayList(int capacity)
The following program shows a simple use of ArrayList. An array list is created for objects of type
String, and then several strings are added to it.
// Demonstrate ArrayList.
import [Link].*;
class ArrayListDemo {
[Link]("C");
[Link]("A");
[Link]("E");
[Link]("B");
[Link]("D");
[Link]("F");
[Link](1, "A2");
[Link]("F");
[Link](2);
HashSet extends AbstractSet and implements the Set interface. It creates a collection that uses a hash
table for storage. HashSet is a generic class that has this declaration:
class HashSet<E>
Here, E specifies the type of objects that the set will hold.
HashSet( )
HashSet(Collection c)
HashSet(int capacity)
HashSet(int capacity, float fillRatio)
// Demonstrate HashSet.
import [Link].*;
class HashSetDemo {
[Link]("B");
[Link]("A");
[Link]("D");
[Link]("E");
[Link]("C");
[Link]("F");
[Link](hs);
The LinkedHashSet class extends HashSet and adds no members of its own. It is a generic class that
has this declaration:
Here, E specifies the type of objects that the set will hold. Its constructors parallel those in HashSet.
TreeSet extends AbstractSet and implements the NavigableSet interface. It creates a collection that
uses a tree for storage. Objects are stored in sorted, ascending order. Access and retrieval times are
quite fast, which makes TreeSet an excellent choice when storing large amounts of sorted information
that must be found quickly. TreeSet is a generic class that has this declaration:
class TreeSet<E>
Here, E specifies the type of objects that the set will hold.
TreeSet( )
TreeSet(Collection c)
TreeSet(Comparator comp)
TreeSet(SortedSet ss)
// Demonstrate TreeSet.
import [Link].*;
class TreeSetDemo {
[Link]("C");
[Link]("A");
[Link]("B");
[Link]("E");
[Link]("F");
[Link]("D");
[Link](ts);
}}
PriorityQueue extends AbstractQueue and implements the Queue interface. It creates a queue that is
prioritized based on the queue’s comparator. PriorityQueue is a generic class that has this declaration:
class PriorityQueue<E>
Here, E specifies the type of objects stored in the queue. PriorityQueues are dynamic, growing as
necessary.
PriorityQueue( )
PriorityQueue(int capacity)
PriorityQueue(int capacity, Comparator<? super E> comp)
PriorityQueue(Collection<? extends E> c)
PriorityQueue(PriorityQueue<? extends E> c)
PriorityQueue(SortedSet<? extends E> c)
Java SE 6 added the ArrayDeque class, which extends AbstractCollection and implements the Deque
interface. It adds no methods of its own. ArrayDeque creates a dynamic array and has no capacity
restrictions. (The Deque interface supports implementations that restrict capacity, but does not require
such restrictions.) ArrayDeque is a generic class that has this declaration:
class ArrayDeque<E>
ArrayDeque( )
ArrayDeque(int size)
ArrayDeque(Collection<? extends E> c)
// Demonstrate ArrayDeque.
import [Link].*;
class ArrayDequeDemo {
[Link]("A");
[Link]("B");
[Link]("D");
[Link]("E");
[Link]("F");
while([Link]() != null)
[Link]();
EnumSet extends AbstractSet and implements Set. It is specifically for use with keys of an enum type.
It is a generic class that has this declaration:
Here, E specifies the elements. Notice that E must extend Enum, which enforces the requirement that
the elements must be of the specified enum type.
An iterator, which is an object that implements either the Iterator or the list iterator interface.
ListIterator extends Iterator to allow bidirectional traversal of a list, and the modification of elements.
Iterator and ListIterator are generic interfaces which are declared as shown here:
interface Iterator<E>
In general, to use an iterator to cycle through the contents of a collection, follow these steps:
1. Obtain an iterator to the start of the collection by calling the collection’s iterator( ) method.
2. Set up a loop that makes a call to hasNext( ). Have the loop iterate as long as hasNext( ) returns true.
The following example implements these steps, demonstrating both the Iterator and ListIterator
interfaces. It uses an ArrayList object, but the general principles apply to any type of collection. Of
course, ListIterator is available only to those collections that implement the List interface.
// Demonstrate iterators.
import [Link].*;
class IteratorDemo {
[Link]("C");
[Link]("A");
[Link]("E");
[Link]("B");
[Link]("D");
[Link]("F");
while([Link]()) {
[Link]();
while([Link]()) {
[Link](element + "+");
itr = [Link]();
while([Link]()) {
[Link]();
while([Link]()) {
[Link]();
import [Link].*;
class ForEachDemo {
[Link](1);
[Link](2);
[Link](3);
[Link](4);
[Link](5);
for(int v : vals)
[Link]();
int sum = 0;
for(int v : vals)
sum += v;
import [Link].*;
class Address {
name = n;
street = s;
city = c;
state = st;
code = cd;
return name + "\n" + street + "\n" + city + " " + state + " " + code;
class MailList {
[Link](element + "\n");
[Link]();
**********************************************************************************
Even though Map is part of the Java Collection Framework, it does not extend the Collection
interface.
Because Map does not store single elements, it stores pairs of elements.
Key → Value
[Link](1, "Ravi");
[Link](2, "Anita");
[Link](3, "Kumar");
The SortedMap interface extends Map. It ensures that the entries are maintained in ascending order
based on the keys. SortedMap is generic and is declared as shown here:
Here, K specifies the type of keys, and V specifies the type of values.
The NavigableMap interface was added by Java SE 6. It extends SortedMap and declares the behavior
of a map that supports the retrieval of entries based on the closest match to a given key or keys.
NavigableMap is a generic interface that has this declaration:
Here, K specifies the type of the keys, and V specifies the type of the values associated with the keys.
The [Link] interface enables you to work with a map entry. Recall that the entrySet( ) method
declared by the Map interface returns a Set containing the map entries. Each of these set elements is a
[Link] object. [Link] is generic and is declared like this:
Here, K specifies the type of keys, and V specifies the type of values.
Several classes provide implementations of the map interfaces. The classes that can be used for maps
are summarized here:
The HashMap class extends AbstractMap and implements the Map interface. It uses a hash table to
store the map. This allows the execution time of get( ) and put( ) to remain constant even for large sets.
HashMap is a generic class that has this declaration:
Here, K specifies the type of keys, and V specifies the type of values. The following constructors are
defined: HashMap( ) HashMap(Map m) HashMap(int capacity) HashMap(int capacity, float fillRatio)
import [Link].*;
class HashMapDemo {
[Link]();
The TreeMap class extends AbstractMap and implements the NavigableMap interface. It creates maps
stored in a tree structure. A TreeMap provides an efficient means of storing key/value pairs in sorted
order and allows rapid retrieval. You should note that, unlike a hash map, a tree map guarantees that its
elements will be sorted in ascending key order.
Here, K specifies the type of keys, and V specifies the type of values.
TreeMap( )
TreeMap(Comparator<? super K> comp)
TreeMap(Map<? extends K, ? extends V> m)
TreeMap(SortedMap<K, ? extends V> sm)
import [Link].*;
class TreeMapDemo {
[Link]([Link]());
[Link]();
[Link]("John Doe"));
LinkedHashMap extends HashMap. It maintains a linked list of the entries in the map, in the order in
which they were inserted. This allows insertion-order iteration over the map. That is, when iterating
through a collection-view of a LinkedHashMap, the elements will be returned in the order in which
they were inserted.
Here, K specifies the type of keys, and V specifies the type of values
LinkedHashMap( )
LinkedHashMap(Map<? extends K, ? extends V> m)
LinkedHashMap(int capacity)
LinkedHashMap(int capacity, float fillRatio)
LinkedHashMap(int capacity, float fillRatio, boolean Order)
import [Link].*;
class LinkedHashMapDemo {
public static void main(String[] args) {
// Create a LinkedHashMap
LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
IdentityHashMap extends AbstractMap and implements the Map interface. It is similar to HashMap
except that it uses reference equality when comparing elements. IdentityHashMap is a generic class
that has this declaration:
IdentityHashMap is a Map class that uses == to compare keys, not equals().
class IdentityHashMap<K, V>
Here, K specifies the type of key, and V specifies the type of value. The API documentation explicitly
states that IdentityHashMap is not for general use.
import [Link].*;
class IdentityHashMapDemo {
public static void main(String[] args) {
EnumMap extends AbstractMap and implements Map. It is specifically for use with keys of an enum
type. It is a generic class that has this declaration:
Here, K specifies the type of key, and V specifies the type of value.
Notice that K must extend Enum<K>, which enforces the requirement that the keys must be of an
enum type.
EnumMap(Class<K> kType)
EnumMap(Map<K, ? extends V> m)
EnumMap(EnumMap<K, ? extends V> em)
import [Link].*;
enum Day {
MON, TUE, WED, THU, FRI
}
class EnumMapDemo {
public static void main(String[] args) {
[Link]([Link], "Work");
[Link]([Link], "Study");
[Link]([Link], "Play");
[Link](map);
}
}
*********************************************************************************
Comparators
Comparator interface in Java is used to order the objects of user-defined classes. Comparator is a
generic interface that has this declaration:
interface Comparator<T>
The Comparator interface defines two methods: compare( ) and equals( ). The compare( ) method,
shown here, compares two elements for order:
obj1 and obj2 are the objects to be compared. This method returns zero if the objects are [Link]
returns a positive value if obj1 is greater than obj2.
Using a Comparator
import [Link].*;
// Add elements
[Link]("C");
[Link]("A");
[Link]("B");
[Link]("E");
[Link]("F");
[Link]("D");
// Display elements
[Link]("Elements in reverse sorted order:");
for(String element : ts) {
[Link](element + " ");
}
}
}
The Collections Framework defines several algorithms that can be applied to collections and maps.
These algorithms are defined as static methods within the Collections class.
Collections defines three static variables: EMPTY_SET, EMPTY_LIST, and EMPTY_MAP. All are immutable.
import [Link].*;
class AlgorithmsDemo {
[Link](-8);
[Link](20);
[Link](-20);
[Link](8);
Comparator<Integer> r = [Link]();
[Link](ll, r);
for(int i : ll)
[Link]();
// Shuffle list.
[Link](ll);
for(int i : ll)
[Link]();
************************************************************************************************
Arrays
The Arrays class provides various methods that are useful when working with arrays. These methods
help bridge the gap between collections and arrays. Each method defined by Arrays is examined in this
[Link] asList( ) method returns a List that is backed by a specified array. In other words, both the
list and the array refer to the same location. It has the following signature:
The binarySearch( ) method uses a binary search to find a specified value. This method must be
applied to sorted arrays
Here, array is the array to be searched, and value is the value to be located. The last two forms throw a
ClassCastException if array contains elements that cannot be compared (for example, Double and
StringBuffer) or if value is not compatible with the types in array.
The copyOf( ) method was added by Java SE 6. It returns a copy of an array and has the following
forms:
The original array is specified by source, and the length of the copy is specified by len. If the copy is
longer than source, then the copy is padded with zeros (for numeric arrays), nulls (for object
arrays), or false (for boolean arrays). If the copy is shorter than source, then the copy is truncated.
In the last form, the type of resultT becomes the type of the array returned. If len is negative, a
NegativeArraySizeException is thrown. If source is null, a NullPointerException is thrown. If
resultT is incompatible with the type of source, an ArrayStoreException is thrown.
The copyOfRange( ) method was also added by Java SE 6. It returns a copy of a range within an array
and has the following forms:
The equals( ) method returns true if two arrays are equivalent. Otherwise, it returns false.
Here, array1 and array2 are the two arrays that are compared for equality
The fill( ) method assigns a value to all elements in an array. In other words, it fills an array with a
specified value. The fill( ) method has two versions. The first version, which has the following forms,
fills an entire array:
The second version of the fill( ) method assigns a value to a subset of an array. Its forms are shown
here:
static void fill(boolean array[ ], int start, int end, boolean value)
static void fill(byte array[ ], int start, int end, byte value)
static void fill(char array[ ], int start, int end, char value)
static void fill(double array[ ], int start, int end, double value)
static void fill(float array[ ], int start, int end, float value)
static void fill(int array[ ], int start, int end, int value)
static void fill(long array[ ], int start, int end, long value)
static void fill(short array[ ], int start, int end, short value)
static void fill(Object array[ ], int start, int end, Object value)
Here, value is assigned to the elements in array from position start to position end–1.
The sort( ) method sorts an array so that it is arranged in ascending order. The sort( ) method has two
versions. The first version, shown here, sorts the entire array:
Here, array is the array to be sorted. In the last form, c is a Comparator that is used to order the
elements of array
The second version of sort( ) enables you to specify a range within an array that you want to sort. Its
forms are shown here:
Here, the range beginning at start and running through end–1 within array will be sorted.
The following program illustrates how to use some of the methods of the Arrays class:
// Demonstrate Arrays
import [Link].*;
class ArraysDemo {
array[i] = -3 * i;
display(array);
[Link](array);
[Link]("Sorted: ");
display(array);
[Link](array, 2, 6, -1);
display(array);
[Link](array);
display(array);
int index =
[Link](array, -9);
[Link](index);
for(int i: array)
[Link]();
*********************************************************************************
Legacy classes are older collection classes that existed before the introduction of the Java
Collections Framework and are retained in Java for compatibility with old programs.
There is one legacy interface called Enumeration. The following sections examine Enumeration and
each of the legacy classes, in turn.
The Enumeration interface defines the methods by which you can enumerate (obtain one at a time) the
elements in a collection of objects. This legacy interface has been superseded by Iterator
interface Enumeration<E>
boolean hasMoreElements( )
E nextElement( )
When implemented, hasMoreElements( ) must return true while there are still more elements to
extract, and false when all the elements have been enumerated. nextElement( ) returns the next
object in the enumeration. That is, each call to nextElement( ) obtains the next object in the
enumeration. It throws NoSuchElementException when the enumeration is complete.
Vector
Vector implements a dynamic array. It is similar to ArrayList, but with two differences: Vector is
synchronized, and it contains many legacy methods that are not part of the Collections Framework.
With the advent of collections, Vector was reengineered to extend AbstractList and to implement
the List interface. With the release of JDK 5, it was retrofitted for generics and reengineered to
implement Iterable. This means that Vector is fully compatible with collections, and a Vector can
have its contents iterated by the enhanced for loop.
class Vector<E>
Vector( )
Vector(int size)
Vector(int size, int incr)
Vector(Collection<? extends E> c)
The first form creates a default vector, which has an initial size of 10. The second form creates a vector
whose initial capacity is specified by size. The third form creates a vector whose initial capacity is
specified by size and whose increment is specified by incr. The increment specifies the number of
elements to allocate each time that a vector is resized upward.
int capacityIncrement;
int elementCount;
Object[ ] elementData;
The increment value is stored in capacityIncrement. The number of elements currently in the vector is
stored in elementCount. The array that holds the vector is stored in elementData.
import [Link].*;
class VectorDemo {
[Link]());
[Link](1);
[Link](2);
[Link](3);
[Link](4);
[Link](5);
[Link](6);
[Link](7);
[Link](9);
if([Link](3))
[Link]("\nElements in vector:");
while([Link]())
[Link]();
[Link]("\nElements in vector:");
while([Link]())
[Link]();
You can also use a for-each for loop to cycle through a Vector, as the following version of the
preceding code shows:
[Link]("\nElements in vector:");
for(int i : v)
[Link]();
Stack
Stack is a subclass of Vector that implements a standard last-in, first-out stack. Stack only defines the
default constructor, which creates an empty stack. With the release of JDK 5, Stack was retrofitted for
generics and is declared as shown here:
class Stack<E>
import [Link].*;
class StackDemo {
stack: []
static void showpush(Stack<Integer> st, int a) { push(42)
stack: [42]
[Link](a); push(66)
stack: [42, 66]
[Link]("push(" + a + ")"); push(99)
stack: [42, 66, 99]
[Link]("stack: " + st); pop -> 99
stack: [42, 66]
pop -> 66
} stack: [42]
pop -> 42
static void showpop(Stack<Integer> st) { stack: []
pop -> empty stack
[Link]("pop -> ");
Integer a = [Link]();
[Link](a);
showpush(st, 42);
showpush(st, 66);
showpush(st, 99);
showpop(st);
showpop(st);
showpop(st);
try {
showpop(st);
} catch (EmptyStackException e) {
[Link]("empty stack");
Dictionary
Dictionary is an abstract class that represents a key/value storage repository and operates much like
Map. Given a key and value, you can store the value in a Dictionary object. Once the value is stored,
you can retrieve it by using its key.
Here, K specifies the type of keys, and V specifies the type of values.
import [Link].*;
class DictDemo {
public static void main(String args[]) {
Dictionary<Integer, String> d = new Hashtable<>();
[Link](1, "Java");
[Link](2, "Python");
[Link]([Link](1)); // Java
}
Get more study materials and resources at VTUCrack
Date: 12/2/2025
}
Hashtable
Hashtable was part of the original [Link] and is a concrete implementation of a Dictionary.
Here, K specifies the type of keys, and V specifies the type of values.
A hash table can only store objects that override the hashCode( ) and equals( ) methods that are
defined by Object
The Hashtable constructors are shown here: Hashtable( ) Hashtable(int size) Hashtable(int size, float
fillRatio) Hashtable(Map m)
String str;
Get more study materials and resources at VTUCrack
Date: 12/2/2025
double bal;
names = [Link]();
while([Link]()) {
str = [Link]();
[Link]();
import [Link].*;
class HTDemo2 {
String str;
// Get an iterator.
while([Link]()) {
str = [Link]();
[Link]();
Properties
Properties is a subclass of Hashtable. It is used to maintain lists of values in which the key is a String
and the value is also a String. The Properties class is used by many other Java classes. For example, it
is the type of object returned by [Link]( ) when obtaining environmental values.
Although the Properties class, itself, is not generic, several of its methods are.
Get more study materials and resources at VTUCrack
Date: 12/2/2025
Properties defaults;
This variable holds a default property list associated with a Properties object. Properties defines these
constructors:
Properties( )
Properties(Properties propDefault)
The first version creates a Properties object that has no default values.
import [Link].*;
class PropDemo {
[Link]("Illinois", "Springfield");
[Link]("Washington", "Olympia");
Get more study materials and resources at VTUCrack
Date: 12/2/2025
[Link]("California", "Sacramento");
[Link]("Indiana", "Indianapolis");
[Link]();
One of the most useful aspects of Properties is that the information contained in a Properties object can
be easily stored to or loaded from disk with the store( ) and load( ) methods.
import [Link].*;
import [Link].*;
class Phonebook {
throws IOException
try {
} catch(FileNotFoundException e) {
try {
if(fin != null) {
[Link](fin);
[Link]();
} catch(IOException e) {
do {
name = [Link]();
if([Link]("quit")) continue;
number = [Link]();
[Link](name, number);
changed = true;
} while();
if(changed) {
[Link]();
do {
name = [Link]();
if([Link]("quit")) continue;
[Link](number);
} while();
****************************************************************************
Comparators
Comparator interface in Java is used to order the objects of user-defined classes. Comparator is a
generic interface that has this declaration:
interface Comparator<T>
The compare( ) method, shown here, compares two elements for order:
obj1 and obj2 are the objects to be compared. This method returns zero if the objects are equal. It
returns a positive value if obj1 is greater than obj2.
import [Link].*;
// Student class
class Student {
int age;
String name;
// Display result
for (Student s : list) {
[Link]([Link] + " " + [Link]);
}
}
}
The Collection Algorithms
The Collections Framework defines several algorithms that can be applied to collections and maps.
These algorithms are defined as static methods within the Collections class.
Collections define three static variables: EMPTY_SET, EMPTY_LIST, and EMPTY_MAP. All are
immutable.
AbstractCollection
1 Implements most of the Collection interface.
2 AbstractList
Extends AbstractCollection and implements most of the List interface.
AbstractSequentialList
3 Extends AbstractList for use by a collection that uses sequential rather than random
access of its elements.
4 LinkedList
Implements a linked list by extending AbstractSequentialList.
5 ArrayList
Implements a dynamic array by extending AbstractList.
6 AbstractSet
Extends AbstractCollection and implements most of the Set interface.
7 HashSet
Extends AbstractSet for use with a hash table.
8 LinkedHashSet
Extends HashSet to allow insertion-order iterations.
TreeSet
9
Implements a set stored in a tree. Extends AbstractSet.
AbstractMap
10
Implements most of the Map interface.
HashMap
11
Extends AbstractMap to use a hash table.
TreeMap
12
Extends AbstractMap to use a tree.
LinkedHashMap
13
Extends HashMap to allow insertion-order iterations.
IdentityHashMap
14
Extends AbstractMap and uses reference equality when comparing documents.
Arrays
The Arrays class provides various methods that are useful when working with arrays. These methods
help bridge the gap between collections and arrays. Each method defined by Arrays is examined in
this section. The asList( ) method returns a List that is backed by a specified array. In other words,
both the list and the array refer to the same location. It has the following signature:
Vector
1 This implements a dynamic array. It is similar to ArrayList, but with some
differences.
2 Stack
Dictionary
3 Dictionary is an abstract class that represents a key/value storage repository and
operates much like Map.
Hashtable
4 Hashtable was part of the original [Link] and is a concrete implementation of a
Dictionary.
Properties
5 Properties is a subclass of Hashtable. It is used to maintain lists of values in
which the key is a String and the value is also a String.
The Java collections framework gives the programmer access to prepackaged data structures as well as
to algorithms for manipulating them.
A collection is an object that can hold references to other objects. The collection interfaces declare the
operations that can be performed on each type of collection.
The classes and interfaces of the collections framework are in package [Link].