четверг, 14 марта 2024 г.

Collections in Java

 The Collection is a framework that provides an architecture to store and manipulate the group of objects. The java.util package contains all the classes and interfaces for the Collection framework.



Common Methods:

  • add(E element): Adds the specified element to the end of the list.
  • add(int index, E element): Inserts the specified element at the specified position in the list.
  • get(int index): Returns the element at the specified index in the list.
  • remove(int index): Removes the element at the specified index from the list.
  • remove(Object obj): Removes the first occurrence of the specified element from the list.
  • size(): Returns the number of elements in the list.
  • contains(Object obj): Returns true if the list contains the specified element, false otherwise.

List interface is the child interface of Collection interface. It inhibits a list type data structure in which we can store the ordered collection of objects. It can have duplicate values.
List interface is implemented by the classes ArrayList, LinkedList, Vector, and Stack.

ArrayList class uses a dynamic array for storing the elements. It is like an array, but there is no size limit. We can add or remove elements anytime. It inherits the AbstractList class and implements List interfaceThe important points about the Java ArrayList class are:
  • Java ArrayList class can contain duplicate elements.
  • Java ArrayList class maintains insertion order.
  • Java ArrayList class is non synchronized.
  • Java ArrayList allows random access because the array works on an index basis.
  • In ArrayList, manipulation is a little bit slower than the LinkedList in Java because a lot of shifting needs to occur if any element is removed from the array list.
  • We can not create an array list of the primitive types, such as int, float, char, etc. It is required to use the required wrapper class in such cases. 
import java.util.ArrayList;

public class SimpleArrayListExample {
public static void main(String[] args) {
// Creating an ArrayList to store integers
ArrayList<Integer> numbers = new ArrayList<>();

// Adding elements to the ArrayList
numbers.add(10);
numbers.add(20);
numbers.add(30);

// Accessing elements of the ArrayList
System.out.println("Elements of the ArrayList:");
for (int num : numbers) {
System.out.println(num);
}

// Removing an element
numbers.remove(1); // Removing the element at index 1

// Accessing elements after removal
System.out.println("\nElements after removing element at index 1:");
for (int num : numbers) {
System.out.println(num);
}

// Checking the size of the ArrayList
System.out.println("\nSize of the ArrayList: " + numbers.size());

// Checking if an element exists
int searchElement = 10;
if (numbers.contains(searchElement)) {
System.out.println(searchElement + " is present in the ArrayList");
} else {
System.out.println(searchElement + " is not present in the ArrayList");
}
}
}


LinkedList class uses a doubly linked list to store the elements. It provides a linked-list data structure. It inherits the AbstractList class and implements List and Deque interfaces. The important points about Java LinkedList are:

  • LinkedList class can contain duplicate elements.
  • LinkedList class maintains insertion order.
  • LinkedList class is non synchronized.
  • In LinkedList class, manipulation is fast because no shifting needs to occur.
import java.util.LinkedList;

public class SimpleLinkedListExample {
public static void main(String[] args) {
// Creating a LinkedList of integers
LinkedList<Integer> linkedList = new LinkedList<>();

// Adding elements to the LinkedList
linkedList.add(10);
linkedList.add(20);
linkedList.add(30);

// Displaying elements of the LinkedList
System.out.println("Elements of the LinkedList:");
for (int num : linkedList) {
System.out.println(num);
}

// Adding an element at the end of the list
linkedList.addLast(40);
System.out.println("\nAfter adding 40 at the end:");
for (int num : linkedList) {
System.out.println(num);
}

// Removing the first element
linkedList.removeFirst();
System.out.println("\nAfter removing the first element:");
for (int num : linkedList) {
System.out.println(num);
}

// Checking if the list is empty
System.out.println("\nIs the LinkedList empty? " + linkedList.isEmpty());

// Getting the size of the LinkedList
System.out.println("Size of the LinkedList: " + linkedList.size());
}
}


Vector uses a dynamic array to store the data elements. It is similar to ArrayList. However, It is synchronized and contains many methods that are not the part of Collection framework.

import java.util.Vector;

public class VectorExample {
public static void main(String[] args) {
// Creating a Vector to store integers
Vector<Integer> vector = new Vector<>();

// Adding elements to the Vector
vector.add(10);
vector.add(20);
vector.add(30);

// Displaying elements of the Vector
System.out.println("Elements of the Vector:");
for (int num : vector) {
System.out.println(num);
}

// Accessing an element by index
int elementAtIndex1 = vector.get(1);
System.out.println("\nElement at index 1: " + elementAtIndex1);

// Checking if the Vector contains a specific element
int searchElement = 20;
if (vector.contains(searchElement)) {
System.out.println(searchElement + " is present in the Vector");
} else {
System.out.println(searchElement + " is not present in the Vector");
}

// Removing an element
vector.removeElement(20);

// Displaying elements after removal
System.out.println("\nElements after removing 20:");
for (int num : vector) {
System.out.println(num);
}

// Checking the size of the Vector
System.out.println("\nSize of the Vector: " + vector.size());
}
}


Stack is the subclass of Vector. It implements the last-in-first-out data structure, i.e., Stack. The stack contains all of the methods of Vector class and also provides its methods like boolean push(), boolean peek(), boolean push(object o), which defines its properties.

import java.util.Stack;

public class StackExample {
public static void main(String[] args) {
// Creating a stack to store integers
Stack<Integer> stack = new Stack<>();

// Pushing elements onto the stack
stack.push(10);
stack.push(20);
stack.push(30);

// Displaying elements of the stack
System.out.println("Elements of the Stack:");
for (int num : stack) {
System.out.println(num);
}

// Popping an element from the stack
int poppedElement = stack.pop();
System.out.println("\nPopped element: " + poppedElement);

// Displaying elements after popping
System.out.println("\nElements after popping:");
for (int num : stack) {
System.out.println(num);
}

// Peeking at the top element of the stack
int topElement = stack.peek();
System.out.println("\nTop element of the Stack: " + topElement);

// Checking if the stack is empty
System.out.println("Is the Stack empty? " + stack.isEmpty());

// Checking the size of the stack
System.out.println("Size of the Stack: " + stack.size());
}
}

Set Interface is present in java.util package. It extends the Collection interface. It represents the unordered set of elements which doesn't allow us to store the duplicate items. We can store at most one null value in Set. Set is implemented by HashSet, LinkedHashSet, and TreeSet.

HashSet class implements Set Interface. The important points about HashSet class are:
  • HashSet stores the elements by using a mechanism called hashing.
  • HashSet contains unique elements only.
  • HashSet allows null value.
  • HashSet class is non synchronized.
  • HashSet doesn't maintain the insertion order. Here, elements are inserted on the basis of their hashcode.
  • HashSet is the best approach for search operations.
  • The initial default capacity of HashSet is 16, and the load factor is 0.75.

import java.util.HashSet;

public class HashSetExample {
public static void main(String[] args) {
// Creating a HashSet
HashSet<String> namesSet = new HashSet<>();

// Adding elements to the HashSet
namesSet.add("Alice");
namesSet.add("Bob");
namesSet.add("Charlie");
namesSet.add("Alice"); // Adding a duplicate element, which will be ignored

// Displaying the elements of the HashSet
System.out.println("HashSet elements: " + namesSet);

// Checking the size of the HashSet
System.out.println("Size of HashSet: " + namesSet.size());

// Removing an element from the HashSet
namesSet.remove("Bob");

// Displaying the elements of the HashSet after removal
System.out.println("HashSet elements after removal: " + namesSet);

// Checking if a specific element exists in the HashSet
System.out.println("Does HashSet contain 'Charlie'? " + namesSet.contains("Charlie"));

// Iterating through the HashSet
System.out.println("Iterating through HashSet:");
for (String name : namesSet) {
System.out.println(name);
}

// Clearing all elements from the HashSet
namesSet.clear();

// Checking if the HashSet is empty
System.out.println("Is HashSet empty? " + namesSet.isEmpty());
}
}


LinkedHashSet class represents the LinkedList implementation of Set Interface. It extends the HashSet class and implements Set interface. The important points about the LinkedHashSet class are: 
  • LinkedHashSet class contains unique elements only like HashSet.
  • LinkedHashSet class provides all optional set operations and permits null elements.
  • LinkedHashSet class is non-synchronized.
  • LinkedHashSet class maintains insertion order.

import java.util.LinkedHashSet;

public class LinkedHashSetExample {
public static void main(String[] args) {
// Creating a LinkedHashSet
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();

// Adding elements to the LinkedHashSet
linkedHashSet.add("Apple");
linkedHashSet.add("Banana");
linkedHashSet.add("Orange");

// Displaying the elements of the LinkedHashSet
System.out.println("LinkedHashSet elements: " + linkedHashSet);

// Adding a duplicate element, it won't be added to the set
linkedHashSet.add("Apple");

// Displaying the elements of the LinkedHashSet again
System.out.println("LinkedHashSet elements after adding duplicate: " + linkedHashSet);

// Removing an element from the LinkedHashSet
linkedHashSet.remove("Banana");

// Displaying the elements of the LinkedHashSet after removal
System.out.println("LinkedHashSet elements after removal: " + linkedHashSet);

// Checking if a specific element exists in the LinkedHashSet
System.out.println("Does LinkedHashSet contain 'Orange'? " + linkedHashSet.contains("Orange"));

// Iterating through the LinkedHashSet
System.out.println("Iterating through LinkedHashSet:");
for (String element : linkedHashSet) {
System.out.println(element);
}

// Clearing all elements from the LinkedHashSet
linkedHashSet.clear();

// Checking if the LinkedHashSet is empty
System.out.println("Is LinkedHashSet empty? " + linkedHashSet.isEmpty());
}
}


TreeSet class implements the Set interface that uses a tree for storage. It inherits AbstractSet class and implements the NavigableSet interface. The important points about the TreeSet class are:
  • Java TreeSet class contains unique elements only like HashSet.
  • Java TreeSet class access and retrieval times are quiet fast.
  • Java TreeSet class doesn't allow null element.
  • Java TreeSet class is non synchronized.
  • Java TreeSet class maintains ascending order.

import java.util.TreeSet;

public class TreeSetExample {
public static void main(String[] args) {
// Creating a TreeSet
TreeSet<String> treeSet = new TreeSet<>();

// Adding elements to the TreeSet
treeSet.add("Apple");
treeSet.add("Banana");
treeSet.add("Orange");
treeSet.add("Grapes");
treeSet.add("Pineapple");

// Displaying the TreeSet
System.out.println("TreeSet elements: " + treeSet);

// Adding a duplicate element (not added)
treeSet.add("Banana");

// Displaying the TreeSet after adding a duplicate element
System.out.println("TreeSet elements after adding duplicate: " + treeSet);

// Removing an element from the TreeSet
treeSet.remove("Orange");

// Displaying the TreeSet after removing an element
System.out.println("TreeSet elements after removal: " + treeSet);

// Checking if the TreeSet contains a specific element
System.out.println("Is 'Grapes' present in the TreeSet? " + treeSet.contains("Grapes"));

// Getting the first and last elements of the TreeSet
System.out.println("First element: " + treeSet.first());
System.out.println("Last element: " + treeSet.last());

// Getting the size of the TreeSet
System.out.println("Size of the TreeSet: " + treeSet.size());

// Clearing the TreeSet
treeSet.clear();
System.out.println("TreeSet after clearing: " + treeSet);
}
}


Map interface contains values on the basis of key, i.e. key and value pair. Each key and value pair is known as an entry. A Map contains unique keys. A Map is useful if you have to search, update or delete elements on the basis of a key. A Map doesn't allow duplicate keys, but you can have duplicate values. 

HashMap class implements the Map interface which allows us to store key and value pair, where keys should be unique. If you try to insert the duplicate key, it will replace the element of the corresponding key. The important points about the HashMap class are:

  • Java HashMap contains values based on the key.
  • Java HashMap contains only unique keys.
  • Java HashMap may have one null key and multiple null values.
  • Java HashMap is non synchronized.
  • Java HashMap maintains no order.
  • The initial default capacity of HashMap class is 16 with a load factor of 0.75.
import java.util.HashMap;
import java.util.Map;

public class HashMapExample {
public static void main(String[] args) {
// Create a HashMap with String keys and Integer values
HashMap<String, Integer> ageMap = new HashMap<>();

// Add some entries to the HashMap
ageMap.put("Alice", 30);
ageMap.put("Bob", 25);
ageMap.put("Charlie", 35);
ageMap.put("David", 28);

// Accessing elements
System.out.println("Alice's age: " + ageMap.get("Alice"));

// Iterating over entries
System.out.println("Iterating over entries:");
for (Map.Entry<String, Integer> entry : ageMap.entrySet()) {
String name = entry.getKey();
int age = entry.getValue();
System.out.println(name + "'s age is " + age);
}

// Removing an entry
ageMap.remove("Charlie");

// Checking for existence
System.out.println("Is Bob's age present? " + ageMap.containsKey("Bob"));
System.out.println("Is age 35 present? " + ageMap.containsValue(35));

// Size
System.out.println("Number of entries: " + ageMap.size());
}
}


LinkedHashMap class inherits HashMap class and implements the Map interface. The important points about the LinkedHashMap class are:
  • LinkedHashMap contains values based on the key.
  • LinkedHashMap contains unique elements.
  • LinkedHashMap may have one null key and multiple null values.
  • LinkedHashMap is non synchronized.
  • LinkedHashMap maintains insertion order.
  • The initial default capacity of HashMap class is 16 with a load factor of 0.75.

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

public class LinkedHashMapExample {
public static void main(String[] args) {
// Create a LinkedHashMap with String keys and Integer values
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();

// Add some entries to the LinkedHashMap
linkedHashMap.put("Alice", 30);
linkedHashMap.put("Bob", 25);
linkedHashMap.put("Charlie", 35);
linkedHashMap.put("David", 28);

// Accessing elements
System.out.println("Charlie's age: " + linkedHashMap.get("Charlie"));

// Iterating over entries (maintains insertion order)
System.out.println("Iterating over entries:");
for (Map.Entry<String, Integer> entry : linkedHashMap.entrySet()) {
String name = entry.getKey();
int age = entry.getValue();
System.out.println(name + "'s age is " + age);
}

// Size
System.out.println("Number of entries: " + linkedHashMap.size());
}
}


TreeMap class provides an efficient means of storing key-value pairs in sorted order. The important points about TreeMap class are:
  • TreeMap contains values based on the key. It implements the NavigableMap interface and extends AbstractMap class.
  • TreeMap contains only unique elements.
  • TreeMap cannot have a null key but can have multiple null values.
  • TreeMap is non synchronized.
  • TreeMap maintains ascending order.
import java.util.TreeMap;
import java.util.Map;

public class TreeMapExample {
public static void main(String[] args) {
// Create a TreeMap with String keys and Integer values
TreeMap<String, Integer> treeMap = new TreeMap<>();

// Add some entries to the TreeMap
treeMap.put("Alice", 30);
treeMap.put("Bob", 25);
treeMap.put("Charlie", 35);
treeMap.put("David", 28);

// Accessing elements
System.out.println("Charlie's age: " + treeMap.get("Charlie"));

// Iterating over entries (sorted by keys)
System.out.println("Iterating over entries:");
for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
String name = entry.getKey();
int age = entry.getValue();
System.out.println(name + "'s age is " + age);
}

// Size
System.out.println("Number of entries: " + treeMap.size());
}
}


Queue interface maintains the first-in-first-out order. It can be defined as an ordered list that is used to hold the elements which are about to be processed. There are various classes like PriorityQueue, Deque, and ArrayDeque which implements the Queue interface.

PriorityQueue class implements the Queue interface. It holds the elements or objects which are to be processed by their priorities. PriorityQueue doesn't allow null values to be stored in the queue.

import java.util.PriorityQueue;

public class Main {
public static void main(String[] args) {
// Creating a PriorityQueue
PriorityQueue<Integer> pq = new PriorityQueue<>();

// Adding elements to the PriorityQueue
pq.offer(10);
pq.offer(20);
pq.offer(15);

// Printing the PriorityQueue
System.out.println("PriorityQueue: " + pq);

// Removing elements from the PriorityQueue
while (!pq.isEmpty()) {
System.out.println("Removed: " + pq.poll());
}
}
}


Deque interface extends the Queue interface. In Deque, we can remove and add the elements from both the side. Deque stands for a double-ended queue which enables us to perform the operations at both the ends.

ArrayDeque class implements the Deque interface. It facilitates us to use the Deque. Unlike queue, we can add or delete the elements from both the ends. ArrayDeque is faster than ArrayList and Stack and has no capacity restrictions.

import java.util.ArrayDeque;

public class ArrayDequeExample {
public static void main(String[] args) {
// Create an ArrayDeque
ArrayDeque<Integer> deque = new ArrayDeque<>();

// Add elements to the front of the deque
deque.offerFirst(1);
deque.offerFirst(2);
deque.offerFirst(3);

// Add elements to the end of the deque
deque.offerLast(4);
deque.offerLast(5);
deque.offerLast(6);

// Print the deque
System.out.println("Deque: " + deque);

// Remove elements from the front and end of the deque
System.out.println("Removing elements:");
while (!deque.isEmpty()) {
System.out.println("Removed: " + deque.pollFirst() + ", " + deque.pollLast());
}
}
}



We can sort the elements of:

  1. String objects
  2. Wrapper class objects
  3. User-defined class objects

String class and Wrapper classes implement the Comparable interface. So if you store the objects of string or wrapper classes, it will be Comparable.

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

public class SortingExample {
public static void main(String[] args) {
// Create an ArrayList of Strings
ArrayList<String> fruits = new ArrayList<>();
// Add some elements to the ArrayList
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Banana");
fruits.add("Pineapple");
// Print the ArrayList before sorting
System.out.println("Before sorting:");
System.out.println(fruits);
// Sort the ArrayList
Collections.sort(fruits);
// Print the ArrayList after sorting
System.out.println("\nAfter sorting:");
System.out.println(fruits);
}
}


Comparable interface is used to order the objects of the user-defined class. This interface is found in java.lang package and contains only one method named compareTo(Object). It provides a single sorting sequence only, i.e., you can sort the elements on the basis of single data member only.

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

// Define a class representing a Fruit
class Fruit implements Comparable<Fruit> {
private String name;
private int quantity;

// Constructor
public Fruit(String name, int quantity) {
this.name = name;
this.quantity = quantity;
}

// Getter methods
public String getName() {
return name;
}

public int getQuantity() {
return quantity;
}

// Implement the compareTo method of Comparable interface
@Override
public int compareTo(Fruit other) {
// Compare fruits based on their quantity
return Integer.compare(this.quantity, other.quantity);
// Compare fruits based on their quantity in reverse order for descending sorting
//return Integer.compare(other.quantity, this.quantity);
// Compare fruits based on their names
//return this.name.compareTo(other.name);
// Compare fruits based on their names in reverse order for descending sorting
//return other.name.compareTo(this.name);
}

// Override toString method for better representation
@Override
public String toString() {
return "Fruit{" +
"name='" + name + '\'' +
", quantity=" + quantity +
'}';
}
}

public class ComparableExample {
public static void main(String[] args) {
// Create an ArrayList of Fruit objects
ArrayList<Fruit> fruits = new ArrayList<>();
fruits.add(new Fruit("Apple", 10));
fruits.add(new Fruit("Banana", 5));
fruits.add(new Fruit("Orange", 8));

// Before sorting
System.out.println("Before sorting:");
for (Fruit fruit : fruits) {
System.out.println(fruit);
}

// Sort the fruits (natural ordering based on quantity)
Collections.sort(fruits);

// After sorting
System.out.println("\nAfter sorting:");
for (Fruit fruit : fruits) {
System.out.println(fruit);
}
}
}


Comparator interface is used to order the objects of a user-defined class. This interface is found in java.util package. It provides multiple sorting sequences, i.e., you can sort the elements on the basis of any data member.

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

// Define a class representing a Fruit
class Fruit {
private String name;
private int quantity;

// Constructor
public Fruit(String name, int quantity) {
this.name = name;
this.quantity = quantity;
}

// Getter methods
public String getName() {
return name;
}

public int getQuantity() {
return quantity;
}

// Override toString method for better representation
@Override
public String toString() {
return name + " (" + quantity + ")";
}
}

// Define a class to compare Fruits based on quantity
class QuantityComparator implements Comparator<Fruit> {
@Override
public int compare(Fruit fruit1, Fruit fruit2) {
return Integer.compare(fruit1.getQuantity(), fruit2.getQuantity());
}
}

public class ComparatorExample {
public static void main(String[] args) {
// Create an ArrayList of Fruit objects
ArrayList<Fruit> fruits = new ArrayList<>();
fruits.add(new Fruit("Apple", 10));
fruits.add(new Fruit("Banana", 5));
fruits.add(new Fruit("Orange", 8));

// Before sorting
System.out.println("Before sorting:");
for (Fruit fruit : fruits) {
System.out.println(fruit);
}

// Sort the fruits based on quantity
Collections.sort(fruits, new QuantityComparator());

// After sorting
System.out.println("\nAfter sorting based on quantity:");
for (Fruit fruit : fruits) {
System.out.println(fruit);
}
}
}

Комментариев нет:

Отправить комментарий