Java HashSet - Walking Techie

Blog about Java programming, Design Pattern, and Data Structure.

Sunday, December 11, 2016

Java HashSet

HashSet is a part of collection framework and is present in java.util package. Java HashSet is most popular implementation of Set interface. Java HashSet is backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.

The HashSet class extends AbstractSet class and implements the Set , Cloneable and Serializable interfaces.

HashSet is a generic class that has this declaration:

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable

Here, E specifies the type of objects that the set will hold.

  • Java HashSet inherits AbstractSet class and implements Set interface.
  • Java HashSet is default size is 16. The size can increase if collection grows or shrunk if objects are removed from the collection.
  • Java HashSet does not guarantee the insertion order of elements.
  • Java HashSet does not allows duplicate entries.
  • Java HashSet allows null element.
  • Java HashSet can not be used for primitive types, like int, char, etc. We need to use wrapper classes.
  • Java HashSet is not synchronized.
  • Java HashSet is not thread-safe. You can get thread-safe HashSet using Collections.synchronizedSet method at the cost of performance. You can also use CopyOnWriteArraySet concurrency class for thread safety.
  • The iterator return by java HashSet's Iterator() method is fail-fast. If the set structure is modified after creating the iterator in any other way except the iterator remove method, it will throw ConcurrentModificationException.

Java HashSet constructors

There are four constructors in Java HashSet.

Constructor Description
public HashSet(int initialCapacity) This HashSet constructor will return an empty set; backing HashMap instance has the specified initial capacity and default load factor 0.75. If the initialCapacity argument is negative, it will throw IllegalArgumentException.
public HashSet() Most widly used Java HashSet constructor.Constructs a new empty set; the backing HashMap instance has default initial capacity 16 and load factor 0.75.
public HashSet(Collection<? extends E> c) This Java HshSet constructor return a new set containing the elements of the specified collection c. The HashMap is created with default load factor 0.75 and an initial capacity sufficient to contain the elements in the specified collection. It will throws NullPointerException if the specified collection c is null
public HashSet(int initialCapacity, float loadFactor) Constructs a new empty set; the backing HashMap instance has the specified initial capacity and the specified load factor. If the initialCapacity argument is negative, or if the load factor is nonpositive, it will throw IllegalArgumentException.

Below is a simple code snippet showing Java HashSet constructors.

//default HashSet constructor
Set<String> set=new HashSet<String>();

//HashSet constructor with initial capacity
Set<String> wordSet=new HashSet<String>(1024);

//Empty set with backing HashMap specified initial capacity and load factor 0.80.
Set<String> set1= new HashSet<String>(128, 0.80f);

//HashSet with specified collection
List<String> list=new LinkedList<String>();
list.add("Nokia");
list.add("Samsung");
list.add("MI");
list.add("Zenfone");
Set<String> set2= new HashSet<String>(list);

Java HashSet methods

Method Description
public int size() Returns the number of elements in the invoking set.
public boolean isEmpty() Returns true if the invoking set contains no elements.
public boolean contains(Object obj) Returns true if the invoking set contains the specified element.
public Object clone() Returns a shallow copy of the invoking HashSet instance.(The elements themselves are not copied.)
public boolean add(E e) Adds the specified element to this set if it is not already present. If this set already contains the element, the call leaves the set unchanged and returns false.
public boolean remove(Object obj) Removes the specified element from this set, if it is present. If the set does not contain the element, it is unchanged.
public void clear() Removes all of the elements from this set. The set will be empty after this call returns.
public Iterator<E> iterator() Returns an iterator over the elements in this set. The elements are returned in no particular order.
public Spliterator<E> spliterator() Creates a late-binding and fail-fast Spliterator over the elements in this set. This is introduced in Java 8.

Java HashSet Example

Java HashSet common operations

Here we will see an example of commonly used method of HashSet.

package com.walking.techie;

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo {
 public static void main(String[] args) {
  Set<Integer> numbers = new HashSet<Integer>();

  // Add elements in HashSet
  numbers.add(10);
  numbers.add(20);
  numbers.add(30);

  System.out.println("Elements of numbers set " + numbers);

  // size of hash set numbers
  System.out.println("Size of numbers set is " + numbers.size());

  // check set numbers contain 20
  System.out.println("numbers set contain element 20 ?:  " + numbers.contains(20));

  // creating odd numbers set
  Set<Integer> oddNumbers = new HashSet<Integer>();
  oddNumbers.add(5);
  oddNumbers.add(25);
  oddNumbers.add(9);

  // appending odd numbers set to numbers set
  numbers.addAll(oddNumbers);
  System.out.println("numbers set after appending odd numbers set " + numbers);

  // clear method to empty the odd numbers set
  oddNumbers.clear();
  System.out.println("odd number set " + oddNumbers);

  // remove first occurrence of 5
  boolean isRemoved = numbers.remove(new Integer(5));
  System.out.println("element 5 removed ? " + isRemoved + " numbers contains " + numbers);
  // removeAll example
  oddNumbers.add(13);
  oddNumbers.add(25);
  oddNumbers.add(9);
  numbers.removeAll(oddNumbers);
  System.out.println("numbers elements after removeAll call " + numbers);

  numbers.add(25);
  numbers.add(9);

  // retainAll example
  oddNumbers.add(25);
  oddNumbers.add(11);
  oddNumbers.add(9);

  numbers.retainAll(oddNumbers);
  System.out.println("numbers elements after retainAll operation is " + numbers);

 }
}

Output of above program is shown below:

Elements of numbers set [20, 10, 30]
Size of numbers set is 3
numbers set contain element 20 ?:  true
numbers set after appending odd numbers set [20, 5, 25, 9, 10, 30]
odd number set []
element 5 removed ? true numbers contains [20, 25, 9, 10, 30]
numbers elements after removeAll call [20, 10, 30]
numbers elements after retainAll operation is [25, 9]

Java HashSet removeIf

The removeIf method was added in Java 8 and available in Collection interface.This method will remove all of the elements in the set which will satisfy the given predicate. Below is the program of HashSet removeIf example.

package com.walking.techie;

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

public class HashSetRemoveIfDemo {

 public static void main(String[] args) {
  Set<Integer> numbers = new HashSet<Integer>();

  // add numbers from 1 to 10 in set
  for (int i = 1; i <= 10; i++) {
   numbers.add(i);
  }
  Predicate<Integer> filter = new HashSetRemoveIfDemo().new EvenPredicate<Integer>();

  //set before removeIf operation
  System.out.println("Numbers set " + numbers);

  numbers.removeIf(filter);
  System.out.println("Numbers set after removeIf call " + numbers);
 }

 private class EvenPredicate<T> implements Predicate<Integer> {

  @Override
  public boolean test(Integer t) {
   return t%2==0;
  }
 }
}

Output of above program is shown below:

Numbers set [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Numbers set after removeIf call [1, 3, 5, 7, 9]

Java HashSet Iterator

Java HashSet iterator is fail-fast, so iterator will throw java.util.ConcurrentModificationException if the set is modified at any time after the iterator is created, in any way except through the iterator's own remove method.

package com.walking.techie;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetIteratorDemo {

 public static void main(String[] args) {
  Set<Integer> numbers = new HashSet<Integer>();
  numbers.add(23);
  numbers.add(34);
  numbers.add(13);
  numbers.add(2);
  numbers.add(28);
  System.out.print("Elements of numbers set [");

  // traversal over set using iterator
  Iterator<Integer> iterator = numbers.iterator();
  while (iterator.hasNext()) {
   int number = iterator.next();
   System.out.print(number + " ");
  }
  System.out.println("]");

  // ConcurrentModificationException
  iterator = numbers.iterator();
  while (iterator.hasNext()) {
   int number = iterator.next();
   System.out.print(number + " ");
   if (number == 2) {
    System.out.println();
    numbers.add(12); // throw ConcurrentModificationException
   }
  }
 }
}

Output of above program is shown below:

Elements of numbers set [34 2 23 28 13 ]
34 2
Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
 at java.util.HashMap$KeyIterator.next(HashMap.java:1461)
 at com.walking.techie.HashSetIteratorDemo.main(HashSetIteratorDemo.java:30)

Java HashSet to Array Example

Here is example to convert a set into Array and Array into set. Sometimes we need to convert array into set and vice-versa.

package com.walking.techie;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class HashSetToArray {

 public static void main(String[] args) {
  Set<String> phone= new HashSet<String>();
  phone.add("Nokia");
  phone.add("Samsung");
  phone.add("MI");
  phone.add("Zenfone");
  System.out.println("Set of phone "+ phone);

  //convert set to Array
  String[] array1=new String[phone.size()];
  phone.toArray(array1);
  System.out.println("Elements of Array1 "+ Arrays.toString(array1));

  Object[] array2=new Object[phone.size()];
  array2=phone.toArray();
  System.out.println("Elements of Array2 "+ Arrays.toString(array2));

  //convert array to set
  Set<String> set=new HashSet<String>(Arrays.asList(array1));
  System.out.println("Elements of set " + set);
 }
}

Output of above program is shown below:

Set of phone [Samsung, Zenfone, MI, Nokia]
Elements of Array1 [Samsung, Zenfone, MI, Nokia]
Elements of Array2 [Samsung, Zenfone, MI, Nokia]
Elements of set [Samsung, Zenfone, MI, Nokia]

Java HashSet to List Example

List and Set both are different from each others, but sometimes we need List from Set and vice-versa.

package com.walking.techie;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class HashSetToList {

 public static void main(String[] args) {
  Set<String> phone = new HashSet<String>();
  phone.add("Nokia");
  phone.add("Samsung");
  phone.add("MI");
  phone.add("Zenfone");
  System.out.println("Set of phone " + phone);

  // convert set to list
  List<String> phoneList = new ArrayList<String>(phone);
  System.out.println("Elements of phoneList " + phoneList);

  // convert list to set
  Set<String> phoneSet = new HashSet<String>(phoneList);
  System.out.println("Elements of set " + phoneSet);
 }
}

Output of above program is shown below:

Set of phone [Samsung, Zenfone, MI, Nokia]
Elements of phoneList [Samsung, Zenfone, MI, Nokia]
Elements of set [Samsung, Zenfone, MI, Nokia]

No comments :

Post a Comment