All Methods in Collection and Map in Java

In Java, Collection and Map are two fundamental interfaces that provide numerous methods for working with data structures like lists, sets, and maps. Below is a detailed explanation of all the methods in each interface.

1. Methods in Collection Interface

The Collection interface is the root interface of the Java collection framework. It defines methods for adding, removing, and querying elements in various collections.

All Methods in Collection Interface

Example: Using Collection Methods


import java.util.ArrayList;
import java.util.Iterator;

public class CollectionExample {
    public static void main(String[] args) {
        ArrayList fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Cherry");

        System.out.println("Size: " + fruits.size()); // Size of the collection
        System.out.println("Contains Banana? " + fruits.contains("Banana")); // Check if "Banana" is in the collection

        // Using iterator to traverse the collection
        Iterator iterator = fruits.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        fruits.remove("Banana"); // Remove "Banana"
        System.out.println("After removal: " + fruits);

        fruits.clear(); // Clear the collection
        System.out.println("Is empty? " + fruits.isEmpty());
    }
}
      

2. Methods in Map Interface

The Map interface represents a collection of key-value pairs, such as a dictionary. The methods of the Map interface provide functionality for adding, removing, and querying key-value pairs in a map.

All Methods in Map Interface

Example: Using Map Methods


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

public class MapExample {
    public static void main(String[] args) {
        Map map = new HashMap<>();
        map.put(1, "Apple");
        map.put(2, "Banana");
        map.put(3, "Cherry");

        System.out.println("Size: " + map.size()); // Size of the map
        System.out.println("Value for key 2: " + map.get(2)); // Get value by key

        // Iterate over the map
        for (Map.Entry entry : map.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

        map.remove(2); // Remove key-value pair for key 2
        System.out.println("After removal: " + map);

        System.out.println("Contains key 3? " + map.containsKey(3)); // Check if key 3 exists
        System.out.println("Contains value Cherry? " + map.containsValue("Cherry")); // Check if value exists
    }
}
      

3. Summary of Collection and Map Methods

Both Collection and Map interfaces provide a variety of methods for performing operations like adding, removing, and querying elements. While Collection is used to represent a single set of objects, Map is designed to store key-value pairs.

Iterating Collection Objects in Java

Java provides various ways to iterate through collection objects, such as Enumeration, Iterator, and ListIterator. Here's how to use them:

1. Using Enumeration

The Enumeration interface is used to iterate legacy collections like Vector and Hashtable.


import java.util.Enumeration;
import java.util.Vector;

public class EnumerationExample {
    public static void main(String[] args) {
        Vector vector = new Vector<>();
        vector.add("Apple");
        vector.add("Banana");
        vector.add("Cherry");

        Enumeration enumeration = vector.elements();
        while (enumeration.hasMoreElements()) {
            System.out.println(enumeration.nextElement());
        }
    }
}
      

2. Using Iterator

The Iterator interface is used to iterate modern collections like ArrayList, HashSet, etc.


import java.util.ArrayList;
import java.util.Iterator;

public class IteratorExample {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("Dog");
        list.add("Cat");
        list.add("Rabbit");

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
      

3. Using ListIterator

The ListIterator interface is used to iterate over List collections like ArrayList, LinkedList. It allows bidirectional traversal.


import java.util.LinkedList;
import java.util.ListIterator;

public class ListIteratorExample {
    public static void main(String[] args) {
        LinkedList list = new LinkedList<>();
        list.add("Red");
        list.add("Green");
        list.add("Blue");

        ListIterator listIterator = list.listIterator();
        System.out.println("Forward Traversal:");
        while (listIterator.hasNext()) {
            System.out.println(listIterator.next());
        }

        System.out.println("Backward Traversal:");
        while (listIterator.hasPrevious()) {
            System.out.println(listIterator.previous());
        }
    }
}
      

Comparison: Enumeration vs Iterator vs ListIterator

Aspect Enumeration Iterator ListIterator
Applicable Collections Legacy collections like Vector, Hashtable. All modern collections in the java.util framework. List-based collections like ArrayList, LinkedList.
Traversal Only forward. Only forward. Bidirectional (forward and backward).
Modification No modification allowed during iteration. Allows element removal during iteration using remove(). Allows addition, removal, and replacement of elements during iteration.
Fail-Fast Behavior Not fail-fast. Fail-fast (throws ConcurrentModificationException). Fail-fast (throws ConcurrentModificationException).

Iterating Map Objects in Java

Maps in Java cannot be directly iterated as they are not part of the Collection interface. However, we can iterate through their keys, values, or key-value pairs.

1. Iterating Using EntrySet


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

public class MapEntrySetExample {
    public static void main(String[] args) {
        Map map = new HashMap<>();
        map.put(1, "One");
        map.put(2, "Two");
        map.put(3, "Three");

        for (Map.Entry entry : map.entrySet()) {
            System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
        }
    }
}
      

2. Iterating Using KeySet


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

public class MapKeySetExample {
    public static void main(String[] args) {
        Map map = new HashMap<>();
        map.put(1, "Apple");
        map.put(2, "Banana");
        map.put(3, "Cherry");

        for (Integer key : map.keySet()) {
            System.out.println("Key: " + key + ", Value: " + map.get(key));
        }
    }
}
      

3. Iterating Using Values


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

public class MapValuesExample {
    public static void main(String[] args) {
        Map map = new HashMap<>();
        map.put(1, "Red");
        map.put(2, "Green");
        map.put(3, "Blue");

        for (String value : map.values()) {
            System.out.println("Value: " + value);
        }
    }
}
      

User-Defined Objects with Collections

In Java, user-defined objects can be used with collections like List, Set, and Map. Below are examples demonstrating how to use them effectively.

1. User-Defined Objects with List

A List can store multiple user-defined objects and maintain the insertion order.


import java.util.ArrayList;

class Student {
    private int rollNo;
    private String name;

    public Student(int rollNo, String name) {
        this.rollNo = rollNo;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{rollNo=" + rollNo + ", name='" + name + "'}";
    }
}

public class ListExample {
    public static void main(String[] args) {
        ArrayList students = new ArrayList<>();
        students.add(new Student(1, "Alice"));
        students.add(new Student(2, "Bob"));
        students.add(new Student(3, "Charlie"));

        for (Student student : students) {
            System.out.println(student);
        }
    }
}
      

2. User-Defined Objects with HashSet and TreeSet

A HashSet is used to store unique objects, and a TreeSet is used for storing unique objects in a sorted order. For TreeSet, the class must implement Comparable or a custom Comparator must be provided.

Example: Using HashSet


import java.util.HashSet;

class Employee {
    private int id;
    private String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + "'}";
    }

    @Override
    public int hashCode() {
        return id;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Employee employee = (Employee) obj;
        return id == employee.id;
    }
}

public class HashSetExample {
    public static void main(String[] args) {
        HashSet employees = new HashSet<>();
        employees.add(new Employee(1, "Alice"));
        employees.add(new Employee(2, "Bob"));
        employees.add(new Employee(1, "Alice")); // Duplicate, won't be added

        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }
}
      

Example: Using TreeSet


import java.util.TreeSet;

class Product implements Comparable {
    private int id;
    private String name;

    public Product(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int compareTo(Product other) {
        return this.id - other.id; // Sorting by ID
    }

    @Override
    public String toString() {
        return "Product{id=" + id + ", name='" + name + "'}";
    }
}

public class TreeSetExample {
    public static void main(String[] args) {
        TreeSet products = new TreeSet<>();
        products.add(new Product(3, "Laptop"));
        products.add(new Product(1, "Phone"));
        products.add(new Product(2, "Tablet"));

        for (Product product : products) {
            System.out.println(product);
        }
    }
}
      

3. User-Defined Objects with HashMap and TreeMap

A HashMap is used to store key-value pairs, while a TreeMap stores key-value pairs in a sorted order based on the keys.

Example: Using HashMap


import java.util.HashMap;

class Department {
    private int id;
    private String name;

    public Department(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Department{id=" + id + ", name='" + name + "'}";
    }
}

public class HashMapExample {
    public static void main(String[] args) {
        HashMap departmentMap = new HashMap<>();
        departmentMap.put(new Department(1, "HR"), "Alice");
        departmentMap.put(new Department(2, "Finance"), "Bob");

        for (var entry : departmentMap.entrySet()) {
            System.out.println("Department: " + entry.getKey() + ", Employee: " + entry.getValue());
        }
    }
}
      

Example: Using TreeMap


import java.util.TreeMap;

class Course implements Comparable {
    private int id;
    private String name;

    public Course(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int compareTo(Course other) {
        return this.id - other.id; // Sorting by ID
    }

    @Override
    public String toString() {
        return "Course{id=" + id + ", name='" + name + "'}";
    }
}

public class TreeMapExample {
    public static void main(String[] args) {
        TreeMap courseMap = new TreeMap<>();
        courseMap.put(new Course(3, "Mathematics"), "Alice");
        courseMap.put(new Course(1, "Physics"), "Bob");
        courseMap.put(new Course(2, "Chemistry"), "Charlie");

        for (var entry : courseMap.entrySet()) {
            System.out.println("Course: " + entry.getKey() + ", Student: " + entry.getValue());
        }
    }
}
      

HashSet Internal Implementation in Java

The HashSet in Java is part of the java.util package and is used to store unique elements. It internally uses a HashMap to achieve this functionality.

1. How HashSet Works Internally

The uniqueness of elements in a HashSet depends on the proper implementation of the hashCode() and equals() methods in the objects being stored.

2. Why Override hashCode() and equals()

If you don't override hashCode() and equals(), the default implementation from the Object class will be used. This may result in incorrect behavior for user-defined objects:

This can lead to duplicate objects being stored in a HashSet, as the hash values and equality checks would not work correctly for content-based comparison.

3. Example: Without Overriding


import java.util.HashSet;

class Employee {
    private int id;
    private String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + "'}";
    }
}

public class WithoutOverrideExample {
    public static void main(String[] args) {
        HashSet employees = new HashSet<>();
        employees.add(new Employee(1, "Alice"));
        employees.add(new Employee(1, "Alice")); // Treated as a different object

        System.out.println("HashSet Contents:");
        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }
}
      

Output: The duplicate object will be added, as the default hashCode() and equals() do not compare content.

4. Example: With Overriding


import java.util.HashSet;

class Employee {
    private int id;
    private String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int hashCode() {
        return id; // Generate hash code based on 'id'
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Employee employee = (Employee) obj;
        return id == employee.id && name.equals(employee.name);
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + "'}";
    }
}

public class WithOverrideExample {
    public static void main(String[] args) {
        HashSet employees = new HashSet<>();
        employees.add(new Employee(1, "Alice"));
        employees.add(new Employee(1, "Alice")); // Treated as duplicate and not added

        System.out.println("HashSet Contents:");
        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }
}
      

Output: The duplicate object will not be added, as the overridden hashCode() and equals() methods ensure proper comparison.

5. Key Points

Comparable vs Comparator in Java

Both Comparable and Comparator are interfaces in Java that allow sorting of objects. They are part of the java.lang and java.util packages respectively.

1. Key Differences

Aspect Comparable Comparator
Definition Defines the natural ordering of objects. Defines custom ordering of objects.
Method compareTo(Object o) - Compares the current object with another object. compare(Object o1, Object o2) - Compares two objects.
Package java.lang java.util
Code Modification Requires modifying the class whose objects need sorting. No modification needed in the class; sorting logic is external.
Sorting Type Used for natural ordering (single sorting logic). Used for custom sorting (multiple sorting logics).
Example Sorting employees by ID. Sorting employees by name or salary.

2. Example: Using Comparable

The Comparable interface is implemented by a class to define its natural ordering.


import java.util.ArrayList;
import java.util.Collections;

class Employee implements Comparable {
    private int id;
    private String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public int compareTo(Employee other) {
        return this.id - other.id; // Natural ordering by ID
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + "'}";
    }
}

public class ComparableExample {
    public static void main(String[] args) {
        ArrayList employees = new ArrayList<>();
        employees.add(new Employee(3, "Alice"));
        employees.add(new Employee(1, "Bob"));
        employees.add(new Employee(2, "Charlie"));

        Collections.sort(employees); // Uses compareTo method
        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }
}
      

3. Example: Using Comparator

The Comparator interface allows sorting using custom logic.

Sorting by Name


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class Employee {
    private int id;
    private String name;

    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + "'}";
    }
}

class NameComparator implements Comparator {
    @Override
    public int compare(Employee e1, Employee e2) {
        return e1.getName().compareTo(e2.getName()); // Custom ordering by name
    }
}

public class ComparatorExample {
    public static void main(String[] args) {
        ArrayList employees = new ArrayList<>();
        employees.add(new Employee(3, "Alice"));
        employees.add(new Employee(1, "Charlie"));
        employees.add(new Employee(2, "Bob"));

        Collections.sort(employees, new NameComparator()); // Uses custom comparator
        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }
}
      

Sorting by Salary


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class Employee {
    private int id;
    private String name;
    private double salary;

    public Employee(int id, String name, double salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }

    @Override
    public String toString() {
        return "Employee{id=" + id + ", name='" + name + "', salary=" + salary + "}";
    }
}

class SalaryComparator implements Comparator {
    @Override
    public int compare(Employee e1, Employee e2) {
        return Double.compare(e1.getSalary(), e2.getSalary()); // Custom ordering by salary
    }
}

public class ComparatorSalaryExample {
    public static void main(String[] args) {
        ArrayList employees = new ArrayList<>();
        employees.add(new Employee(3, "Alice", 50000));
        employees.add(new Employee(1, "Charlie", 70000));
        employees.add(new Employee(2, "Bob", 60000));

        Collections.sort(employees, new SalaryComparator()); // Uses custom comparator
        for (Employee employee : employees) {
            System.out.println(employee);
        }
    }
}
      

4. When to Use

Collections and Arrays Class in Java

In Java, the Collections class and the Arrays class provide utility methods for working with collections and arrays. Here’s an overview of both:

1. Collections Class

The Collections class is a utility class in java.util that provides static methods to operate on or return collections. It includes methods for sorting, searching, reversing, shuffling, and more.

Key Methods of the Collections Class

Example: Using Collections Class


import java.util.ArrayList;
import java.util.Collections;

public class CollectionsExample {
    public static void main(String[] args) {
        ArrayList numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(3);
        numbers.add(8);
        numbers.add(1);

        // Sorting the list
        Collections.sort(numbers);
        System.out.println("Sorted List: " + numbers);

        // Shuffling the list
        Collections.shuffle(numbers);
        System.out.println("Shuffled List: " + numbers);

        // Reversing the list
        Collections.reverse(numbers);
        System.out.println("Reversed List: " + numbers);

        // Finding the maximum element
        System.out.println("Max element: " + Collections.max(numbers));
    }
}
      

2. Arrays Class

The Arrays class, also in java.util, provides static methods for manipulating arrays (such as sorting and searching).

Key Methods of the Arrays Class

Example: Using Arrays Class


import java.util.Arrays;

public class ArraysExample {
    public static void main(String[] args) {
        int[] numbers = {5, 3, 8, 1, 2};

        // Sorting the array
        Arrays.sort(numbers);
        System.out.println("Sorted Array: " + Arrays.toString(numbers));

        // Searching for a value using binary search
        int index = Arrays.binarySearch(numbers, 3);
        System.out.println("Index of 3: " + index);

        // Filling the array with a specific value
        Arrays.fill(numbers, 0);
        System.out.println("Array after fill: " + Arrays.toString(numbers));

        // Comparing two arrays
        int[] anotherArray = {0, 0, 0, 0, 0};
        System.out.println("Arrays are equal: " + Arrays.equals(numbers, anotherArray));
    }
}
      

3. Differences Between Collections Class and Arrays Class

Aspect Collections Class Arrays Class
Purpose Provides utility methods for manipulating collections (e.g., List, Set). Provides utility methods for manipulating arrays.
Applicable Type Works with any collection class that implements java.util.Collection. Works specifically with arrays (primitive or object arrays).
Common Methods sort(), shuffle(), reverse(), max(), min() sort(), binarySearch(), fill(), toString(), equals()
Null Elements Can handle null elements in collections like List and Set. Cannot handle null elements for primitive type arrays.

4. Summary

The Collections class is used for operations on collections like List, Set, and Queue, while the Arrays class is focused on operations related to arrays. The methods provided by both classes help you manipulate and perform operations on data structures effectively.