o7planning

Java Set Tutorial with Examples

  1. Set
  2. Simple Examples
  3. stream()
  4. iterator()
  5. How does Set check for duplication?
  6. of(..)
  7. spliterator()
  8. toArray​(..)

1. Set

Set is an interface in Java Collection Framework, and is a subinterface of Collection, therefore it has all the features of a Collection.
Set is an unordered Collection, not allowing duplicated elements and containing maximum 1 null element. If you intentionally add a duplicated element to Set, this action will be igorned and Set will not change.
public interface Set<E> extends Collection<E>
SortedSet is a subinterface of Set. It has the ability to automatically sort the elements by their natural order or by a provided Comparator.
The hierarchy of classes implements Set interface.
Methods of Set interface:
Set interface
boolean add​(E e)  
boolean addAll​(Collection<? extends E> c)  

void clear()  

boolean contains​(Object o)  
boolean containsAll​(Collection<?> c)  

boolean equals​(Object o)  
int hashCode()  
boolean isEmpty()  
int size()  

boolean remove​(Object o)  
boolean removeAll​(Collection<?> c)  
boolean retainAll​(Collection<?> c)  

Object[] toArray()  
<T> T[] toArray​(T[] a)

Iterator<E> iterator()  
default Spliterator<E> spliterator()  

static <E> Set<E> copyOf​(Collection<? extends E> coll)  

static <E> Set<E> of()  
static <E> Set<E> of​(E e1)  
static <E> Set<E> of​(E... elements)  
static <E> Set<E> of​(E e1, E e2)  
static <E> Set<E> of​(E e1, E e2, E e3)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

2. Simple Examples

Set is an interface. Therefore, to create a Set object you need to create through a class that implements it, such as HashSet, LinkedHashSet, TreeSet, and so on.
In the following example we create a HashSet object with an initial capacity of 10 elements, and the capacity will increase by 80% if its number of elements exceeds the current capacity.
SetEx1.java
package org.o7planning.set.ex;

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

public class SetEx1 {

    public static void main(String[] args) {
        Set<String> set = new HashSet<String>(10, (float) 0.8);

        set.add("One");
        set.add("Two");
        set.add("Three");
        
        Iterator<String> it1 = set.iterator();
        while (it1.hasNext()) {
            System.out.println(it1.next());
        }
        
        System.out.println(" ----- ");
        
        // When duplication occurs.
        // It will add new element and remove old element.
        set.add("Two");
        set.add("Four");

        Iterator<String> it2 = set.iterator();
        while (it2.hasNext()) {
            System.out.println(it2.next());
        }
    }
}
Note: Set is an unordered Collection, so you might get a slightly different result when printing elements to the Console.
Output:
One
Two
Three
 -----
One
Four
Two
Three
Array --> Set?
An example of converting an array into a Set object.
ArrayToSetEx.java
package org.o7planning.set.ex;

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

public class ArrayToSetEx {
    
    public static void main(String[] args) {
        Integer[] sourceArray = { 0, 3, 5, 3, 4, 5 };
        
        Set<Integer> targetSet = new HashSet<Integer>(Arrays.asList(sourceArray));
    
        for(Integer i : targetSet)  {
            System.out.println(i);
        }
    }  
}
Output:
0
3
4
5

3. stream()

Set is a subinterface of Collection so it inherits stream() method. Accessing elements of a Collection via Stream makes your code brief and easy to understand:
Set_stream.java
package org.o7planning.set.ex;

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

public class Set_stream {

    public static void main(String[] args) {  
        Set<String> set = new HashSet<String>();
        
        set.add("a1");
        set.add("b1");
        set.add("a2");  
        set.add("c1");  
        set.add("d1");  
        set.add("e1");  
        
        set.stream() //
              .map(String::toUpperCase) // to upsercase
              .filter(s -> !s.startsWith("A")) // Not starts with "A".
              .forEach(System.out::println);  
    }  
}
Output:
E1
D1
C1
B1

4. iterator()

iterator() is a method inheriting from Collection, returning an Iterator object to iterate the elements of Collection.
Iterator<E> iterator()
Set_iterator.java
package org.o7planning.set.ex;

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

public class Set_iterator {

    public static void main(String[] args) {  
        Set<String> set = new HashSet<String>();
        
        set.add("a1");
        set.add("b1");
        set.add("a2");  
        
        Iterator<String> ite = set.iterator();
        
        while(ite.hasNext()) {
            System.out.println(ite.next());
        }
    }  
}
Output:
a1
a2
b1

5. How does Set check for duplication?

Set is a Collection that does not allow to contain duplicated elements. If you intentionally add a duplicated element to Set, this action will be ignored. So the question is, how does "Set" check for duplication?
SortedSet is a subinterface of Set. In this section, we only refer to pure Set (not SortedSet). The classes that represent a pure Set are HashSet, LinkedHashSet, CopyOnWriteArraySet, and EnumSet.
The way SortedSet checks for duplication is completely different from pure Set, and is covered in the following article:
HashSet / LinkedHashSet
HashSet (andLinkedHashSet) compares the hashcode of two elements, then compares the two elements directly via their equals method.
Take a look at the 2 examples HashSetDupTest1 & HashSetDupTest2 below to understand more about the above description.
HashSetDupTest1.java
package org.o7planning.set.test;

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

public class HashSetDupTest1 {

    public static class Student {
        private int studentId;
        private String studentName;
        
        public Student(int studentId, String studentName) {
            this.studentId = studentId;
            this.studentName = studentName;
        }
        public int getStudentId() {
            return studentId;
        }
        public String getStudentName() {
            return studentName;
        }
        @Override
        public boolean equals(Object other)  {
            if(other == null || !(other instanceof Student)) {
                return false;
            }
            Student o = (Student) other;
            return this.studentId == o.studentId;
        }
    }
    
    public static void main(String[] args) {
        Student s1 = new Student(1, "Tom");
        Student s2 = new Student(2, "Jerry");
        Student s3 = new Student(1, "Tom Cat"); // Same Id with s1.
        
        Set<Student> set = new HashSet<Student>();
        
        set.add(s1);
        set.add(s2);
        set.add(s3);

        for(Student s: set)  {
            System.out.printf("Student Id: %d / Name: %s (Hashcode: %s)\n", //
                    s.getStudentId(),s.getStudentName(),s.hashCode());
        }
    }
}
Output:
Student Id: 2 / Name: Jerry (Hashcode: 474675244)
Student Id: 1 / Name: Tom Cat (Hashcode: 932583850)
Student Id: 1 / Name: Tom (Hashcode: 1586600255)
Edit the above example by overriding the hashCode() method in the Student class:
HashSetDupTest2.java
package org.o7planning.set.test;

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

public class HashSetDupTest2 {

    public static class Student {
        private int studentId;
        private String studentName;
        
        public Student(int studentId, String studentName) {
            this.studentId = studentId;
            this.studentName = studentName;
        }
        public int getStudentId() {
            return studentId;
        }
        public String getStudentName() {
            return studentName;
        }
        @Override
        public boolean equals(Object other)  {
            if(other == null || !(other instanceof Student)) {
                return false;
            }
            Student o = (Student) other;
            return this.studentId == o.studentId;
        }
        @Override
        public int hashCode() { // -----> Override hashCode() method.
            return this.studentName.charAt(0);
        }
    }
    
    public static void main(String[] args) {
        Student s1 = new Student(1, "Tom");   // Hashcode: 84 ('T')
        Student s2 = new Student(1, "Tom Cat"); // Hashcode: 84 ('T')
        
        Student s3 = new Student(2, "Jerry"); // Hashcode: 74 ('J')
        
        Student s4 = new Student(4, "Daffy"); // Hashcode: 68 ('D')
        Student s5 = new Student(5, "Donald"); // Hashcode: 68 ('D')
        
        
        Set<Student> set = new HashSet<Student>();
        
        set.add(s1);
        set.add(s2); // a Duplication (Ignored!)
        set.add(s3);
        set.add(s4);  
        set.add(s5);  

        for(Student s: set)  {
            System.out.printf("Student Id: %d / Name: %s (Hashcode: %s)\n", //
                    s.getStudentId(),s.getStudentName(),s.hashCode());
        }
    }
}
Output:
Student Id: 1 / Name: Tom (Hashcode: 84)
Student Id: 4 / Name: Daffy (Hashcode: 68)
Student Id: 5 / Name: Donald (Hashcode: 68)
Student Id: 2 / Name: Jerry (Hashcode: 74)
CopyOnWriteArraySet
CopyOnWriteArraySet directly compares 2 elements via their equals method.
Take a look at the 2 examples CopyOnWriteArraySetDupTest1 & CopyOnWriteArraySetDupTest2 below to understand more about the above description.
CopyOnWriteArraySetDupTest1.java
package org.o7planning.set.test;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

public class CopyOnWriteArraySetDupTest1 {

    public static class Employee {
        private int empId;
        private String empName;
        
        public Employee(int empId, String empName) {
            this.empId = empId;
            this.empName = empName;
        }
        public int getEmpId() {
            return empId;
        }
        public String getEmpName() {
            return empName;
        }
        // Employee class uses equals(Object) method inherited from Object class.
    }
    
    public static void main(String[] args) {
        Employee s1 = new Employee(1, "Tom");    
        Employee s2 = new Employee(2, "Jerry");  
        Employee s3 = new Employee(1, "Tom Cat");  
        
        Set<Employee> set = new CopyOnWriteArraySet<Employee>();
        
        set.add(s1);
        set.add(s2);
        set.add(s3);  

        for(Employee s: set)  {
            System.out.printf("Emp Id: %d / Name: %s\n", //
                    s.getEmpId(),s.getEmpName());
        }
    }
}
Output:
Emp Id: 1 / Name: Tom
Emp Id: 2 / Name: Jerry
Emp Id: 1 / Name: Tom Cat
Edit the above example by overriding the equals(Object) method in the Employee class:
CopyOnWriteArraySetDupTest2.java
package org.o7planning.set.test;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

public class CopyOnWriteArraySetDupTest2 {

    public static class Employee {
        private int empId;
        private String empName;
        
        public Employee(int studentId, String studentName) {
            this.empId = studentId;
            this.empName = studentName;
        }
        public int getEmpId() {
            return empId;
        }
        public String getEmpName() {
            return empName;
        }
        @Override
        public boolean equals(Object other)  { // -----> Override equals() method.
            if(other == null || !(other instanceof Employee)) {
                return false;
            }
            Employee o = (Employee) other;
            return this.empId == o.empId;
        }
    }
    
    public static void main(String[] args) {
        Employee s1 = new Employee(1, "Tom");   
        Employee s2 = new Employee(2, "Jerry");  
        Employee s3 = new Employee(1, "Tom Cat");
        
        Set<Employee> set = new CopyOnWriteArraySet<Employee>();
        
        set.add(s1);
        set.add(s2);
        set.add(s3); // a Duplication.

        for(Employee s: set)  {
            System.out.printf("Emp Id: %d / Name: %s\n", //
                    s.getEmpId(),s.getEmpName());
        }
    }
}
Output:
Emp Id: 1 / Name: Tom
Emp Id: 2 / Name: Jerry

6. of(..)

The static method Set.of(..) returns a fixed-size Set object, the exception is thrown if the input parameters are duplicated. This Set object does not support optional methods: add, remove, set, and clear.
static <E> Set<E> of()  
static <E> Set<E> of​(E e1)  
static <E> Set<E> of​(E... elements)  
static <E> Set<E> of​(E e1, E e2)  
static <E> Set<E> of​(E e1, E e2, E e3)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
Set_of.java
package org.o7planning.set.ex;

import java.util.Iterator;
import java.util.Set;

public class Set_of {

    public static void main(String[] args) {
        Set<Integer> set = Set.of(1, 2, 5, 3, 7, 9, 0);

        Iterator<Integer> it2 = set.iterator();
        while (it2.hasNext()) {
            System.out.println(it2.next());
        }
    }
}
Note: Set is an unordered Collection, so you might get a slightly different result when printing elements to the Console.
Output:
2
3
5
7
9
0
1

7. spliterator()

Create a Spliterator object for traversing and partitioning the elements of Set.
default Spliterator<E> spliterator()
Spliterator is widely used for traversing and partitioning many different data sources such as Collection (List, Set, Queue), BaseStream, array.
  • Java Spliterator

8. toArray​(..)

toArray(..) method returns an array containing all the elements of Set.
Object[] toArray()  

<T> T[] toArray​(T[] a)

// Java 11, The default method, inherited from Collection.
default <T> T[] toArray​(IntFunction<T[]> generator)
Set_toArray.java
package org.o7planning.set.ex;

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

public class Set_toArray {

    public static void main(String[] args) {  
        Set<String> set = new HashSet<String>();
        
        set.add("a1");
        set.add("b1");
        set.add("a2");  
        
        String[] array = new String[set.size()];
        
        set.toArray(array);
        
        for(String s: array) {
            System.out.println(s);
        }
    }  
}
Output:
a1
a2
b1