Multiset Interface by Guava in Java
A Multiset is a collection that is similar to Set, but it may have duplicate elements. The duplicate elements are supported by maintaining a count of the total number of times an element appears in the collection. This post will cover Multiset interface provided by the Guava library in Java.
Since JDK doesn’t provide any implementation of the Multiset, programmers often switch to HashMap to store element-count pairs in Java. We have already seen how to implement Multiset class in Java using a List interface. Several third-party libraries also offer the Multiset implementation, such as Guava and Apache Commons Collections. This post will discuss common utility methods provided by Guava’s Multiset interface:
1. Using add() and contains() methods
We know that if two equal elements are added to java.util.Set, the second element will be discarded. The Guava Multiset, on the other hand, can store the duplicates. Any subsequent calls to the add() method for the same value will not be discarded. The following example demonstrates the usage of the add(), addAll(), contains(), and containsAll() methods provided by Guava’s Multiset interface.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; import java.util.Arrays; class Main { public static void main(String[] args) { // Create a new, empty `HashMultiset` instance Multiset<String> multiset = HashMultiset.create(); // Add a single occurrence of "David" to the `HashMultiset` multiset.add("David"); // Add four occurrences of "Smith" to the `HashMultiset` multiset.add("Smith", 4); // addAll() method is inherited from `java.util.Collection` interface multiset.addAll(Arrays.asList("John", "John")); // print the multiset System.out.println(multiset); // [Smith x 4, David, John x 2] // Determine whether multiset contains "David" System.out.println(multiset.contains("David")); // true // Determine whether the multiset contains at least one occurrence of each // element in the specified list System.out.println(multiset.containsAll(Arrays.asList("David", "Tom"))); // false } } |
The above code creates a Multiset instance using the HashMultiset implementation of Multiset, which is backed by a HashMap. There are several other implementations provided by Guava, such as TreeMultiset, LinkedHashMultiset, ConcurrentHashMultiset, ImmutableMultiset, or ImmutableSortedMultiset.
2. Removing values from the Multiset
The Guava Multiset provides the remove(Object) method that removes a single occurrence of the specified element from the multiset. It also has the removeAll(Object, int) method that removes a specified number of occurrences of the specified element from the multiset. The following example demonstrates the use of these methods:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; import java.util.Arrays; class Main { public static void main(String[] args) { Multiset<String> multiset = HashMultiset.create(); multiset.add("Zachary"); multiset.add("Tom", 3); multiset.add("Peter", 4); multiset.add("David", 2); // [Tom x 3, Zachary, David x 2, Peter x 4] System.out.println("Before: " + multiset); // Removes a single occurrence of "Tom" from this multiset multiset.remove("Tom"); // Removes all occurrences of "David" and "Peter" from this multiset multiset.removeAll(Arrays.asList("David", "Peter")); // removeIf method is inherited from the `java.util.Collection` interface multiset.removeIf(s -> s.startsWith("Z")); System.out.println("After : " + multiset); // [Tom x 2] } } |
3. Iterating over the Multiset
Multiset provides two collection views: elementSet() and entrySet(). The elementSet() method returns the distinct elements in the Multiset. The entrySet() method returns the Multiset.Entry instances that has both distinct elements and their count. We can also use elementSet().size() to know the number of unique elements in the multiset. The following example demonstrates the usage of the elementSet() and entrySet() methods:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import com.google.common.collect.HashMultiset; import com.google.common.collect.Multiset; import java.util.Arrays; class Main { public static<E> void iterateWithEntrySet(Multiset<E> multiset) { for (Multiset.Entry<E> e: multiset.entrySet()) { System.out.println(e.getElement() + " occurs " + e.getCount() + " times"); } } public static<E> void iterateWithElementSet(Multiset<E> multiset) { for (E e: multiset.elementSet()) { System.out.println(e + " occurs " + multiset.count(e) + " times"); } } public static void main(String[] args) { Multiset<String> multiset = HashMultiset.create(); multiset.add("David"); multiset.add("Smith", 4); multiset.add("John", 2); System.out.println(multiset); // [Smith x 4, David, John x 2] // Iterate over the Multiset using entrySet() method iterateWithEntrySet(multiset); // Smith occurs 4 times // David occurs 1 times // John occurs 2 times // Iterate over the Multiset using elementSet() method iterateWithElementSet(multiset); // Smith occurs 4 times // David occurs 1 times // John occurs 2 times } } |
4. Immutable Multiset in Guava
An Immutable Multiset is a type of Multiset that does not allow modifications to its elements. The Guava Multiset interface has two immutable implementations: ImmutableMultiset and ImmutableSortedMultiset, which can be used over the mutable implementations if needed. We can easily create an ImmutableMultiset using a builder. For example, we can use something like this:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import com.google.common.collect.ImmutableMultiset; import com.google.common.collect.Multiset; class Main { public static void main(String[] args) { Multiset<String> multiset = ImmutableMultiset.<String>builder() .add("Zachary", "Grover") .addCopies("Tom", 3) .addCopies("David", 2) .build(); System.out.println(multiset); // [Zachary, Grover, Tom x 3, David x 2] try { // this will fail since the set is immutable multiset.add("Obama"); } catch (UnsupportedOperationException ex) { System.out.print("java.lang.UnsupportedOperationException thrown"); } } } |
That’s all about Multiset Interface by Guava in Java.
Reference: Multiset (Guava: Google Core Libraries for Java 31.0-jre API)
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)