Collection frameworks in Java

Any group of individual objects which are represented as a single unit is known as collection of objects.

Java developers have developed collection framework so that there were so many data structures in Java like Vectors, Arrays,Hashtables and many more where they apply same methods in different ways. the "addElement" method in vector and "put" method in Hashtable has the same purpose of adding an element to the variable.

So Java developers thought of making a single framework where you can all the methods with just a name of the method not the body of implementation such that data strucutres classes or interfaces can decide how to implement a method. It was really big thing in Java coz Collection framework enabled us to integrate all the data strucutre class to single framework and make programmers work easy.

import java.io.*;
import java.util.*;

class CollectionDemo {

    public static void main(String[] args)
    {
        // Creating instances of the array,
        // vector and hashtable
        int arr[] = new int[] { 1, 2, 3, 4 };
        Vector<Integer> v = new Vector();
        Hashtable<Integer, String> h = new Hashtable();

        // Adding the elements into the
        // vector
        v.addElement(1);
        v.addElement(2);

        // Adding the element into the
        // hashtable
        h.put(1, "poshith");
        h.put(2, "hello");

        // Array instance creation requires [],
        // while Vector and hastable require ()
        // Vector element insertion requires addElement(),
        // but hashtable element insertion requires put()

        // Accessing the first element of the
        // array, vector and hashtable
        System.out.println(arr[0]);
        System.out.println(v.elementAt(0));
        System.out.println(h.get(1));

        // Array elements are accessed using [],
        // vector elements using elementAt()
        // and hashtable elements using get()
    }
}
1
1
poshith

You can see in the above pic that how Collection framework is linked to the data structures and make integration happen in java.

Hierachy of Collection Framework:

The utility package(java.util) contains all the classes and interfaces that are required by collection framework. Starting point or root of Collection framework is iterable interface and Collection interface in the framework is implements iterable interface such that the data structures those are linked to collection interface like a subclass can use iterable interface which is used to iterate through data structure which is created.

Main Collection interface has the all the methods defined with no implementation as an abstract class so the data structures like Linkedlist , Stacks , queues will implement their own kind of methods. You can see that Set, List and Queue are the subclass of Collection interface so these interfaces also implements iterable interface can use the methods of it.

  1. List Interface - It is child interface of Collection interface. This interface contains data of the list type in which we can store all the ordered collection of the objects.This also allows duplicate data to be present in it. We can also add duplicate data because list type is ordered and so even a duplicate element have a index number which differentiate the duplicate elements. List interface is implemented by various classes ArrayList, Vector and Linkedlist.

    If you can see the below code example you can see in all the data types you are using add method but implementation of add method is different for linkedlist, arraylist and vector.

     import java.io.*;
     import java.util.*;
    
     class List_Example {
    
         // Main Method
         public static void main(String[] args)
         {
    
             // Declaring the ArrayList with
             // initial size n
             ArrayList<Integer> al = new ArrayList<Integer>();
    
             // Appending new elements at
             // the end of the list
             for (int i = 1; i <= 5; i++)
                 al.add(i);
    
             // Printing elements
             System.out.println(al);
    
             // Remove element at index 3
             al.remove(3);
    
             // Displaying the ArrayList
             // after deletion
             System.out.println(al);
    
             // Printing elements one by one
             for (int i = 0; i < al.size(); i++)
                 System.out.print(al.get(i) + " ");
    
             // Declaring the LinkedList
         LinkedList<Integer> ll = new LinkedList<Integer>();
    
             // Appending new elements at
             // the end of the list
             for (int i = 1; i <= 5; 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) + " ");
                     }
                      // Declaring the Vector
         Vector<Integer> v = new Vector<Integer>();
    
             // Appending new elements at
             // the end of the list
             for (int i = 1; i <= 5; i++)
                     v.add(i);
    
                     // Printing elements
                     System.out.println(v);
    
                     // Remove element at index 3
                     v.remove(3);
    
                     // Displaying the Vector
                     // after deletion
                     System.out.println(v);
    
                     // Printing elements one by one
                     for (int i = 0; i < v.size(); i++){
    
                         System.out.print(v.get(i) + " ");
                     }
         }
    
     [1, 2, 3, 4, 5]
     [1, 2, 3, 5]
     1 2 3 5
     [1, 2, 3, 4, 5]
     [1, 2, 3, 5]
     1 2 3 5
     [1, 2, 3, 4, 5]
     [1, 2, 3, 5]
     1 2 3 5
    
  2. Queue - As the name suggests, a queue interface maintains the FIFO(First In First Out) order similar to a real-world queue line. This interface is dedicated to storing all the elements where the order of the elements matter. There are various classes like PriorityQueue, ArrayDeque, etc

    PriorityQueue - It is basic implementation of queue where first in first out but ther order in which is stored is based on alphabetical order for alphabets or ascending order of numbers. You can also implement comparator constructor which we can make a customised queue based on the how we can order the elements of the queue.

     import java.util.*;
    
     class PriorityQueue {
    
         // Main Method
         public static void main(String args[])
         {
             // Creating empty priority queue
             PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
    
             // Adding items to the pQueue using add()
             pQueue.add(10);
             pQueue.add(20);
             pQueue.add(15);
    
             // Printing the top element of PriorityQueue
             System.out.println(pQueue.peek());
    
             // Printing the top element and removing it
             // from the PriorityQueue container
             System.out.println(pQueue.poll());
    
             // Printing the top element again
             System.out.println(pQueue.peek());
         }
    
     10
     10
     15
    

    Deque Interface: This is a very slight variation of the queue data structure. Deque, also known as a double-ended queue, is a data structure where we can add and remove the elements from both ends of the queue. This interface extends the queue interface. The class which implements this interface is ArrayDeque.

    ArrayDeque: ArrayDeque class which is implemented in the collection framework provides us with a way to apply resizable-array. This is a special kind of array that grows and allows users to add or remove an element from both sides of the queue. Array deques have no capacity restrictions and they grow as necessary to support usage.

     import java.util.*;
     public class ArrayDequeDemo {
         public static void main(String[] args)
         {
             // Initializing an deque
             ArrayDeque<Integer> de_que = new ArrayDeque<Integer>(10);
    
             // add() method to insert
             de_que.add(10);
             de_que.add(20);
             de_que.add(30);
             de_que.add(40);
             de_que.add(50);
    
             System.out.println(de_que);
    
             // clear() method
             de_que.clear();
    
             // addFirst() method to insert the
             // elements at the head
             de_que.addFirst(564);
             de_que.addFirst(291);
    
             // addLast() method to insert the
             // elements at the tail
             de_que.addLast(24);
             de_que.addLast(14);
    
             System.out.println(de_que);
         }
     }
    
     [10, 20, 30, 40, 50]
     [291, 564, 24, 14]
    

    Coolest thing you can see in Deque is that you can even insert elements at First and Last same while deleting or removing elements.

  3. Set Interface: A set is an unordered collection of objects in which duplicate values cannot be stored. This collection is used when we wish to avoid the duplication of the objects and wish to store only the unique objects. This set interface is implemented by various classes like HashSet, TreeSet, LinkedHashSet, etc.

    ```java import java.util.*;

    public class HashSetDemo {

     // Main Method
     public static void main(String args[])
     {
         // Creating HashSet and
         // adding elements
         HashSet<String> hs = new HashSet<String>();
    
         hs.add("Hello");
         hs.add("World");
         hs.add("Welcome");
         hs.add("Home");
    
        // Traversing elements
        System.out.println("HashSet Output:");
        Iterator<String> itr = hs.iterator();
        while (itr.hasNext()) {
            System.out.println(itr.next());
        }

        // Creating LinkedHashSet and
    // adding elements
    LinkedHashSet<String> lhs = new LinkedHashSet<String>();




                // Traversing elements
                Iterator<String> itr = lhs.iterator();
        System.out.println("LinkedHashSet Output: ");
        while (itr.hasNext()) {
        System.out.println(itr.next());
        }
    }
}
```

```java
HashSet Output:
Hello
Welcome
World
Home
LinkedHashSet Output: 
Hello
World
Welcome
Home
```

You can see the code and output as the Hashset elements are not ordered and no duplicate elements where as in LinkedHashset uses a doubly linked list to store the data and retains the ordering of the elements.
  1. Map Interface: A map is a data structure that supports the key-value pair for mapping the data. This interface doesn’t support duplicate keys because the same key cannot have multiple mappings, however it allows duplicate values in different keys. A map is useful if there is data and we wish to perform operations on the basis of the key. This map interface is implemented by various classes like HashMap, TreeMap, etc.

    HashMap: HashMap provides the basic implementation of the Map interface of Java. It stores the data in (Key, Value) pairs. To access a value in a HashMap, we must know its key. HashMap uses a technique called Hashing. Hashing is a technique of converting a large String to a small String that represents the same String so that the indexing and search operations are faster. HashSet also uses HashMap internally.

     import java.util.*;
    
     public class HashMapDemo {
    
         // Main Method
         public static void main(String args[])
         {
             // Creating HashMap and
             // adding elements
             HashMap<Integer, String> hm = new HashMap<Integer, String>();
    
             hm.put(1, "Poshith");
             hm.put(2, "Hello");
             hm.put(3, "World");
    
             // Finding the value for a key
             System.out.println("Value for 1 is " + hm.get(1));
    
             // Traversing through the HashMap
             for (Map.Entry<Integer, String> e : hm.entrySet())
                 System.out.println(e.getKey() + " " + e.getValue());
         }
     }
    
     Value for 1 is Poshith
     1 Poshith
     2 Hello
     3 World