Skip to main content

Java

A Beginner’s Guide to Java HashSet

Let's dive into a fundamental and incredibly useful part of the Java Collections Framework: the HashSet. If you've ever needed to store a collection of unique items where order doesn't matter, then HashSet is your go-to data structure. Let's explore what it is, how it works, and when to use it. What is a Java HashSet? At its core, a HashSet in Java is an implementation of the Set interface, based on a hash table. This means it inherits the key property of all sets: it cannot contain duplicate elements. When you try to add an element that already exists in the set, the add operation will simply be ignored (it won't throw an error, but the set's state won't change). Think of it like a collection of unique, unordered items. If you put two identical postcards into a box that only allows one copy of each postcard, you'll still only have one postcard in the box. Key Characteristics of HashSet: No Duplicates: As mentioned, HashSet strictly enforces uniqueness. Unordered: There is no guarantee about the iteration order of elements in a HashSet. The order might even change over time due to operations like adding or removing elements. Null Elements: A HashSet can contain one (and only one) null element. Performance: It offers constant time performance (O(1)) for basic operations like add(), remove(), and contains(), assuming the hash function distributes elements properly. In the worst-case scenario (many hash collisions), performance can degrade to O(n). Non-Synchronized: HashSet is not thread-safe. If multiple threads access a hash set concurrently and at least one of the threads modifies the set, it must be synchronized externally.

Mastering TreeSet in Java: A Guide for Developers

Today, we're diving into an essential part of the Java Collections Framework: the TreeSet class. If you've been working with Java for a while, you've likely encountered HashSet for its blazing fast operations or LinkedHashSet for its predictable iteration order. But what if you need a set that not only stores unique elements but also keeps them in a sorted order? Enter TreeSet – your go-to for naturally ordered or custom-ordered sets. Let's explore its functionalities, advantages, and how to effectively use it in your Java applications. What is a Java TreeSet? In Java, a TreeSet is a concrete implementation of the Set interface, which in turn extends the SortedSet and NavigableSet interfaces. This means it provides all the capabilities of a standard Set (no duplicate elements) along with the power of ordering and navigation. Under the hood, TreeSet is backed by a TreeMap. This is a crucial detail, as TreeMap stores its elements in a Red-Black tree structure. This self-balancing binary search tree ensures that operations like adding, removing, and searching elements have a time complexity of O(log n) – making it very efficient for large datasets. Key Characteristics of TreeSet: Stores Unique Elements: Like all Set implementations, TreeSet does not allow duplicate elements. If you try to add an element that already exists, the operation will be ignored, and the set will remain unchanged. Maintains Sorted Order: This is its defining feature. Elements are stored in ascending order by default, either based on their natural ordering or a custom comparator you provide. No Null Elements: TreeSet does not permit null elements. Attempting to add a null will result in a NullPointerException. This is because null cannot be compared with other elements. Non-Synchronized: TreeSet is not thread-safe. If multiple threads access a TreeSet concurrently and at least one thread modifies it, external synchronization must be performed. You can use Collections.synchronizedSortedSet() for this purpose. Performance: Operations like add(), remove(), and contains() have an average time complexity of O(log n).

Java Hashtable: A Dive into Synchronized HashMaps

In the world of Java, when you need to store key-value pairs, HashMap is often your first thought. But what if you need thread-safety—what if multiple threads need to access and modify your map concurrently without corrupting its data? Enter Hashtable. While Hashtable might seem like an older, perhaps less frequently used, sibling to HashMap, it offers a distinct advantage: built-in synchronization. Let's explore Hashtable in detail, understanding its characteristics, how to use it, and when it's the right choice. What is Hashtable? java.util.Hashtable is a concrete implementation of the Map interface in Java. It stores data in key-value pairs and uses a hashing mechanism to efficiently store and retrieve objects. Key characteristics include: Synchronization: All public methods of Hashtable are synchronized. This means that only one thread can access a Hashtable instance at a time, ensuring data consistency in a multi-threaded environment. Nulls Not Allowed: Unlike HashMap, Hashtable does not allow null keys or null values. Attempting to insert a null key or value will result in a NullPointerException. Legacy Class: Hashtable is part of Java's legacy collections framework, dating back to Java 1.0. While functional, newer (and often more performant) synchronized map implementations like ConcurrentHashMap are generally preferred for new development. Initial Capacity and Load Factor: Hashtable uses an initial capacity (default 11) and a load factor (default 0.75). When the number of entries exceeds (capacity * load factor), the Hashtable automatically rehashes and increases its capacity.

Tail vs Non-Tail Recursion in Java: Definitions, Examples, and When It Matters

Quick summary Tail recursion is when a function’s recursive call is the last operation before returning, enabling tail-call elimination in languages/runtimes that support it; non-tail recursion performs additional work after the recursive call returns. In Java, tail-call optimization is not guaranteed by the JVM, so tail recursion does not reduce stack usage unless transformed to iterative code; still, converting non-tail recursion to tail style can make iterative conversion straightforward and avoid stack overflow in production. What is recursion? Recursion is a divide-and-conquer technique where a function calls itself with smaller inputs until a base case is reached, with the JVM allocating a stack frame for each invocation; deep recursion risks StackOverflowError if not controlled. Each call must eventually reduce the problem and hit a base case to terminate safely and predictably.

Java DelayQueue — A Specialized BlockingQueue for Delayed Elements

In concurrent programming, often you need to schedule work or tasks to happen after a delay: e.g. timeouts, scheduled retries, delayed tasks, rate limiting, delayed processing, etc. Java’s java.util.concurrent package provides a handy queue for such use cases — DelayQueue — which accepts elements that become available only after a specified delay. In this post, we will explore: What is a DelayQueue The Delayed interface How DelayQueue works internally Key methods and behaviors A simple producer/consumer example Real-world use cases & caveats Summary 1. What is DelayQueue DelayQueue<E extends Delayed> is an unbounded blocking queue whose elements must implement the Delayed interface. An element can be retrieved (via take() or poll(...)) only when its delay has expired. Until then, it stays “dormant” inside the queue. Some important characteristics: The head of the queue is the delayed element whose expiration (delay) is earliest (i.e. whose delay will expire first). If no element has expired yet, poll() returns null, and take() blocks until an element becomes available. The queue is unbounded — operations like put() or offer() never block (unless out of memory). The queue uses internal locking (ReentrantLock) for thread safety. Iterators over the queue are weakly consistent and do not guarantee ordered traversal. In short: DelayQueue is like a priority queue (ordered by expiration time) combined with blocking/waiting semantics.

Java BitSet Explained (with Practical Examples)

When developing applications, there are situations where we need to represent and manipulate large collections of binary values – typically true or false. Storing these values in a conventional data structure like a boolean[] or a HashSet<Integer> can be inefficient in terms of memory and speed. Java provides the BitSet class in the java.util package to address this problem. BitSet represents a sequence of bits that can grow dynamically and provides built-in methods for bit-level manipulation. In this article, we will cover: Introduction to BitSet Internal representation and advantages Common operations Basic usage example Real-world example: Attendance tracking Bitwise operations (AND, OR, XOR, ANDNOT) Performance comparison with boolean[] and HashSet Conclusion

Apache Commons Collection – MultiValuedMap

Apache Commons Collections MultiValuedMap compared against Guava Multimap and a vanilla nested Map of Lists, with a realistic form-validation-errors use case, annotated code, sample output, and FAQs.

Spring Cloud: Getting started with Hystrix Dashboard

⚠️ This tutorial is outdated. Hystrix Dashboard was removed from Spring Cloud and does not work with Spring Boot 3.x. The modern approach is Resilience4j metrics with Prometheus & Grafana — see the Spring Cloud Netflix migration guide. This post remains online for teams maintaining legacy systems. This is a quick tutorial on Hystrix dashboard. Hystrix dashboard allows you to view the overall status of your Spring cloud application at a single glance. It provides access to vital metrics of your application and gives you a graphical representation of those for better understanding. This post is the continuation of Spring Cloud: Adding Hystrix Circuit Breaker and Spring Cloud: Playing with Hystrix Circuit Breaker. Please go through those post, if you haven't. Those posts explain about Hystrix circuit breaker. TL;DR You can download whole project by clicking following link. Spring Cloud (V2.3.1) Hystrix DashboardDownload

Spring Cloud Config Server on Spring Boot 3.x: Git Mode, Native Mode, and Runtime Refresh

Spring Cloud Config is, alongside Eureka, one of the two survivors of the original Spring Cloud stack — still maintained, still the standard answer for centralized configuration outside Kubernetes. This post is a complete rewrite of my 2020 Config Server tutorials for Spring Boot 3.x: a Config Server backed by Git (with native/filesystem mode for local development), clients using the modern spring.config.import mechanism instead of the long-gone bootstrap.properties, and runtime refresh that actually works.