💻Step 21: Collection Frameworks -14th+15th hour + code

Learn with youtube video-

💡Collection-Dynamic data structure to store and manipulating group of elements.

💡Collections Framework-It’s a architecture for representing and manipulating collections.

In java, collection framework includes 2 things-

-(A)interfaces
-(B)implemented classes

💡Collections Hierarchy –

Important :

💡– fail-fast-

When we iterate through the collection, it throws exception if any change occurs in internal structure of collection. for example- Hashmap

💡– fail-safe-

It uses a copy of internal structure of collection, so changes are performed on this internal structure, rather than original collection. Doesn’t throw any exception. for example- Concurrent Hashmap

💡– Hashing

In Java, a hash is a function that converts an input (also called a key) into a fixed-size numeric value (the hash code). The resulting hash code can then be used to store or retrieve the original data more efficiently.

Every Java object has a hashCode() method that returns an integer value representing the object’s hash code. This method is defined in the Object class, which is the parent class of all Java objects. For example:

String s = “Hello”;
int hash = s.hashCode(); // Generates a hash code for “Hello”

💡 1- Equals and hashCode contract in Java

An equals method in Java must follow its contract with hashcode method in Java as stated below.

1) If two objects are equal by equals() method then there hashcode must be same.

2) If two objects are not equal by equals() method then there hashcode could be same or different.

2-When Overriding hashcode method in any class-

It is important to note that the hashCode() method should be implemented in a way that returns the same hash code for two objects that are considered equal so equals() method should return true for these two objects.

3-Role of hashcode to store/fetech data in collections-

For example, consider a HashTable(legacy/old class) with a size of 10. If the hash code of a key is 35, the bucket index will be calculated as follows:

bucketIndex = 35 % 10 = 5

This means that the key-value pair will be stored in the 5th bucket of the HashTable.

Note – HashTable is used in HashSet/HashMap so it’s important to understand how data is stored/fetched with hashtable.

💡Interfaces In collections Framework-

💡Iterable Interface –

💡Collection Interface –

Here is a table that compares the Iterable and Collection interfaces in Java:

DifferencesIterableCollection
Packagejava.langjava.util
SuperinterfaceIterable
SubinterfacesList, Set, QueueList, Set, Queue, Deque
Main methodsiterator()size(), isEmpty(), add(), remove(), contains(), iterator(), toArray()
Additional methodsaddAll(), containsAll(), removeAll(), retainAll(), clear(), equals(), hashCode(), toString()
  • Iterable is a root interface in the collection hierarchy. It provides a single method, iterator(), which returns an iterator for the collection.
  • Collection is a subinterface of Iterable. It extends Iterable by adding methods for adding, removing, and checking for the presence of elements, as well as methods for modifying the structure of the collection.

Note that both Iterable and Collection are interfaces, not classes. Therefore, they cannot be instantiated directly. Instead, you can use one of the classes that implements these interfaces, such as ArrayList or HashSet.

💡Ordered:
When a collection is ordered, it means you can iterate through the collection in a specific (not-random) order

💡Sorted:
A sorted collection means that the order of objects in the collection is determined according to some rule or rules, known as the sorting order.

💡List interface vs set interface vs queue interface vs map interface in java –

Here is a tabular comparison of the List, Set, Queue, and Map interfaces in Java:

InterfaceDescription
ListA list is an ordered collection of elements that can contain duplicates. It provides access to elements by their position in the list, and allows for insertion and deletion at any position. Examples of classes that implement the List interface include ArrayList and LinkedList.
SetA set is a collection of elements that does not allow duplicates. It does not provide access to elements by their position, and does not allow for insertion or deletion at specific positions. Examples of classes that implement the Set interface include HashSet and TreeSet.
QueueA queue is a collection of elements that are added to one end and removed from the other. It follows the “first-in, first-out” (FIFO) principle. Examples of classes that implement the Queue interface include LinkedList and ArrayDeque.
MapA map is a collection of key-value pairs. It provides access to values by their associated keys, and allows for the insertion and deletion of key-value pairs. Examples of classes that implement the Map interface include HashMap and TreeMap.

In summary, the List interface is used for collections of elements that are ordered and can contain duplicates, the Set interface is used for collections of elements that do not allow duplicates, the Queue interface is used for collections of elements that are ordered according to the FIFO principle, and the Map interface is used for collections of key-value pairs.

💡Implemented Classes-

💡Classes that inherit List Interface –

💡ArrayList vs Vector vs LinkedList vs Stack

Here is a summary of the main differences between ArrayList, Vector, LinkedList, and Stack:

ArrayListVectorLinkedListStack
ImplementationArrayArrayLinked listVector
ResizableYesYesNoNo
Thread safetyNoYesNoYes
Iteration speedFastFastSlowFast
Random access speedFastFastSlowFast
Insertion/deletionFastSlowFastSlow
  • 💡ArrayList: This class uses an array as the underlying data structure to store the elements. It provides fast access to the elements using an index, but it is slower to add or remove elements from the middle of the list because it requires shifting the elements to make room for the new element or fill the gap left by the removed element.
  • 💡Vector: This class is similar to ArrayList, but it is synchronized, which means that multiple threads can access it safely. This makes it suitable for use in multi-threaded environments, but it can be slower than ArrayList because of the overhead of synchronization.
  • 💡LinkedList: This class uses a linked list as the underlying data structure to store the elements. It is slower to access elements using an index than ArrayList or Vector, but it is faster to add or remove elements from the middle of the list because it does not require shifting the elements.
  • 💡Stack: This class extends Vector and provides a last-in, first-out (LIFO) data structure, which means that the element that is added last to the stack is the first one to be removed. It provides push and pop operations to add and remove elements, respectively.

💡1- ArrayList

import java.util.ArrayList;

public class Main {
  public static void main(String[] args) {
    // Create an ArrayList of Strings
    ArrayList<String> list = new ArrayList<>();
  
    // Add elements to the ArrayList
    list.add("apple");
    list.add("banana");
    list.add("cherry");
  
    // Print the ArrayList
    System.out.println(list);  // Output: [apple, banana, cherry]
  
    // Access an element in the ArrayList
    String element = list.get(1);  // element will be "banana"
  
    // Modify an element in the ArrayList
    list.set(1, "orange");  // list will be ["apple", "orange", "cherry"]
  
    // Remove an element from the ArrayList
    list.remove(1);  // list will be ["apple", "cherry"]
  }
}

💡2- LinkedList

For example:

import java.util.LinkedList;

public class Main {
  public static void main(String[] args) {
    // Create a new linked list
    LinkedList<String> list = new LinkedList<>();

    // Add some elements to the list
    list.add("apple");
    list.add("banana");
    list.add("cherry");

    // Insert a new element at the beginning of the list
    list.addFirst("lemon");

    // Insert a new element at the end of the list
    list.addLast("orange");

    // Insert a new element after the first element
    list.add(1, "grape");

    // Remove the first element from the list
    list.removeFirst();

    // Remove the last element from the list
    list.removeLast();

    // Iterate through the list and print each element
    for (String fruit : list) {
      System.out.println(fruit);
    }
  }
}

If you wanted to use an array list instead of a linked list, you could use the ArrayList class in place of LinkedList, and use the add, addAll, remove, and set methods to modify the list. However, you wouldn’t be able to use the addFirst, addLast, removeFirst, or removeLast methods, since these are specific to linked lists.

💡3- Vector

Note that the Vector class is a legacy class and is not recommended for use in new code.

Here is an example of how to use a Vector in Java:

import java.util.Vector;

public class VectorExample {
  public static void main(String[] args) {
    // Create a Vector with initial capacity of 3
    Vector<String> vector = new Vector<>(3);

    // Add elements to the Vector
    vector.add("Apple");
    vector.add("Banana");
    vector.add("Orange");

    // Print the Vector
    System.out.println(vector);  // Output: [Apple, Banana, Orange]

    // Add more elements to the Vector
    vector.add("Mango");
    vector.add("Pineapple");

    // Print the Vector again
    System.out.println(vector);  // Output: [Apple, Banana, Orange, Mango, Pineapple]

    // Get the size of the Vector
    int size = vector.size();
    System.out.println("Size of Vector: " + size);  // Output: "Size of Vector: 5"

    // Get the element at index 2
    String element = vector.get(2);
    System.out.println("Element at index 2: " + element);  // Output: "Element at index 2: Orange"

    // Remove the element at index 2
    vector.remove(2);

    // Print the Vector again
    System.out.println(vector);  // Output: [Apple, Banana, Mango, Pineapple]
  }
}

💡4- Stack – It is generally recommended to use the Deque interface and its implementing classes, such as ArrayDeque, instead of the Stack class for new code.

Here is an example of how to use a Stack in Java:

import java.util.Stack;

public class StackExample {
  public static void main(String[] args) {
    // Create a Stack
    Stack<String> stack = new Stack<>();

    // Push elements onto the Stack
    stack.push("Apple");
    stack.push("Banana");
    stack.push("Orange");

    // Print the Stack
    System.out.println(stack);  // Output: [Apple, Banana, Orange]

    // Pop an element from the Stack
    String element = stack.pop();
    System.out.println("Popped element: " + element);  // Output: "Popped element: Orange"

    // Print the Stack again
    System.out.println(stack);  // Output: [Apple, Banana]

    // Peek at the top element of the Stack
    element = stack.peek();
    System.out.println("Top element: " + element);  // Output: "Top element: Banana"

    // Print the Stack again
    System.out.println(stack);  // Output: [Apple, Banana]

    // Search for an element in the Stack
    int index = stack.search("Apple");
    System.out.println("Index of element: " + index);  // Output: "Index of element: 2"
  }
}

💡Classes that inherit Set Interface –

💡Hashset vs Linkedhashset vs Treeset

Here is a comparison of the Java HashSet, LinkedHashSet, and TreeSet classes:

HashSetLinkedHashSetTreeSet
Underlying DataHash tableHash table + linkedBalanced tree
OrderUnorderedInsertion orderSorted (natural order)
Null values allowed?NoYesNo
Thread-safe?No (unsynchronized)No (unsynchronized)No (unsynchronized)

💡In Java, a HashSet is a class that extends the AbstractSet class and implements the Set interface. It creates a collection that uses a hash table for storage and does not allow duplicate elements. It does not maintain the insertion order of elements, meaning the order in which elements are added to a HashSet is not reflected in the set’s iteration order.

💡A LinkedHashSet is a class that extends HashSet and implements the Set interface. It is similar to a HashSet, but it maintains a doubly-linked list running through all of its elements. This linked list defines the iteration order of the elements in the set, which is the order in which they were inserted.

💡A TreeSet is a class that extends AbstractSet and implements the NavigableSet interface. It creates a collection that uses a tree for storage and is sorted according to the natural ordering of its elements or according to a Comparator provided at the time of creation.

In summary, a HashSet is a collection that stores elements in a hash table and does not maintain the insertion order of elements, a LinkedHashSet is a collection that stores elements in a hash table and maintains the insertion order of elements, and a TreeSet is a collection that stores elements in a tree and is sorted according to the natural ordering of its elements or a provided Comparator.

💡1- HashSet

Here is an example of how to create and use a HashSet in Java:

import java.util.HashSet;

public class Main {
  public static void main(String[] args) {
    // Create a HashSet of strings
    HashSet<String> set = new HashSet<>();

    // Add some elements to the set
    set.add("apple");
    set.add("banana");
    set.add("cherry");

    // Check if the set contains a specific element
    if (set.contains("banana")) {
      System.out.println("The set contains banana.");
    } else {
      System.out.println("The set does not contain banana.");
    }

    // Remove an element from the set
    set.remove("cherry");

    // Print the elements of the set
    for (String element : set) {
      System.out.println(element);
    }
  }
}

This code would output the following:

The set contains banana.
apple
banana

💡2- LinkedHashSet – Here is an example of how to create and use a LinkedHashSet in Java:

import java.util.LinkedHashSet;

public class Main {
  public static void main(String[] args) {
    // Create a LinkedHashSet
    LinkedHashSet<String> set = new LinkedHashSet<>();

    // Add elements to the set
    set.add("Apple");
    set.add("Banana");
    set.add("Orange");

    // Iterate through the set and print out the elements
    for (String fruit : set) {
      System.out.println(fruit);
    }
  }
}

Output:

Apple
Banana
Orange

Note that a LinkedHashSet does not allow duplicate elements, and it maintains the order in which the elements were added to the set. It also provides constant-time performance for the basic operations of adding, removing, and checking if an element is contained in the set.

💡 SortedSet Interface

In the Java programming language, the SortedSet interface is a subinterface of the Set interface that provides additional methods for working with sorted sets. A sorted set is a collection that maintains its elements in ascending order, according to the natural ordering of its elements or according to a Comparator provided at set creation time.

💡3- TreeSet class– Here is an example of how you can create a TreeSet and add some elements to it:

import java.util.TreeSet;

public class Main {
  public static void main(String[] args) {
    // Create a TreeSet and add some elements to it
    TreeSet<Integer> set = new TreeSet<>();
    set.add(5);
    set.add(2);
    set.add(10);
    set.add(1);

    // Print the elements of the set
    for (Integer element : set) {
      System.out.println(element);
    }
  }
}

This code will output the elements 1, 2, 5, and 10, in that order.

TreeSet is a good choice when you need a sorted set with fast lookup and insertion performance. It is implemented using a balanced tree data structure, which gives it a good balance between performance and memory usage.

💡Classes that inherit Queue Interface –

💡PriorityQueue vs ArrayDeque

Here is a comparison of the Java PriorityQueue and ArrayDeque classes:

PriorityQueueArrayDeque
Underlying DataHeapResizable array
OrderAccording to comparatorInsertion order
Null values allowed?NoYes
Thread-safe?No (unsynchronized)No (unsynchronized)
Queue or double-ended queue?QueueDouble-ended queue

In Java, a PriorityQueue is a class that extends the AbstractQueue class and implements the Queue interface. It creates a queue that orders its elements based on their natural ordering or based on a Comparator provided at the time of creation. The head of the queue is the element with the highest priority, and elements are removed from the queue in priority order. A PriorityQueue does not allow null elements.

An ArrayDeque (double-ended queue) is a class that extends the AbstractCollection class and implements the Deque interface. It creates a resizable array, which is used to store elements. An ArrayDeque can be used as a stack (last-in, first-out) or a queue (first-in, first-out). It does not have a fixed capacity and can grow or shrink as needed. An ArrayDeque allows null elements.

In summary, a PriorityQueue is a queue that orders its elements based on their natural ordering or a provided Comparator, and an ArrayDeque is a resizable array that can be used as a stack or a queue and allows null elements.

💡1- Priority Queue – Here is an example of how to create and use a PriorityQueue in Java:

import java.util.PriorityQueue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        // Create a priority queue
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        // Add elements to the priority queue
        pq.add(10);
        pq.add(20);
        pq.add(15);

        // Print the head of the queue
        System.out.println("Head of the queue: " + pq.peek()); // prints 10

        // Remove the head of the queue
        pq.poll();

        // Print the new head of the queue
        System.out.println("New head of the queue: " + pq.peek()); // prints 15
    }
}

💡 Deque Interface

In Java, a deque (double-ended queue) is a linear collection that supports element insertion and removal at both ends. The Deque interface, which extends the Queue interface, defines the methods that a deque implementation should support.

💡2- ArrayDeque class – Here is an example of how you can use ArrayDeque in Java:

import java.util.ArrayDeque;

public class Main {
  public static void main(String[] args) {
    // Create an ArrayDeque with a capacity of 10
    ArrayDeque<Integer> deque = new ArrayDeque<>(10);

    // Add elements to the deque
    deque.addFirst(1);
    deque.addLast(2);
    deque.addFirst(3);
    deque.addLast(4);

    // Remove elements from the deque
    int first = deque.removeFirst();
    int last = deque.removeLast();

    // Print the deque
    System.out.println(deque); // Output: [3, 1]

    // Check if the deque is empty
    System.out.println(deque.isEmpty()); // Output: false

    // Get the size of the deque
    System.out.println(deque.size()); // Output: 2
  }
}

💡Misc- 💡– Hashtable

It’s similar to synchronizedHashmap, but it just legacy class.

💡Classes that inherit Map Interface –

💡HashMap vs LinkedHashMap vs Treemap vs WeakHashMap

In Java, the HashMap, LinkedHashMap, TreeMap, and WeakHashMap classes are all implementations of the Map interface, which maps keys to values. Each implementation differs in the way it stores and retrieves the keys and values, and in the performance characteristics it offers.

Here is a summary of the main differences between these four map implementations:

💡HashMap-

HashMap is a general-purpose map implementation that uses a hash table to store the keys and values. It is fast for most operations, including getting and putting values, and it does not maintain the order of the elements. HashMap is not synchronized, which means that it is not thread-safe. To make a HashMap thread-safe, you can use the Collections.synchronizedMap method to wrap it in a thread-safe map.

💡LinkedHashMap-

LinkedHashMap is a map implementation that maintains the insertion order of the elements. It is similar to HashMap, but it uses a linked list to store the keys and values, which allows it to maintain the insertion order. LinkedHashMap is not synchronized, so you may need to synchronize it if you are using it in a multi-threaded environment.

💡TreeMap-

TreeMap is a map implementation that maintains the keys in ascending order, according to their natural ordering or according to a Comparator provided at the time of creation. It uses a red-black tree to store the keys and values, which ensures that the keys are always in order. TreeMap is not synchronized, so you may need to synchronize it if you are using it in a multi-threaded environment.

💡WeakHashMap-

WeakHashMap is a map implementation that stores keys as weak references. This means that the keys in a WeakHashMap can be garbage collected if there are no other strong references to the keys. WeakHashMap is useful for creating caches that automatically remove entries when they are no longer needed. WeakHashMap is not synchronized, so you may need to synchronize it if you are using it in a multi-threaded environment.

In general, you should choose the map implementation that best fits your needs based on the performance characteristics and features you require. HashMap is a good choice for most purposes, but if you need to maintain the insertion order of the elements or the keys must be ordered in a particular way, you may want to use LinkedHashMap or TreeMap instead. If you need a map that automatically removes entries when they are no longer needed, you may want to use WeakHashMap.

Here is a summary of the differences between these four map implementations:

HashMapLinkedHashMapTreeMapWeakHashMap
OrderingUnorderedInsertion-orderSortedUnordered
Null keysYesYesNoYes
Null valuesYesYesYesYes
Automatic removal of stale entriesNoYes NoYes

💡10 – HashMap

import java.util.HashMap;

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

    // Add some key-value pairs to the map
    map.put("Apple", 10);
    map.put("Banana", 20);
    map.put("Carrot", 30);

    // Look up a value using a key
    int value = map.get("Banana");  // value will be 20
    
    // Check if the map contains a particular key
    boolean hasKey = map.containsKey("Apple");  // hasKey will be true
    
    // Remove a key-value pair from the map
    map.remove("Carrot");
  }
}

In this example, we create a HashMap object that maps String keys to Integer values. We add three key-value pairs to the map, then look up the value for the key “Banana” and check if the map contains the key “Apple”. Finally, we remove the key-value pair for the key “Carrot”.

💡11 – LinkedHashMap

import java.util.LinkedHashMap;

public class Main {
  public static void main(String[] args) {
    // Create a LinkedHashMap
    LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
  
    // Add key-value pairs to the map
    map.put("Apple", 1);
    map.put("Banana", 2);
    map.put("Cherry", 3);
  
    // Print the map
    System.out.println(map);  // {Apple=1, Banana=2, Cherry=3}
  
    // Get the value for a key
    int value = map.get("Banana");
    System.out.println(value);  // 2
  
    // Remove a key-value pair
    map.remove("Cherry");
  
    // Check if the map contains a key
    boolean containsKey = map.containsKey("Apple");
    System.out.println(containsKey);  // true
  }
}

💡 SortedMap Interface

In Java, the SortedMap interface is a subinterface of the Map interface that provides a total ordering on its keys. The SortedMap interface is implemented by several classes, including TreeMap, ConcurrentSkipListMap, and ConcurrentNavigableMap.

💡12 – TreeMap – Here is an example of how to create and use a treemap in Java:

import java.util.TreeMap;

public class Main {
  public static void main(String[] args) {
    // Create a treemap
    TreeMap<String, Integer> map = new TreeMap<>();
    
    // Add some elements to the treemap
    map.put("apple", 10);
    map.put("banana", 20);
    map.put("cherry", 30);
    
    // Print the treemap
    System.out.println(map);  // Output: {apple=10, banana=20, cherry=30}
    
    // Get the value for a key
    int value = map.get("banana");
    System.out.println(value);  // Output: 20
    
    // Remove an element from the treemap
    map.remove("cherry");
    
    // Check if the treemap contains a key
    boolean containsKey = map.containsKey("Apple");
    System.out.println(containsKey);  // true
  }
}


In this example, we create a treemap called map and add three elements to it: an “apple” with a value of 10, a “banana” with a value of 20, and a “cherry” with a value of 30. We then print the treemap, get the value for the “banana” key, remove the “cherry” element, and check if the treemap contains the “apple” key.

💡13 – WeakHashMap- Here is an example of how to use a WeakHashMap:

import java.util.Map;
import java.util.WeakHashMap;

public class WeakHashMapExample {
  public static void main(String[] args) {
    // Create a WeakHashMap
    Map<Object, String> map = new WeakHashMap<>();
  
    // Put some key-value pairs in the map
    Object key1 = new Object();
    Object key2 = new Object();
    map.put(key1, "value1");
    map.put(key2, "value2");
  
    // Remove all strong references to the keys
    key1 = null;
    key2 = null;
  
    // Force garbage collection
    System.gc();
  
    // The keys in the WeakHashMap are now eligible for garbage collection,
    // so the map will only contain one entry (assuming that the garbage
    // collection actually occurred)
    System.out.println(map.size());  // Outputs 1
  }
}

💡Other Useful Classes –

💡SynchronizedHasmap

Entire hashmap in synchronized.
Every read and write aquires lock, hence decrease the performance.

💡ConcurrentHashmap

It’s thread Safe hashmap.
– All read without lock and write with lock, so gives better performance in more reader, less writer scenario.
– Lock is applied on portion of hashmap-buckets, which is called segments.
– by default, there are 16 segments and 16 threads.
– it’s a fail-safe.

Here is a comparison of the Java SynchronizedMap, ConcurrentHashMap, HashMap, and Hashtable classes:

SynchronizedMapConcurrentHashMapHashMapHashtable
Underlying DataHash tableSegmented hash tableHash tableHash table
Null values allowed?NoYesYesNo
Thread-safe?Yes (synchronized)Yes (locking at a finer granularity)No (unsynchronized)Yes (synchronized)
Iterator thread-safetyYesYesNoYes

code samples are here

 
1- Sorting a collection

 

package CollectionFramework;


import java.util.*;
public class ExsortArrList1 {

public static void main(String[] args) {
List collDemo=new ArrayList();

collDemo.add(5);
collDemo.add(15);
collDemo.add(15);
collDemo.add(12);

Collections.sort(collDemo);

Iterator iterator=collDemo.iterator();
while(iterator.hasNext()){
System.out.println("using iterator :only next: "+iterator.next());
}
}
}

2- Searching in collection

package CollectionFramework;

import java.util.*;
public class ExsearchingArrList1 {

public static void main(String[] args) {
List collDemo=new ArrayList();

collDemo.add(5);
collDemo.add(15);
collDemo.add(15);
collDemo.add(12);
Collections.sort(collDemo);
/
int i = Collections.binarySearch(collDemo,12);

System.out.println("position of element is ");
System.out.println(i);
}
} 

3- Shuffling a collection

package CollectionFramework;

import java.util.*;
public class ExshuffleArrList1 {

public static void main(String[] args) {
List collDemo=new ArrayList();

collDemo.add(5);
collDemo.add(15);
collDemo.add(15);
collDemo.add(12);

Collections.shuffle(collDemo);

Iterator iterator=collDemo.iterator();
while(iterator.hasNext()){
System.out.println("using iterator :only next: "+iterator.next());
}
}
}

4– Reversing a collection

package CollectionFramework;

import java.util.*;
public class ExreverseArrList1 {

public static void main(String[] args) {
List collDemo=new ArrayList();

collDemo.add(5);
collDemo.add(15);
collDemo.add(15);
collDemo.add(12);

Collections.reverse(collDemo);

Iterator iterator=collDemo.iterator();
while(iterator.hasNext()){
System.out.println("using iterator :only next: "+iterator.next());
}
}
}

Interview Questions —

  • What is difference between array and arraylist?
  • What is difference between arraylist and Hashset?
  • What is difference between Hashmap and Hashset?
  • What is general contract of hashcode and equals method?
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.