top of page
shubhangisingh453

Learn How to Implement and Use Different Data Structures in Java Programming

Updated: Mar 14, 2023





Data Structures


Data structures are fundamental concepts in computer science and programming that enable efficient storage and manipulation of data. Java is a popular programming language that provides a wide range of built-in data structures, as well as libraries for implementing complex data structures.

Here's a complete tutorial on data structures in Java:

  • Arrays

  • Lists

  • Queue

  • Map

  • Set

Arrays in JAVA


Arrays are a fundamental data structure in Java that allow you to store a collection of elements of the same data type. In this tutorial, we'll cover everything you need to know about arrays in Java.


Declaring and Initializing Arrays


To declare an array in Java, you need to specify the type of elements that the array will store, followed by the name of the array and its size enclosed in square brackets. For example, to declare an array of integers with 5 elements, you would write:


int[] myArray = new int[5];

This creates an array called myArray that can store 5 integers.

To initialize an array with specific values, you can use an array initializer, which is a comma-separated list of values enclosed in curly braces. For example, to initialize myArray with the values 1, 2, 3, 4, and 5, you would write:


int[] myArray = {1, 2, 3, 4, 5};

Accessing Array Elements


You can access elements in an array using their index, which is a zero-based integer that specifies the position of the element in the array. For example, to access the first element of myArray, you would write:

javaCopy code
int firstElement = myArray[0];

This sets the variable firstElement to the value of the first element in myArray.


Modifying Array Elements


You can modify the value of an element in an array by assigning a new value to its index. For example, to change the value of the first element in myArray to 10, you would write:


myArray[0] = 10;

This sets the value of the first element in myArray to 10.


Array Length


You can get the length of an array using the length property. For example, to get the length of myArray, you would write:


int arrayLength = myArray.length;

This sets the variable arrayLength to the length of myArray, which is 5.


Iterating Over Arrays


You can iterate over the elements in an array using a loop. For example, to print all the elements in myArray, you would write:


for (int i = 0; i < myArray.length; i++) {
    System.out.println(myArray[i]);
}

This loop iterates over the indices of myArray and prints each element to the console.


Multidimensional Arrays


Java also supports multidimensional arrays, which are arrays of arrays. For example, to declare a 2D array of integers with 3 rows and 2 columns, you would write:


int[][] myArray = new int[3][2];

This creates a 2D array called myArray that can store 3 rows and 2 columns of integers.

To access an element in a 2D array, you need to specify both the row and column indices. For example, to access the element in the second row and first column of myArray, you would write:


int element = myArray[1][0];

This sets the variable element to the value of the element in the second row and first column of myArray.


Arrays Class:

The Arrays class in Java provides a number of useful methods for working with arrays.

For example, you can use the sort method to sort an array in ascending order:


int[] arr = {3, 2, 1, 5, 4}; Arrays.sort(arr); 
// arr is now {1, 2, 3, 4, 5}

You can use the binarySearch method to search for a value in a sorted array:


int[] arr = {1, 2, 3, 4, 5}; int index = Arrays.binarySearch(arr, 3);
 // index is 2

You can use the copyOf method to create a copy of an array:


int[] arr = {1, 2, 3, 4, 5}; int[] copy = Arrays.copyOf(arr, arr.length); // copy is {1, 2, 3, 4, 5}

Arrays are Objects:

  • In Java, arrays are objects, which means they are created on the heap and have a reference type.

  • You can use the new keyword to create an array object. For example:


int[] arr = new int[5];

Common Array Algorithms:

  • There are a number of common algorithms that can be implemented using arrays, such as searching, sorting, and merging.

  • These algorithms can be implemented using a variety of techniques, such as brute force, divide and conquer, and dynamic programming.

  • Some common algorithms include binary search, merge sort, quick sort, and bubble sort.

LISTS in Java


In Java, a list is an ordered collection of elements that can be of any data type. Lists are used extensively in programming for their flexibility and ease of use.

Java provides several built-in list implementations, including ArrayList, LinkedList, and Vector. Each of these implementations has its own unique properties and performance characteristics, allowing developers to choose the best one for their specific use case.

Here's a brief overview of each of these list implementations:

ArrayList:

  • Implements the List interface using a dynamically resizable array.

  • Provides constant-time access to elements by index.

  • Good for situations where elements are frequently accessed by index, but not frequently added or removed.

  • Not thread-safe.

LinkedList:

  • Implements the List and Deque interfaces using a doubly-linked list.

  • Provides constant-time insertion and removal of elements at the beginning or end of the list.

  • Good for situations where elements are frequently added or removed from the beginning or end of the list.

  • Not as efficient for random access by index as ArrayList.

  • Not thread-safe.

Vector:

  • Implements the List interface using a dynamically resizable array, similar to ArrayList.

  • Provides synchronized access to its elements, making it thread-safe.

  • Generally less performant than ArrayList due to synchronization overhead.

  • Generally not recommended for new development, as the synchronized keyword is not considered a good way to achieve thread safety in modern Java programming.


Creating a List in Java: To create a list in Java, you first need to choose an implementation and import the necessary package. For example, to create an ArrayList:


import java.util.ArrayList;
List<String> myArrayList = new ArrayList<>();

This creates a new ArrayList object that can hold String elements.

Adding Elements to a List: To add an element to a list, use the add() method:


myArrayList.add("Hello");
myArrayList.add("World");

Retrieving Elements from a List: To retrieve an element from a list, use the get() method:


String firstElement = myArrayList.get(0);

This retrieves the element at index 0 (the first element) of the list.

Removing Elements from a List: To remove an element from a list, use the remove() method:


myArrayList.remove(1);

This removes the element at index 1 (the second element) of the list.

Iterating Over a List: To iterate over the elements in a list, you can use a for loop or a for-each loop:


for (int i = 0; i < myArrayList.size(); i++) {
    System.out.println(myArrayList.get(i));
}

for (String element : myArrayList) {
    System.out.println(element);
}

These loops print out each element in the list, one at a time.

This is just a brief overview of working with lists in Java. There are many more advanced features and methods available for working with lists, so it's important to consult the Java documentation for more information.


QUEUE in Java


In Java, a queue is a data structure that follows the first-in-first-out (FIFO) principle. It is used to store a collection of elements in which an element is inserted at one end and removed from the other end.

Java provides the Queue interface in the java.util package, which extends the Collection interface. There are several classes in Java that implement the Queue interface, including LinkedList, PriorityQueue, and ArrayDeque.

Here is an example of how to use a Queue in Java:


import java.util.*;

public class QueueExample {
   public static void main(String[] args) {
      Queue<Integer> q = new LinkedList<>();
      q.add(10);
      q.add(20);
      q.add(30);
      System.out.println("Elements in the Queue: " + q);
      System.out.println("Head of the Queue: " + q.peek());
      System.out.println("Removing element from the Queue: " +q.remove());
      System.out.println("Elements in the Queue after removal: " + q);
   }
}

In the above example, we have created a Queue of integers using the LinkedList class. We have added three elements to the queue using the add method. The peek method is used to return the head element of the queue without removing it. The remove method is used to remove and return the head element of the queue.

The output of the above program would be:


Elements in the Queue: [10, 20, 30]
Head of the Queue: 10Removing element from the Queue: 10Elements in the Queue after removal: [20, 30]

Apart from the basic operations, Queue interface also provides methods like offer to add an element to the queue, poll to remove and return the head element of the queue, isEmpty to check if the queue is empty, size to get the size of the queue, and more.

Different implementations of Queue interface have different characteristics like ordering, sorting, null acceptance, and more. For example, the LinkedList class provides a basic implementation of a queue that is not sorted, while the PriorityQueue class provides an implementation of a queue that is sorted based on the natural order of the elements or a specified Comparator.


Priority Queue


Here is an example of using the PriorityQueue class to implement a sorted queue:


import java.util.*;

public class PriorityQueueExample {
   public static void main(String[] args) {
      Queue<Integer> pq = new PriorityQueue<>();
      pq.add(10);
      pq.add(20);
      pq.add(30);
      System.out.println("Elements in the PriorityQueue: " + pq);
      System.out.println("Head of the PriorityQueue: " + pq.peek());
      System.out.println("Removing element from the PriorityQueue: " + pq.poll());
      System.out.println("Elements in the PriorityQueue after removal: " + pq);
   }
}

In this example, we have used the PriorityQueue class to create a sorted queue of integers. We have added three elements to the queue using the add method. The peek method is used to return the head element of the queue without removing it. The poll method is used to remove and return the head element of the queue.

The output of the above program would be:


Elements in the PriorityQueue: [10, 20, 30]
Head of the PriorityQueue: 10Removing element from the PriorityQueue: 10Elements in the PriorityQueue after removal: [20, 30]

Other classes that implement the Queue interface in Java include the ArrayDeque class, which provides a resizable-array implementation of a queue, and the ConcurrentLinkedQueue class, which provides a thread-safe implementation of a queue.

In summary, a queue is a data structure that allows you to store a collection of elements in a first-in-first-out (FIFO) manner. Java provides the Queue interface and several classes that implement it, each with their own unique characteristics and use cases.


Queue using Linked List

Another example of using the Queue interface in Java is with the LinkedList class, which can be used to implement a queue.


import java.util.*;

public class LinkedListQueueExample {
   public static void main(String[] args) {
      Queue<String> queue = new LinkedList<>();
      queue.add("Alice");
      queue.add("Bob");
      queue.add("Charlie");
      System.out.println("Elements in the LinkedListQueue: " + queue);
      System.out.println("Head of the LinkedListQueue: " + queue.peek());
      System.out.println("Removing element from the LinkedListQueue: " + queue.poll());
      System.out.println("Elements in the LinkedListQueue after removal: " + queue);
   }
}

In this example, we have used the LinkedList class to create a queue of strings. We have added three elements to the queue using the add method. The peek method is used to return the head element of the queue without removing it. The poll method is used to remove and return the head element of the queue.

The output of the above program would be:


Elements in the LinkedListQueue: [Alice, Bob, Charlie]
Head of the LinkedListQueue: Alice
Removing element from the LinkedListQueue: Alice
Elements in the LinkedListQueue after removal: [Bob, Charlie]

In addition to the Queue interface, Java also provides the Deque interface, which extends the Queue interface to provide additional operations for inserting and removing elements at both ends of the queue. The LinkedList class also implements the Deque interface, allowing it to be used as a double-ended queue.

Overall, the Queue interface and its implementations provide a useful data structure for storing and manipulating collections of elements in a FIFO manner. The specific implementation to use will depend on the specific use case and performance requirements.


MAP in Java

In Java, the Map interface represents a mapping between keys and values. The keys are unique and cannot be duplicated, while the values can be duplicated. The Map interface provides methods for adding, retrieving, updating, and removing key-value pairs. In this tutorial, we will cover the basics of the Map interface and its implementations in Java.


The Map Interface


The Map interface is part of the java.util package and provides a key-value mapping for elements. The Map interface provides a number of methods for adding, retrieving, updating, and removing elements. Some of the most commonly used methods of the Map interface include:

  • put(key, value): Inserts the key-value pair into the map.

  • get(key): Returns the value associated with the key.

  • containsKey(key): Returns true if the map contains the specified key.

  • containsValue(value): Returns true if the map contains the specified value.

  • remove(key): Removes the key-value pair associated with the key from the map.

  • size(): Returns the number of key-value pairs in the map.

HashMap


HashMap is the most commonly used implementation of the Map interface. It is based on the hash table data structure and provides constant-time performance for adding, retrieving, updating, and removing elements in the average case. Here is an example of using the HashMap class:


import java.util.HashMap;
import java.util.Map;

public class HashMapExample {
    public static void main(String[] args) {
        Map<String, Integer> ages = new HashMap<>();
        ages.put("Alice", 25);
        ages.put("Bob", 30);
        ages.put("Charlie", 35);
        System.out.println("The age of Alice is " + ages.get("Alice"));
        System.out.println("The size of the map is " + ages.size());
        ages.remove("Bob");
        System.out.println("The size of the map after removal is " + ages.size());
    }
}

In this example, we have created a new HashMap object and added three key-value pairs to it using the put method. We have then retrieved the age of Alice using the get method and printed it to the console. We have also printed the size of the map using the size method. Finally, we have removed the key-value pair associated with the key "Bob" using the remove method.

The output of the above program would be:


The age of Alice is 25
The size of the map is 3
The size of the map after removal is 2

TreeMap


TreeMap is another implementation of the Map interface that is based on a red-black tree data structure. It provides log(n) time performance for adding, retrieving, updating, and removing elements in the worst case. Here is an example of using the TreeMap class:


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

public class TreeMapExample {
    public static void main(String[] args) {
        Map<String, Integer> ages = new TreeMap<>();
        ages.put("Alice", 25);
        ages.put("Bob", 30);
        ages.put("Charlie", 35);
        System.out.println("The age of Alice is " + ages.get("Alice"));
        System.out.println("The size of the map is " + ages.size());
        ages.remove("Bob");
        System.out.println("The size of the map after removal is " + ages.size());
    }
}

In this example, we have created a new TreeMap object and added three key-value pairs to it using the put method. We have then retrieved the age of Alice using the get method and printed it to the console. We have also printed the size of data.


Linked HashMap

Here's an example of how to use the LinkedHashMap class in Java:


import java.util.LinkedHashMap;
import java.util.Map;

public class LinkedHashMapExample {
   public static void main(String[] args) {
      // create a new LinkedHashMap
      Map<String, Integer> map = new LinkedHashMap<String, Integer>();
      
      // add some key-value pairs to the map
      map.put("one", 1);
      map.put("two", 2);
      map.put("three", 3);
      map.put("four", 4);
      map.put("five", 5);
      
      // print out the values in the mapfor (Map.Entry<String, Integer> entry : map.entrySet()) {
         System.out.println(entry.getKey() + ": " + entry.getValue());
      }
   }
}

This code creates a new LinkedHashMap object and adds some key-value pairs to it. The order in which the key-value pairs were added is preserved when iterating over the map using a for-each loop with the entrySet() method. The output of running this program would be:


one: 1
two: 2
three: 3
four: 4
five: 5

As you can see, the order in which the key-value pairs were added to the map is preserved when iterating over the map. This is the main difference between a LinkedHashMap and a regular HashMap in Java.


SETs in Java

Here's an overview of the concepts related to sets in Java:

A set in Java is a collection of unique elements. It is an interface in the Java Collections Framework and has several implementations, including HashSet, TreeSet, and LinkedHashSet.


HashSet

A HashSet is an unordered set of elements. It is implemented using a hash table, and provides constant time performance for the basic operations (add, remove, contains, and size).


TreeSet

A TreeSet is an ordered set of elements. It is implemented using a binary search tree, and provides logarithmic time performance for the basic operations (add, remove, contains, and size).


LinkedHashSet

A LinkedHashSet is a set of elements with predictable iteration order. It is implemented as a hash table with a linked list running through it, and provides constant time performance for the basic operations (add, remove, contains, and size).

Here are some examples of how to use each of these set implementations in Java:


import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.LinkedHashSet;

public class SetExample {
   public static void main(String[] args) {
      // create a new HashSet
      Set<String> hashSet = new HashSet<String>();
      
      // add some elements to the set
      hashSet.add("one");
      hashSet.add("two");
      hashSet.add("three");
      hashSet.add("four");
      
      // print out the elements in the set
      System.out.println("HashSet: " + hashSet);
      
      // create a new TreeSet
      Set<String> treeSet = new TreeSet<String>();
      
      // add some elements to the set
      treeSet.add("one");
      treeSet.add("two");
      treeSet.add("three");
      treeSet.add("four");
      
      // print out the elements in the set
      System.out.println("TreeSet: " + treeSet);
      
      // create a new LinkedHashSet
      Set<String> linkedHashSet = new LinkedHashSet<String>();
      
      // add some elements to the set
      linkedHashSet.add("one");
      linkedHashSet.add("two");
      linkedHashSet.add("three");
      linkedHashSet.add("four");
      
      // print out the elements in the set
      System.out.println("LinkedHashSet: " + linkedHashSet);
   }
}

This code creates a HashSet, a TreeSet, and a LinkedHashSet, and adds some elements to each set. The elements are then printed out using the toString() method. The output of running this program would be:


HashSet: [four, three, two, one]TreeSet: [four, one, three, two]LinkedHashSet: [one, two, three, four]

As you can see, the order of the elements in the HashSet is not guaranteed, while the TreeSet orders the elements based on their natural order (in this case, lexicographic order), and the LinkedHashSet preserves the order in which the elements were added to the set.


Thanks for reading, and happy coding!


Master Android Development in Java Series part-3 -> Java Advanced Programming Tutorial with Examples

bottom of page