# Hashtable in Java

**1\. Introduction to Hashtable**

`Hashtable` is a legacy Java class that implements the `Map` interface. It stores data as **key-value pairs** and is synchronized, making its individual operations thread-safe.

### Syntax

```java
Hashtable<KeyType, ValueType> table = new Hashtable<>();
```

### Example

```java
import java.util.Hashtable;

public class Main {
    public static void main(String[] args) {
        Hashtable<Integer, String> students = new Hashtable<>();

        students.put(1, "Mani");
        students.put(2, "Arun");
        students.put(3, "Priya");

        System.out.println(students);
    }
}
```

The output contains all three key-value pairs. The order is not guaranteed.

**2\. Creating a Hashtable**

```java
Hashtable<String, Integer> scores = new Hashtable<>();
```

Creates an empty Hashtable.

**3\. Adding Elements Using put()**

The `put()` method adds or updates a key-value pair.

```java
Hashtable<Integer, String> students = new Hashtable<>();

students.put(1, "Mani");
students.put(2, "Arun");
students.put(1, "Priya");

System.out.println(students.get(1)); // Priya
```

**4\. Accessing Values Using get()**

Returns the value associated with a key.

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");

System.out.println(students.get(1)); // Mani
```

**5\. Checking Keys Using containsKey()**

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");

System.out.println(students.containsKey(1)); // true
```

Checks whether a key exists.

**6\. Checking Values Using containsValue()**

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");

System.out.println(students.containsValue("Mani")); // true
```

Checks whether a value exists.

**7\. Removing Elements Using remove()**

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");
students.put(2, "Arun");

students.remove(1);

System.out.println(students.containsKey(1)); // false
```

Removes the entry associated with the specified key.

**8\. Updating Values Using replace()**

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");

students.replace(1, "Arun");

System.out.println(students.get(1)); // Arun
```

Updates the value when the key exists.

**9\. Finding the Size Using size()**

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");
students.put(2, "Arun");

System.out.println(students.size()); // 2
```

Returns the number of key-value pairs.

**10\. Checking Whether a Hashtable Is Empty**

```java
Hashtable<String, Integer> scores = new Hashtable<>();

System.out.println(scores.isEmpty()); // true
```

The `isEmpty()` method checks whether the table contains entries.

**11\. Removing All Entries Using clear()**

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");

students.clear();

System.out.println(students.size()); // 0
```

Removes all key-value pairs.

**12\. Iterating Through a Hashtable**

Use `entrySet()` to access keys and values.

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");
students.put(2, "Arun");

for (var entry : students.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}
```

The iteration order is not guaranteed.

**13\. Getting All Keys and Values**

```java
Hashtable<Integer, String> students = new Hashtable<>();
students.put(1, "Mani");
students.put(2, "Arun");

System.out.println(students.keySet());
System.out.println(students.values());
```

- `keySet()` returns the keys.
- `values()` returns the values.

**14\. Handling Duplicate Keys and Values**

Keys must be unique, but values can be duplicated.

```java
Hashtable<Integer, String> students = new Hashtable<>();

students.put(1, "Mani");
students.put(1, "Arun");
students.put(2, "Arun");

System.out.println(students.size()); // 2
System.out.println(students.get(1)); // Arun
```

Adding an existing key replaces its previous value.

**15\. Does Hashtable Allow Null Keys and Values?**

No. Hashtable does not allow `null` keys or `null` values. Attempting to add either throws a `NullPointerException`.

```java
Hashtable<String, String> map = new Hashtable<>();

map.put("language", "Java");
// map.put(null, "Java"); // NullPointerException
// map.put("language", null); // NullPointerException
```

**16\. Setting a Default Value Using getOrDefault()**

```java
Hashtable<String, Integer> scores = new Hashtable<>();
scores.put("Mani", 90);

System.out.println(scores.getOrDefault("Arun", 0)); // 0
```

Returns the default value if the key is absent.

**17\. Adding Entries Using putIfAbsent()**

```java
Hashtable<Integer, String> students = new Hashtable<>();

students.put(1, "Mani");
students.putIfAbsent(1, "Arun");
students.putIfAbsent(2, "Priya");

System.out.println(students.get(1)); // Mani
```

Adds the mapping only if the key is absent.

**18\. Hashtable vs HashMap vs ConcurrentHashMap**

| Feature | Hashtable | HashMap | ConcurrentHashMap |
| --- | --- | --- | --- |
| Thread safety | Synchronized methods | Not synchronized | Designed for concurrent access |
| Null keys/values | Not allowed | One null key; null values allowed | Not allowed |
| Order | Not guaranteed | Not guaranteed | Not guaranteed |
| Performance | Often lower under contention | Good for non-concurrent use | Usually better for concurrent access |

**19\. Important Hashtable Methods**

| Method | Purpose |
| --- | --- |
| `put()` | Adds or updates an entry |
| `get()` | Retrieves a value |
| `containsKey()` | Checks a key |
| `containsValue()` | Checks a value |
| `remove()` | Removes an entry |
| `replace()` | Updates a value |
| `getOrDefault()` | Returns a value or default |
| `putIfAbsent()` | Adds if the key is absent |
| `keySet()` | Returns keys |
| `values()` | Returns values |
| `entrySet()` | Returns entries |
| `size()` | Returns the number of entries |
| `isEmpty()` | Checks whether empty |
| `clear()` | Removes all entries |

**20\. Time Complexity of Hashtable**

| Operation | Average Time Complexity |
| --- | --- |
| `put()` | O(1) |
| `get()` | O(1) |
| `remove()` | O(1) |
| `containsKey()` | O(1) |
| `containsValue()` | O(n) |
| Iteration | O(n) |

*Note: Hash collisions can affect performance.*

**Conclusion**

`Hashtable` is a legacy Java collection that stores key-value pairs and synchronizes its individual operations.

Key points:

- Keys are unique; values can be duplicated.
- Null keys and values are not allowed.
- Iteration order is not guaranteed.
- Individual methods are synchronized, but multi-step operations may still require external synchronization.
- For modern concurrent applications, `ConcurrentHashMap` is generally preferred.

**Audience Engagement:** Have you used `Hashtable`, `HashMap`, or \`ConcurrentHashMap in a Java project? Which would you choose for a multithreaded application, and why?
