Showing posts with label Collections In Java. Show all posts
Showing posts with label Collections In Java. Show all posts

Sunday, July 26, 2020

List Interface In Java

List Interface :
public interface List<E>
	extends Collection<E>

All Superinterfaces:
Collection<E>, Iterable<E>

All Known Implementing Classes:
AbstractList, AbstractSequentialList, ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList, Stack, Vector
All Known Implementing Classes of List Interface:
  • ArrayList
  • LinkedList
  • AbstractList
  • AbstractSequentialList
  • AttributeList
  • CopyOnWriteArrayList
  • RoleList
  • RoleUnresolvedList
  • Stack
  • Vector
List interface is an ordered collection framework and present in java.util package (also known as a sequence). It allows us to store and access elements sequentially. It extends the Collection interface.

It is a factory of ListIterator interface by using the ListIterator, we can iterate the list in forward and backward directions. Its allow duplicate elements. Its allow multiple null elements

Method Description
void add(int index, E element) Add the specified element at the specified position (at given index) in a list.
boolean add(E e) Append (add) the specified element at the end of a list.
boolean addAll(Collection<? extends E> c) Append (add) all of the elements in the specified collection to the end of a list.
boolean addAll(int index, Collection<? extends E> c) Append all the elements in the specified collection,
starting at the specified position of the list.
void clear() Remove all of the elements from this list.
   
boolean equals(Object o) Compare the specified object with the elements of a list. Return true or false
int hashcode() Return the hash code value for a list.
E get(int index) Fetch the element for given index of the list.
boolean isEmpty() Returns true if the list is empty, otherwise false.
int lastIndexOf(Object o) Return the index in the list of the last occurrence of the specified element,
or -1 if the list does not contain this element.
Object[] toArray() Return an array containing all of the elements in the list in the same order.
<T> T[] toArray(T[] a) Return an array containing all of the elements in the list in the same order.
boolean contains(Object o) Returns true if the list contains the specified element
boolean containsAll(Collection<?> c) Returns true if the list contains all the specified collection
int indexOf(Object o) Return the index in this list of the first occurrence of the specified element,
or -1 if the List does not contain this element.
E remove(int index) Remove the element present at the specified position (index) in the list.
boolean remove(Object o) Remove the first occurrence of the specified element.
boolean removeAll(Collection<?> c) Remove all the elements from the list which are present in the specified collection.
void replaceAll(UnaryOperator<E> operator) Replace all the elements from the list with the specified element.
void retainAll(Collection<?> c) Retain all the elements in the list that are present in the specified collection.
 And remove other elements
E set(int index, E element) Replace the specified element in the list, present at the specified index.
void sort(Comparator<? super E> c) Sort the elements of the list on the basis of specified comparator.
We need to pass comparator
Spliterator<E> spliterator() Create spliterator over the elements in a list.
List<E> subList(int fromIndex, int toIndex) Return  sublist of elements lies within the given range.
int size() Return the number of elements in the list.

Saturday, July 25, 2020

ArrayList


public class ArrayList
 extends AbstractList
  implements List, RandomAccess, Cloneable, Serializable
All Implemented Interfaces:
Serializable, Cloneable, Iterable, Collection, List, RandomAccess

Direct Known Subclasses:
AttributeList, RoleList, RoleUnresolvedList

ArrayList class is resizable-array (dynamic array) implementation of the List interface.It is a part of collection framework and is present in java.util package. it is based on an Array data structure. Internally its use Object[].
Default capacity or size of ArrayList is 10.


Data Growth Of ArrayList:-
ArrayList grows (increments) 50% of the current array size automatically if the number of elements exceeds its capacity.


Load Factor Of ArrayList is 1.
The load factor is a measure of how full the array list is allowed to get before its capacity is automatically increased.


Note:- ArrayList() is slow as compared to array().

ArrayList can store only objects, not primitives that means if we store primitive types like int, char etc. it we be autoboxed to wrapper classes of same types like Integer, Character, Boolean etc.

If we try to create ArrayList with primitive types it will show as below "Syntax error"

ArrayList<int> listInt = new ArrayList<int>();
Syntax error, insert "Dimensions" to complete ReferenceType


Right way to use primitive type.

package com.shubh.example;
import java.util.ArrayList;

public class ArrayListExample {
 public static void main(String[] args) {
  ArrayList listInt = new ArrayList();
  listInt.add(10); // It will autoboxing to Integer wrapper class.
  System.out.println(listInt);
 }
}

Q- Is arraylist is thread safe?
Answer:- No.

Q- Is ArrayList synchronized?
Answer:- No.

Q- How to make arraylist synchronized or thread safe? Or How to synchronize ArrayList?
We can use Collections.synchronizedList() to synchronize ArrayList.
Collections.synchronizedList() method – It returns synchronized list backed by the specified list.
CopyOnWriteArrayList class – It is a thread-safe variant of ArrayList.


package com.shubh.example;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArrayListExample {
 public static void main(String[] args) {
  ArrayList<Integer> listInt = new ArrayList<Integer>();
  listInt.add(10); // It will autoboxing to Integer wrapper class.

  List<Integer> listIntSyn = Collections.synchronizedList(listInt);
  System.out.println(listIntSyn);
  // OR
  ArrayList<Integer> listIntSyn2 = (ArrayList<Integer>) Collections.synchronizedList(listInt);
  System.out.println(listIntSyn2);
 }
}

Constructors of Java ArrayList:
  • ArrayList(): It is used to create an empty arraylist that means default size is 10.
  • ArrayList(Collection<? extends E> c): It is used to create an arraylist that is initialized with the specified collection c.
  • ArrayList(int capacity): It is used to create an arraylist with specified initial capacity.

Methods of Java ArrayList
  • boolean add(E e): To add an element at the end of a list.
  • void add(int index, E element): To add an element at the specified position in a list.
  • boolean addAll(Collection<? extends E> c)
  • boolean addAll(int index, Collection<? extends E> c)
  • void clear()
  • void ensureCapacity(int requiredCapacity)
  • E get(int index)
  • boolean isEmpty()
  • int lastIndexOf(Object o)
  • Object[] toArray()
  • <T> T[] toArray(T[] a)
  • Object clone()
  • boolean contains(Object o)
  • int indexOf(Object o)
  • E remove(int index)
  • boolean remove(Object o)
  • boolean removeAll(Collection<?> c)
  • boolean removeIf(Predicate<? super E> filter)
  • protected void removeRange(int fromIndex, int toIndex)
  • void replaceAll(UnaryOperator<E> operator)
  • void retainAll(Collection<?> c)
  • E set(int index, E element)
  • void sort(Comparator<? super E> c)
  • Spliterator<E> spliterator()
  • List<E> subList(int fromIndex, int toIndex): It the list  of elements lies within the given range.
  • int size() : It return the number of elements available in the list.
  • void trimToSize()
Q- Is Arraylist fail fast or fail safe?
ArrayLists are fail-fast.

Q- Dynamic array in java without arraylist?
Custom Own ArrayList Implementation

Summary of ArrayList:-
  • ArrayList class can contain duplicate elements and null values.
  • ArrayList  maintains the insertion order i.e it is an ordered collection.
  • ArrayList can store only objects, not primitives  that means if we store primitive types like int, char etc. it we be autoboxed to wrapper classes of same types like Integer, Character, Boolean etc.
  • ArrayList is non-synchronized.
  • ArrayList allows ramdom access because array work on index basis.
  • Default Capacity is 10
  • Load Factor is 1
  • Threshold value = Initial_Size * Load_Factor i.e 10*1 = 10
  • Growth Rate is 50% i.e Cutrrent_Size + Current_Size/2 
  • ArrayList() is slow as compared to array().
Time complexity
  • add() – O(1) time when add new element in ArrayList; however, worst-case, when increase size internaly and a new array has to be created and all the elements copied to it, it's O(n)
  • add(index, element) –  O(n) time, on average runs, while add element at given index
  • get() – It is always a constant time O(1) operation
  • remove() – runs in linear O(n) time. We have to iterate the entire array to find the element qualifying for removal.
  • indexOf() – its checks each element one by one, So runs in linear time. It iterates through the internal array and  so the time complexity for this operation always requires O(n) time.
  • contains() – implementation is based on indexOf(), so it'll also run in O(n) time.



Thursday, July 23, 2020

LinkedList


public class LinkedList<E>
 extends AbstractSequentialList<E>
  implements List<E>, Deque<E>, Cloneable, Serializable
Type Parameters:
E - the type of elements held in this collection

All Implemented Interfaces:
Serializable, Cloneable, Iterable, Collection, Deque, List, Queue

LinkedList class is a part of Java’s collections framework and is present in java.util package.
LinkedList Class is implements List and Deque interfaces and extends AbstractList.It use Doubly-linked list to store data.So we can perform all operations of list and queue. ArrayList used Node internally.
As LinkedList doubly-linked list to store data, doubly-linked list consists of a collection of nodes, where each node have a pointer/reference to the next node and  previous node in the list.

Iterating over a LinkedList:-
  • iterator()
  • listIterator()
  • simple for-each loop
  • Java 8 forEach() and lambda expression.
  • iterator() and Java 8 forEachRemaining() method
  • descendingIterator()
Summary of LinkedList:-
  • LinkedList class can contain duplicate elements and null values.
  • LinkedList  maintains the insertion order i.e it is an ordered collection.
  • LinkedList can store only objects, not primitives  that means if we store primitive types like int, char etc. it we be autoboxed to wrapper classes of same types like Integer, Character, Boolean etc.
  • LinkedList is non-synchronized i.e. LinkedList is not thread-safe
  • Manipulation i.e adding or removing elements with LinkedList() is faster as compared to ArrayList() becaues no shifting need to be occured.
  • LinkedList is slower than ArrayList if I randomly access its elements i.e. get() operation.Because it requires a sequential scan from the front or back of the list
  • Default Capacity : Constructs empty list. we can not define initial size of LinkedList like ArrayList. it create empty constructs list.
  • LinkedList can be use as list, skack or queue.
  • LinkedList consumes more memory than an ArrayList because it also stores the next and previous references along with the data.
Time complexity
  • Time complexity for add() – add an element to the end of the Linkedlist. It only updates a tail, and hence, it's O(1) constant-time complexity.
  • Time complexity add(index, element) – on average runs in O(n) time
  • Time complexity get() – search an element takes O(n) time.
  • Time complexity remove(element) – to remove an element from linkedlist, we first need to find it. This operation is O(n).
  • Time complexity remove(index) – to remove an element by index from linkedlist, we first need to travers the linklist from the beginning; hence, the overall complexity is O(n).
  • Time complexity contains() – also has O(n) time complexity
Methods Of  LinkedList Class:- 
  • boolean add(Object o)
  • void add(int index, Object o)
  • boolean addAll(Collection c):
  • boolean addAll(int index, Collection c):
  • void addFirst(Object o):
  • void addLast(Object o):
  • void clear(): Remove all elements from list.
  • Object clone(): returns the copy of the Linked List object.
  • boolean contains(Object o):
  • Object get(int index):
  • Object getFirst():
  • Object getLast():
  • int indexOf(Object o): return index of element.If element not present return -1
  • int lastIndexOf(Object o): if element not present return -1
  • ListIterator listIterator(int index): returns an object of Iterator class that contains  the elements in proper sequence  starting from the specified position as mentioned in the argument.
  • Object remove(int index):  if index specified is out of range. It returns an  IndexOutOfBoundsException exception.
  • boolean remove(Object o): This will deletes the first occurrence of given element in the list.
  • Object removeFirst(): removes the head element from this linked list.
  • Object removeLast(): removes the last element from this linked list.
  • boolean removeFirstOccurrence(Object o): It is used to remove the first occurrence of the specified element in a list (when traversing the list from head to tail).
  • boolean removeLastOccurrence(Object o): removes the last occurrence of the specified element in a list (when traversing the list from head to tail).
  • Object set(int index, Object element): replaces the content  at index  in argument list.
  •  int size(): returns the size of the Linked List i.e. number of elements in the list.
  •  Object[] toArray(): converts the list to  array.
  • <T> T[] toArray(T[] a):
  • Iterator<E> descendingIterator(): return an iterator over the elements in a deque in reverse sequential order.
  • E element(): It is used to retrieve the first element of a list.
  • boolean offer(E e): It adds the element as the last element of a list.
  • boolean offerFirst(E e): It inserts the specified element at the front of a list.
  • boolean offerLast(E e): inserts the element at the end of a list.
  • E peek(): return  the first element of a list.
  • E peekFirst(): return the first element of a list or returns null if a list is empty.
  • E peekLast(): return the last element of a list or returns null if a list is empty.
  • E poll(): return and removes the first element of a list.
  • E pollFirst():return and removes the first element of a list, or returns null if a list is empty.
  • E pollLast(): return and removes the last element of a list, or returns null if a list is empty.
  • E pop(): pops an element from the stack.
  • void push(E e): pushes an element onto the stack.

Related Tutorials 

Java Vector

Vector in java:
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
Direct Known Subclasses:
Stack
All Implemented Interfaces:
Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess
  • Vector is a legacy class.It is introduced in JDK 1.0
  • But Vector belongs to Java Collection framework since Java 1.2.
  • Vector extends AbstractList and implements List interfaces.
  • Vector implements Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess interfaces.
  • Directly known subclass of Vector is Stack.
  • Vectors fall in legacy classes.
  • Vector belongs to the java.util package and implements the List interface, so we can use all the methods of List interface
  • Vector is resizable-array implementations of the List interface. 
  • Vector  internally use an array data structure to store the elements.
  • Vector is synchronized.
  • Vector is thread-safe and It is recommended to use in multithreaded environment only because it is slower then ArrayList.
  • Vector can use both Iterator interface and Enumeration interface to traverse the elements.
  • The iterators returned by this class's iterator and listIterator methods are fail-fast.
  • Java Vector contains many legacy methods that are not the part of a collections framework.
  • Vector maintains an insertion order like an ArrayList.
  • Vector has poor performance in adding, searching, deleting, and updating its elements due to it is synchronized.
  • Vector permits null values and duplicates.
  • Vector increments 100% of its initial capacity. if  the total number of elements exceeds than its     capacity.
Initial Capacity:10.
Load Factor:1 (when the list of vector is full)
Growth Rate: Groth Rate of vector is 100% that means.

Vector Example:
package com.javaiq.in;

import java.io.*;
import java.util.*;

public class VectorExample {

	public static void main(String[] arg) {
		// Creating a default vector
		Vector v1 = new Vector();
		v1.add(8);
		v1.add(6);
		v1.add("Test");
		v1.add("JavaIQ");
		v1.add(7);

		// Display the vector elements
		System.out.println("Vector v1 object elements :  " + v1);

		// Creating generic vector
		Vector<Integer> v2 = new Vector<Integer>();
		v2.add(11);
		v2.add(22);
		v2.add(33);

		// Display the vector elements
		System.out.println("Vector v2 object elements :  " + v2);
	}
}


Set Interface In Java

Set Interface In Java :
  • Set is an interface.
  • its belongs to java.util package and extends the Collection interface.
  • It is an unordered collection of objects.
  • Set is a collection of unique elements.It does not allow duplicate elements means no duplicate elements.
  • It allow only one null element.
public interface Set<E>
	extends Collection<E>
All Known Subinterfaces:
NavigableSet<E>, SortedSet<E>

All Known Implementing Classes:
AbstractSet, ConcurrentHashMap.KeySetView, ConcurrentSkipListSet, CopyOnWriteArraySet, EnumSet, HashSet, JobStateReasons, LinkedHashSet, TreeSet
SortedSet Interface : 
public interface SortedSet<E>
	extends Set<E>

All Known Implementing Classes:
	ConcurrentSkipListSet, TreeSet

All Known Subinterfaces:
	NavigableSet<E> 
Implementation of Set
  • HashSet
  • LinkedHashSet
  • SortedSet : It is a sub-interface of set interface.
  • TreeSet : TheeSet is an implementation class of SortedSet. TreeSet has O(log(n)) time complexity for the add(), remove() and contains() operations because of the TreeMap implementation internally.
  • EnumSet
  • CopyOnWriteArraySet : CopyOnWriteArraySet is a thread-safe variant of HashSet, its uses a CopyOnWriteArrayList internally for all of its operations. The add(), remove() and contains() methods have O(n) average time complexity.
  • ConcurrentSkipListSet : ConcurrentSkipListSet have O(log(n)) time complexity for add(), remove() and contains(), as it's based in skip list data structure.
Time complexity For HashSet, LinkedHashSet, and EnumSet, the add(), remove() and contains() operations cost constant O(1) time. These are uses HashMap internally.

Friday, February 14, 2020

HashSet equals method in java

Before to understand, how HashSet work with HashCode & Equals methods. We have to understand about hashcode & equals methods.

Note:- Point to be remember that. As it implements the Set Interface, duplicate values are not allowed.

Method Definition and Default Implementation
equals(Object obj): As we know equal method belong java.lang.Object that indicates that by default — two objects are equal if and only if they are stored in the same memory address. provided by the JDK, based on memory location. by default it check only reference of object.
by default equal method check references like "==". If  not override.

hashcode(): As we know equal method belong java.lang.Object that returns an integer representation of the object memory address. By default, hashcode() method returns a random integer that is unique for each instance.

The Contract Between equals() and hashcode()
1) If two objects are equal according to the equals(Object) method, then hashcode of of two object by the hashcode() method on each of the two objects must be the same integer.
2) if hashcode of two object is same by hashcode() method but object may not equal by calling equals(Object) method.click here to see in more details

Without hashCode and equal method
package hashsetEqualExample;

public class Student {
 private int id;
 private String name;

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

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 /*
  * @Override public boolean equals(Object obj) { if (obj == null) return false;
  * if (!(obj instanceof Student)) return false; if (obj == this) return true;
  * return this.getId() == ((Student) obj).getId(); }
  * 
  * @Override public int hashCode() { return id; }
  */
}
package hashsetEqualExample;

import java.util.HashSet;

public class HashcodeEquals {

 public static void main(String[] args) {
  Student student1 = new Student(1, "Amit");
  Student student2 = new Student(1, "Amit");
  System.out.println("student1 hashcode = " + student1.hashCode());
  System.out.println("student2 hashcode = " + student2.hashCode());
  System.out.println("equality check between student1 and student2 = " + student1.equals(student2));

  System.out.println("\n\n#######HashSet Test##### without hashcode & equal method########");
  HashSet<Student> students = new HashSet<Student>();
  students.add(student1);
  students.add(student2);
  System.out.println("HashSet size = " + students.size());
  System.out.println("HashSet contains Amit = " + students.contains(new Student(1, "Amit")));
 }
}
Output:
student1 hashcode = 1829164700
student2 hashcode = 2018699554
equality check between student1 and student2 = false


#######HashSet Test##### without hashcode & equal method########
HashSet size = 2
HashSet contains Amit = false

As in the above example. I have not Override hashCode() and equals() methods so the hashCode of the two object with same value are different and they are not seems to be equal. Hence HashSet consider this as two different object and add into HashSet. And while i try to get new object with same value its return false because this is new object for HashSet.

With hashCode() and without equals() method
package hashsetEqualExample;

public class Student {
 private int id;
 private String name;

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

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 /*
  * @Override public boolean equals(Object obj) { if (obj == null) return false;
  * if (!(obj instanceof Student)) return false; if (obj == this) return true;
  * return this.getId() == ((Student) obj).getId(); }
  */

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

import java.util.HashSet;

public class HashcodeEquals {

 public static void main(String[] args) {
  Student student1 = new Student(1, "Amit");
  Student student2 = new Student(1, "Amit");
  System.out.println("student1 hashcode = " + student1.hashCode());
  System.out.println("student2 hashcode = " + student2.hashCode());
  System.out.println("equality check between student1 and student2 = " + student1.equals(student2));

  System.out.println("\n\n#######HashSet Test##### With hashCode() and without equals() method ########");
  HashSet<Student> students = new HashSet<Student>();
  students.add(student1);
  students.add(student2);
  System.out.println("HashSet size = " + students.size());
  System.out.println("HashSet contains Amit = " + students.contains(new Student(1, "Amit")));
 }
}
Output:
student1 hashcode = 1
student2 hashcode = 1
equality check between student1 and student2 = false


#######HashSet Test##### With hashCode() and without equals() method ########
HashSet size = 2
HashSet contains Amit = false


As in the above example. I have Override hashCode() but not override equals() methods. So the hashCode of the two object with same value is same. But as per "hashCode and equals contract" they are not  equal. Hence HashSet consider this as two different object and add into HashSet and while i try to get new object with same value its return false because this is new object for HashSet.

In HashSet, add method of HashSet use as below.
public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
Adds the specified element into HashSet. If it is not already present. by using as below condition
(e==null ? e2==null : e.equals(e2))
More formally, adds the specified element e to this set if this set contains no element e2 such that

If this set already contains the element, the call leaves the set  unchanged(not added element) and returns false.

With equals() method override and without hashCode()
package hashsetEqualExample;

public class Student {
 private int id;
 private String name;

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

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 @Override
 public boolean equals(Object obj) {
  if (obj == null)
   return false;
  if (!(obj instanceof Student))
   return false;
  if (obj == this)
   return true;
  return this.getId() == ((Student) obj).getId();
 }

 /*
  * @Override public int hashCode() { return id; }
  */
}
package hashsetEqualExample;

import java.util.HashSet;

public class HashcodeEquals {

 public static void main(String[] args) {
  Student student1 = new Student(1, "Amit");
  Student student2 = new Student(1, "Amit");
  System.out.println("student1 hashcode = " + student1.hashCode());
  System.out.println("student2 hashcode = " + student2.hashCode());
  System.out.println("equality check between student1 and student2 = " + student1.equals(student2));

  System.out.println("\n\n#######HashSet Test##### With equals() method override and without hashCode() ########");
  HashSet<Student> students = new HashSet<Student>();
  students.add(student1);
  students.add(student2);
  System.out.println("HashSet size = " + students.size());
  System.out.println("HashSet contains Amit = " + students.contains(new Student(1, "Amit")));
 }
}
Output:
student1 hashcode = 1829164700
student2 hashcode = 2018699554
equality check between student1 and student2 = true


#######HashSet Test##### With equals() method override and without hashCode() ########
HashSet size = 2
HashSet contains Amit = false


As in the above example. I have override equals() but not Override hashCode()  methods so the hashCode of the two object with same value are different. even they are equal by equals() method.But because of there hashCode are different. Hence HashSet consider this as two different object and add into HashSet and while i try to get new object with same value its return false because this is new object for HashSet.

With Override hashCode() and equals() method
package hashsetEqualExample;

public class Student {
 private int id;
 private String name;

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

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 @Override
 public boolean equals(Object obj) {
  if (obj == null)
   return false;
  if (!(obj instanceof Student))
   return false;
  if (obj == this)
   return true;
  return this.getId() == ((Student) obj).getId();
 }

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

import java.util.HashSet;

public class HashcodeEquals {

 public static void main(String[] args) {
  Student student1 = new Student(1, "Amit");
  Student student2 = new Student(1, "Amit");
  System.out.println("student1 hashcode = " + student1.hashCode());
  System.out.println("student2 hashcode = " + student2.hashCode());
  System.out.println("equality check between student1 and student2 = " + student1.equals(student2));

  System.out.println("\n\n#######HashSet Test##### With Override hashCode() and equals() method ########");
  HashSet<Student> students = new HashSet<Student>();
  students.add(student1);
  students.add(student2);
  System.out.println("HashSet size = " + students.size());
  System.out.println("HashSet contains Amit = " + students.contains(new Student(1, "Amit")));
 }
}
Output:
student1 hashcode = 1
student2 hashcode = 1
equality check between student1 and student2 = true


#######HashSet Test##### With Override hashCode() and equals() method ########
HashSet size = 1
HashSet contains Amit = true
Conclusion:
  • It is mandatory to override hashcode() and equals() method each time.
  • If two objects are equal by equals() method, they MUST have the same hash code by overriding hashCode() method.
  • If two objects have the same hash code, they may or may not equal.
  • Overriding equals() alone will fail you business logic with hashing data structures like: HashSet, HashMap, HashTable ... etc.
  • Overriding hashcode() alone, it does not force JVM to ignore memory addresses when comparing two objects. because by default equals() method compare reference like "==" operator.

Thursday, February 13, 2020

TreeSet


public class TreeSet<E> extends AbstractSet<E>
 implements NavigableSet<E>, Cloneable, Serializable

public interface NavigableSet<E> extends SortedSet<E>
Type Parameters:
E - the type of elements maintained by this set

All Implemented Interfaces:
Serializable, Cloneable, Iterable<E>, Collection<E>, NavigableSet<E>, Set<E>, SortedSet<E>
  • TreeSet class is implementation of NavigableSet interface and NavigableSet extends SortedSet Interface that means you can say TreeSet is implementation SortedSet.
  • TreeSet internally use TreeMap to store elements.
  • It store key as elements in HashMap and value as PRESENT where  PRESENT = new Object(); 

private static final Object PRESENT = new Object(); 
public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }

  • TreeSet can not have duplicate elements i.e.it has only unique element only.
  • TreeSet cannot contain null value. if add null values it will throw NullPointerException.
  • The elements are in sorted order using their natural ordering, or by a Comparator provided at creation time, depending on which constructor is used.
  • TreeSet implementation provides guaranteed O(log(n)) time cost for add, remove and contains operations.
  • first(), last(), headset(), tailset(), etc. time complexity of basic methods is O(1)
  • TreeSet are not thread-safe i.e not synchronized. You can use Collections.synchronizedSet()  method to make them synchronized.

Example to test null value in TreeSet:-

package com.shubh.example;

import java.util.SortedSet;
import java.util.TreeSet;

public class TreeSetExample {
 
 public static void main(String[] args) {
  SortedSet<String> treeSet = new TreeSet<>();
  treeSet.add("Hi Aa");
  treeSet.add(null);
  //treeSet.add(null);
  System.out.println(treeSet);
 }
}
Output:-

Exception in thread "main" java.lang.NullPointerException
 at java.util.TreeMap.put(Unknown Source)
 at java.util.TreeSet.add(Unknown Source)
 at com.shubh.example.TreeSetExample.main(TreeSetExample.java:11)