Unit-III Part1
Unit-III Part1
Before Collections:
There are 4 ways to store values in JVM
1. Using variables : can store only one value
2. Using class object : can store multiple fixed number of values of different types
3. Using array object : can store multiple fixed number of values of same type
4. Using collections : can store multiple objects of same and different types
without size limitation
What is Collection?
In general terms a collection is a “group of objects”
Technical Definition:
Collection is a container object. It is used for storing homogeneous and heterogeneous, unique and
duplicate objects without size limitation and further it is used for sending objects at a time from one
class methods to other class methods as method arguments and return type with single name across
multiple layers of the project.
∙ Before java 1.2 it is called simply Java.util package
∙ From java 1.2 onwards its all classes together called as Collections Framework
∙ From java 5 onwards they have added new concepts called Collections and Generics
Java Collections Framework all classes are divided into following 3 different types of classes.
Classes
1. Container Objects classes
2. Cursor Objects classes
3. Utility Objects classes
1. Container Objects classes: Following 4 Interfaces are called container objects
1. List <T> 🡪 HashSet <T>, LinkedHashSet<T>
3. Utility Objects: it is nothing but a class that is given to perform different operations on container
objects are called utility objects i.e two classes
1. Collections class
2. Arrays
The Collection in Java is a framework that provides architecture to store and manipulate the group of
objects.
1. Collections are the containers that groups multiple items in a single unit
2. It provides architecture to store and manipulate a group of objects
3. Using collections various operations can be performed on the data like
∙ searching,
∙ sorting,
∙ insertion,
∙ manipulation,
∙ deletion etc.
4. Java collection framework provide many Interfaces and classes
∙ Java Collection class throws a NullPointerException if the collections or class objects provided to
them are null.
List of Collection Classes:
1) Array List
2) Linked List
3) Vector
4) Stack
5) Priority Queue
6) Array Deque
7) Hash Set
8) Tree Set
9) LinkedHashSet
10) SortedSet
Collections: Overview of Java Collection frame work, commonly used Collection classes – Array List,
Linked List, Hash Set, Tree Set, Collection Interfaces – Collection, List, Set. Accessing Collection via
iterator, working with Map. Legacy classes and interfaces – Vector, Hashtable, Stack, Dictionary,
Enumeration interface.
NOTE In addition to the collection classes, several legacy classes, such as Vector, Stack, and
Hashtable, have been reengineered to support collections.
Here, E specifies the type of objects that the list will hold. ArrayList supports dynamic arrays that can
grow as needed. In Java, standard arrays are of a fixed length. After arrays are created, they cannot
grow or shrink, which means that you must know in advance how many elements an array will hold.
But, sometimes, you may not know until run time precisely how large an array you need. To handle this
situation, the Collections Framework defines ArrayList. In essence, an ArrayList is a variable-length
array of object references. That is, an ArrayList can dynamically increase or decrease in size. Array
lists are created with an initial size. When this size is exceeded, the collection is automatically
enlarged. When objects are removed, the array can be shrunk.
NOTE Dynamic arrays are also supported by the legacy class Vector, which is described later
in this chapter.
ArrayList has the constructors shown here:
ArrayList( )
ArrayList(Collection<? extends E> c)
ArrayList(int capacity)
The first constructor builds an empty array list. The second constructor builds an array list that is
initialized with the elements of the collection c. The third constructor builds an array list that has the
specified initial capacity. The capacity is the size of the underlying array that is used to store the
elements. The capacity grows automatically as elements are added to an array list.
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. (Recall that a quoted string is translated into a String
object.) The list is then displayed. Some of the elements are removed and the list is displayed again.
// Demonstrate ArrayList.
import java.util.*;
class ArrayListDemo {
public static void main(String args[]) {
// Create an array list.
ArrayList<String> al = new ArrayList<String>();
System.out.println("Initial size of al: " +
al.size());
// Add elements to the array list.
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
al.add(1, "A2");
System.out.println("Size of al after additions: " +
al.size());
// Display the array list.
System.out.println("Contents of al: " + al);
// Remove elements from the array list.
al.remove("F");
al.remove(2);
System.out.println("Size of al after deletions: " +
al.size());
System.out.println("Contents of al: " + al);
}
}
The output from this program is shown here:
Initial size of al: 0
Size of al after additions: 7
Contents of al: [C, A2, A, E, B, D, F]
Size of al after deletions: 5
Contents of al: [C, A2, E, B, D]
Notice that a1 starts out empty and grows as elements are added to it. When elements are
removed, its size is reduced.
In the preceding example, the contents of a collection are displayed using the default conversion
provided by toString( ) , which was inherited from AbstractCollection. Although it is sufficient for
short, sample programs, you seldom use this method to display the contents of a real-world collection.
Usually, you provide your own output routines. But, for the next few examples, the default output
created by toString( ) is sufficient.
Although the capacity of an ArrayList object increases automatically as objects are stored in it, you can
increase the capacity of an ArrayList object manually by calling ensureCapacity( ).
You might want to do this if you know in advance that you will be storing many more items in the
collection than it can currently hold. By increasing its capacity once, at the start, you can prevent
several reallocations later. Because reallocations are costly in terms of time, preventing unnecessary
ones improves performance. The signature for ensureCapacity( ) is shown here:
void ensureCapacity(int cap)
Several reasons exist why you might want to convert a collection into an array, such as:
• To obtain faster processing times for certain operations
• To pass an array to a method that is not overloaded to accept a collection
• To integrate collection-based code with legacy code that does not understand collections
Whatever the reason, converting an ArrayList to an array is a trivial matter.
The first returns an array of Object. The second returns an array of elements that have the same type
as T. Normally, the second form is more convenient because it returns the proper type of array. The
following program demonstrates its use:
The program begins by creating a collection of integers. Next, toArray( ) is called and it obtains an
array of Integers. Then, the contents of that array are summed by use of a for-each style for loop.
There is something else of interest in this program. As you know, collections can store only references
to, not values of, primitive types. However, autoboxing makes it possible to pass values of type int to
add( ) without having to manually wrap them within an Integer, as the program shows. Autoboxing
causes them to be automatically wrapped. In this way, autoboxing significantly improves the ease with
which collections can be used to store primitive values.
Here, E specifies the type of objects that the list will hold. LinkedList has the two constructors shown
here:
LinkedList( )
LinkedList(Collection<? extends E> c)
The first constructor builds an empty linked list. The second constructor builds a linked list that is
initialized with the elements of the collection c. Because LinkedList implements the Deque interface,
you have access to the methods defined by Deque. For example, to add elements to the start of a list
you can use addFirst( ) or offerFirst( ). To add elements to the end of the list, use addLast( ) or
offerLast( ). To obtain the first element, you can use getFirst( ) or peekFirst( ). To obtain the last
element, use getLast( ) or peekLast( ). To remove the first element, use removeFirst( ) or pollFirst(
). To remove the last element, use removeLast( ) or pollLast( ).
Because LinkedList implements the List interface, calls to add(E) append items to the end of the list,
as do calls to addLast( ). To insert items at a specific location, use the add(int, E) form of add( ), as
illustrated by the call to add(1, “A2”) in the example. Notice how the third element in ll is changed by
employing calls to get( ) and set( ). To obtain the current value of an element, pass get( ) the index at
which the element is stored. To assign a new value to that index, pass set( ) the index and its new
value.
class HashSet<E>
Here, E specifies the type of objects that the set will hold.
As most readers likely know, a hash table stores information by using a mechanism called hashing. In
hashing, the informational content of a key is used to determine a unique value, called its hash code.
The hash code is then used as the index at which the data associated with the key is stored. The
transformation of the key into its hash code is performed automatically— you never see the hash code
itself. Also, your code can’t directly index the hash table. The advantage of hashing is that it allows the
execution time of add( ), contains( ), remove( ), and size( ) to remain constant even for large sets.
The first form constructs a default hash set. The second form initializes the hash set by using the
elements of c. The third form initializes the capacity of the hash set to capacity. (The default capacity is
16.) The fourth form initializes both the capacity and the fill ratio (also called load capacity) of the hash
set from its arguments. The fill ratio must be between 0.0 and 1.0, and it determines how full the hash
set can be before it is resized upward. Specifically, when the number of elements is greater than the
capacity of the hash set multiplied by its fill ratio, the hash set is expanded. For constructors that do
not take a fill ratio, 0.75 is used. HashSet does not define any additional methods beyond those
provided by its superclasses and interfaces.
It is important to note that HashSet does not guarantee the order of its elements, because the process
of hashing doesn’t usually lend itself to the creation of sorted sets. If you need sorted storage, then
another collection, such as TreeSet, is a better choice.
LinkedHashSet maintains a linked list of the entries in the set, in the order in which they were
inserted. This allows insertion-order iteration over the set. That is, when cycling through a
LinkedHashSet using an iterator, the elements will be returned in the order in which they were
inserted. This is also the order in which they are contained in the string returned by toString( ) when
called on a LinkedHashSet object. To see the effect of LinkedHashSet, try
substituting LinkedHashSet for HashSet in the preceding program. The output will be [B, A, D, E,
C, F] which is the order in which the elements were inserted.
class TreeSet<E>
Here, E specifies the type of objects that the set will hold.
The first form constructs an empty tree set that will be sorted in ascending order according to the
natural order of its elements. The second form builds a tree set that contains the elements of c. The
third form constructs an empty tree set that will be sorted according to the comparator specified by
comp. (Comparators are described later in this chapter.) The fourth form builds a tree set that contains
the elements of ss.
Because TreeSet implements the NavigableSet interface (which was added by Java SE 6), you can use
the methods defined by NavigableSet to retrieve elements of a TreeSet. For example, assuming the
preceding program, the following statement uses subSet( ) to obtain a subset of ts that contains the
elements between C (inclusive) and F (exclusive).
It then displays the resulting set.
System.out.println(ts.subSet()("C", "F"));
The output from this statement is shown here:
[C, D, E]
You might want to experiment with the other methods defined by NavigableSet.