Java MultiSet Implementation using TreeMap
Last Updated :
28 Apr, 2025
MultiSet is a generalization of the concept of a set. Its main idea is to allow a member of a multiset to have zero, one, or more than one occurrence in the multiset. In MultiSet, we can delete one occurrence of a member as well as all the occurrences of a member of MultiSet. Java has Set interface which allows you to add and remove elements in O(log(n)) time where n is the number of distinct elements present in the set. Here Set does not allow multiple elements to be present, and for that reason, different languages provide an inbuilt option of multiset which allows the insertion and deletion of elements in O(log(n)) time and O(n) space. Java has provided Guava’s Multiset, in which the duplicate element will not be discarded.
Illustration:
Java
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
// Multiset of String
Multiset<Integer> multiset = HashMultiset.create();
// Adding elements to the set
multiset.add(1);
multiset.add(1);
System.out.println(multiset);
Below we show how TreeMap in java can be used to implement Multiset. We can create MultiSet in java using TreeMap which provides guaranteed log((n)) time cost for the get, put, remove, and contains key operations. We will use treemap, in which the key will be the element added in the multiset, and the value will represent the number of occurrences of that element in the multiset. There are two essential operations that need to be implemented in MultiSet: add and remove
add operation adds an element to the multiset while the remove operation delete the element from the multiset. Remove operation can also have two variations, one is removing all occurrences of the element while the other is removing only one occurrence of the element. Both variations of the delete operation have been taken care of in the implementation
Add Operation Implementation
i) First, we need to create a TreeMap, let's call it Map
TreeMap<Integer, Integer> map=new TreeMap<>();
// here key will be the element in the multiset,
// and value will be the number of occurrence
// of the element in the multiset
ii) For adding an element we need to consider two cases:
Case 1: If the element is already present in the multiset, in that case, the element is already present in the map as well. So we just increment the value of the corresponding element by 1.
map.put(key, map.get(key) + 1);
// increment key value by 1 indicating an extra
// occurrence of key has been added in the multiset
Case 2: If the element is not present in the multiset, in the case element will also be not present in the map as well. So we have to add the element in the map using the put method.
map.put(key, 1);
// put method add key in the map, value 1 indicates
// that only one occurrence of key is present
// in the multiset.
The time complexity of the put() and get() method in TreeMap is O(log(n)) where n is the number of key values, hence the time complexity to perform add operation is O(log(n)).
Delete Operation Implementation
Deleting only one occurrence of the element:
i) For removing only one occurrence of the element we again use the put and get method
map.put(key, map.get(key)-1);
// decrease the occurrence of key by 1 indication
// the removal of key from multiset by 1
ii) For removing all occurrences of the element we can use the remove method of the treemap.
map.remove(key);
// remove the key from multiset
The time complexity of the remove() method in TreeMap is O(log(n)), hence the complexity to perform the deletion operation is also O(log(n)). We can also get the total number of occurrences of a particular element just by using the get(element) method of TreeMap,
int count(int a)
{ // count occurrence of a
return map.getOrDefault(a, 0);
}
For knowing the size of the multiset we can create a global variable size, when adding size we decrement size, and while deleting we decrement size.
Ceiling Operation
we can find the smallest element greater than or equal to a particular element key by using the ceiling() method of treemap which has the time complexity of O(log(n)).
int ceiling(int a)
{
// finds smallest element
// greater than or equal to a
if (map.ceilingKey(a) != null) {
int find = map.ceilingKey(a);
return find;
}
else return Integer.MIN_VALUE;
}
floor Operation:
we can find the largest element smaller than or equal to a particular element key by using the floor() method of treemap which has the time complexity of O(log(n)).
int floor(int a)
{
// finds largest element less
// than or equal to a
if (map.floorKey(a) != null) {
int find = map.floorKey(a);
return find;
} else return Integer.MAX_VALUE;
}
lower operation:
we can find the largest element smaller than a particular element key by using the lower() method of treemap which has the time complexity of O(log(n)).
int lower(int a)
{
// finds largest element smaller than a
if (map.lowerKey(a) != null) {
int find = map.lowerKey(a);
return find;
} else return Integer.MAX_VALUE;
}
higher operation:
finds the smallest element larger than a particular element key by using the higher() method of treemap which has the time complexity of O(log(n)).
int higher(int a)
{
// finds smallest element greater than a
if (map.higherKey(a) != null) {
int find = map.higherKey(a);
return find;
}else return Integer.MIN_VALUE;
}
The total space complexity to implement a multiset using treemap is O(n) for storing the key-value pairs. The complete implementation of the above operation described has been provided below:
Java
/*package whatever // do not write package name here */
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG {
public static class MultiSet {
public TreeMap<Integer, Integer> map;
public int size = 0;
public MultiSet()
{ // constructor for empty multiset
map = new TreeMap<>();
size = 0;
}
public MultiSet(int[] a)
{ // constructor to create a multiset with array
map = new TreeMap<>();
size = a.length;
for (int i = 0; i < a.length; i++) {
map.put(a[i],
map.getOrDefault(a[i], 0) + 1);
}
}
void add(int a)
{ // add element in multiset
size++;
map.put(a, map.getOrDefault(a, 0) + 1);
}
void remove(int a)
{ // remove element from multiset
size -= map.getOrDefault(a, 0);
map.remove(a);
}
int count(int a)
{ // count occurrence of a
return map.getOrDefault(a, 0);
}
int ceiling(int a)
{ // finds smallest element greater than or equal to
// a
if (map.ceilingKey(a) != null) {
int find = map.ceilingKey(a);
return find;
}
else
return Integer.MIN_VALUE;
}
int floor(int a)
{ // finds largest element less than or equal to a
if (map.floorKey(a) != null) {
int find = map.floorKey(a);
return find;
}
else
return Integer.MAX_VALUE;
}
int lower(int a)
{ // finds largest element smaller than a
if (map.lowerKey(a) != null) {
int find = map.lowerKey(a);
return find;
}
else
return Integer.MAX_VALUE;
}
int higher(int a)
{ // finds smallest element greater than a
if (map.higherKey(a) != null) {
int find = map.higherKey(a);
return find;
}
else
return Integer.MIN_VALUE;
}
int first()
{ // return smallest element in multiset
return map.firstKey();
}
int last()
{ // return largest element in multiset
return map.lastKey();
}
boolean contains(int a)
{
if (map.containsKey(a))
return true;
return false;
}
int size() { return size; }
void clear() { map.clear(); }
}
public static void main(String[] args)
{
MultiSet ms = new MultiSet();
ms.add(1);
ms.add(2);
ms.add(3);
ms.add(2);
ms.add(3);
ms.add(3);
ms.add(3);
System.out.println("Occurrence of 1 is "
+ ms.count(1));
System.out.println("Occurrence of 2 is "
+ ms.count(2));
System.out.println("Occurrence of 3 is "
+ ms.count(3));
System.out.println(
"First element greater than 2 is "
+ ms.higher(2));
}
}
Output:
Occurrence of 1 is 1
Occurrence of 2 is 2
Occurrence of 3 is 4
First element greater than 2 is 3
In the above code, you can also find the floor, ceiling, and higher in O(log(n)) time.
Similar Reads
Java Program to Implement TreeMap API The TreeMap is used to implement Map interface and NavigableMap along with the AbstractMap class in java. The map is sorted by the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used. Now, in implementing TreeMap API, the task is div
6 min read
How to Create TreeMap Objects using Comparable Interface in Java? In Java, the TreeMap class is an implementation of the SortedMap interface that stores key-value pairs in a sorted order based on the natural ordering of the keys. By default, the keys are sorted in ascending order. If you want to sort the keys based on a custom ordering criteria, you can use the Co
6 min read
Java Program to Implement TreeSet API TreeSet is one of the most important implementations of the SortedSet interface in Java that uses a Tree for storage. The ordering of the elements is maintained by a set using their natural ordering whether an explicit comparator is provided. This must be consistent with equals if it is to correctly
10 min read
Internal Working of TreeMap in Java TreeMap class is like HashMap. TreeMap stores key-value pairs. The main difference is that TreeMap sorts the key in ascending order. TreeMap is sorted as the ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used. Pre-requisite: Let's go throug
5 min read
How to Get TreeMap Key or Value using Index in Java? The TreeMap in Java is used to implement the Map interface and NavigableMap along with the AbstractMap Class. The TreeMap is sorted according to the natural ordering of its keys. The TreeMap class is a Red-Black tree implementation of the Map interface and thus does not expose any methods using whic
5 min read
Getting Synchronized Map from Java TreeMap TreeMap is a part of the Java Collections framework. Java TreeMap contains values based on the key. It implements the NavigableMap interface and extends AbstractMap class. It provides an efficient means of storing key-value pairs in sorted order. Java TreeMap contains only unique elements. It cannot
2 min read
Creating Subsets and Headsets from TreeMap with Java A Java TreeMap is a sorted collection that is a component of the Java Collections Framework. Subsets are parts of the map, and headsets are made up of items that are less than or equal to a specified key. In this article, we will learn how to create subsets and headsets from a TreeMap based on speci
3 min read
How to Merge Two TreeMaps in Java? In Java, TreeMap is a pre-defined class that implements the NavigableMap interface and extends the AbstractMap class. In this article, we will learn to Merge Two Tree Maps in Java. Program to Merge Two TreeMaps in JavaWe are using the putAll method is inherited from the AbstractMap class in this man
2 min read
How to Create a TreeSet with a List in Java? TreeSet is an implementation of the SortedSet interface in Java that uses a Tree for storage. TreeSet can be created from List by passing the List to the TreeSet constructor in Java or we can traverse complete List and adding each element of the List to the TreeSet. Example: Input : List = [a, b, c]
3 min read
How to Sort a TreeMap By Value in Java? In Java Language, a TreeMap always stores key-value pairs which are in sorted order on the basis of the key. TreeMap implements the NavigableMap interface and extends AbstractMap class. TreeMap contains unique keys. Sorting TreeMap by value in Java The elements in TreeMap are sorted on the basis of
3 min read