Algorithms and Data Structures in Java: A Practical Guide
\n\nMastering algorithms and data structures is a key stage in becoming a Java developer. This is not just theory: understanding how lists, hash tables, and sorting algorithms work directly affects the performance and scalability of your code. In this article, we will cover the main data structures and algorithms in Java with practical examples that will help you write more efficient programs.
\n\n1. Dynamic Arrays: ArrayList
\n\nArrayList is an implementation of a dynamic array in Java. Unlike a regular array, its size automatically increases when new elements are added. This is one of the most frequently used data structures.
Basic Operations
\n- \n
- Adding an element:
add(element)— O(1) on average, O(n) when the array is resized. \n - Getting an element by index:
get(index)— O(1). \n - Removing an element:
remove(index)— O(n), as it requires shifting elements. \n
import java.util.ArrayList;\n\npublic class ArrayListExample {\n public static void main(String[] args) {\n ArrayList<Integer> numbers = new ArrayList<>();\n \n numbers.add(10);\n numbers.add(20);\n numbers.add(30);\n \n System.out.println("Element at index 1: " + numbers.get(1)); // 20\n \n numbers.remove(0); // Remove the first element\n System.out.println("Size after removal: " + numbers.size()); // 2\n }\n}\n\n\nWhen to use: When you need fast access by index and you frequently add elements to the end of the list.
\n\n2. Hash Tables: HashMap
\n\nHashMap is a data structure that stores key-value pairs. It uses a hash function for fast lookup. In Java, HashMap is one of the most performant collections for search, insertion, and deletion operations.
How does it work?
\nEach key is converted into a hash code, which determines the "bucket" where the value will be stored. In case of collisions (when different keys produce the same hash), a linked list or a red-black tree is used (since Java 8).
\n\nUsage Example
\n\nimport java.util.HashMap;\n\npublic class HashMapExample {\n public static void main(String[] args) {\n HashMap<String, Integer> studentGrades = new HashMap<>();\n \n studentGrades.put("Alice", 90);\n studentGrades.put("Bob", 85);\n studentGrades.put("Charlie", 92);\n \n // Look up a grade\n int aliceGrade = studentGrades.get("Alice");\n System.out.println("Alice's grade: " + aliceGrade); // 90\n \n // Check if a key exists\n if (studentGrades.containsKey("David")) {\n System.out.println("David is in the list");\n } else {\n System.out.println("David not found");\n }\n \n // Iterate over all entries\n for (String name : studentGrades.keySet()) {\n System.out.println(name + ": " + studentGrades.get(name));\n }\n }\n}\n\n\nOperation complexity: On average O(1) for insertion, lookup, and deletion. In the worst case (with a large number of collisions) — O(n).
\n\n3. Sorting Algorithms in Java
\n\nSorting is one of the basic operations. Java provides built-in methods, but understanding their internal workings is critically important for writing efficient code.
\n\nQuickSort
\n\nThis is one of the fastest sorting algorithms. It works on the "divide and conquer" principle: it selects a pivot element and partitions the array into two parts — elements smaller and larger than the pivot.
\n\npublic class QuickSort {\n public static v