Java Set Tutorial with Examples
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.
- Collection
- Queue
- List
- SortedSet
- NavigableSet
- TransferQueue
- BlockingQueue
- BlockingDeque
- Deque
The hierarchy of classes implements Set interface.
- HashSet
- LinkedHashSet
- TreeSet
- ConcurrentSkipListSet
- CopyOnWriteArraySet
- Spliterators
- EnumSet
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:
- Collection
- Stream
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
Java Collections Framework Tutorials
- Java PriorityBlockingQueue Tutorial with Examples
- Java Collections Framework Tutorial with Examples
- Java SortedSet Tutorial with Examples
- Java List Tutorial with Examples
- Java Iterator Tutorial with Examples
- Java NavigableSet Tutorial with Examples
- Java ListIterator Tutorial with Examples
- Java ArrayList Tutorial with Examples
- Java CopyOnWriteArrayList Tutorial with Examples
- Java LinkedList Tutorial with Examples
- Java Set Tutorial with Examples
- Java TreeSet Tutorial with Examples
- Java CopyOnWriteArraySet Tutorial with Examples
- Java Queue Tutorial with Examples
- Java Deque Tutorial with Examples
- Java IdentityHashMap Tutorial with Examples
- Java WeakHashMap Tutorial with Examples
- Java Map Tutorial with Examples
- Java SortedMap Tutorial with Examples
- Java NavigableMap Tutorial with Examples
- Java HashMap Tutorial with Examples
- Java TreeMap Tutorial with Examples
- Java PriorityQueue Tutorial with Examples
- Java BlockingQueue Tutorial with Examples
- Java ArrayBlockingQueue Tutorial with Examples
- Java TransferQueue Tutorial with Examples
Show More