If you have a few years of experience in the Java ecosystem, and you're interested in sharing that experience with the community (and getting paid for your work of course), have a look at the "Write for Us" page. Cheers. Eugen

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll illustrate the most useful ways you can leverage Guava to work with Java Sets.

Let’s start very simple and create a HashSet without the new operator, using Guava:

Set<String> aNewSet = Sets.newHashSet();

2. Union of Sets

First, let’s take a look at how we can do a union operation over Sets – using the simple Sets.union() API:

@Test
public void whenCalculatingUnionOfSets_thenCorrect() {
    Set<Character> first = ImmutableSet.of('a', 'b', 'c');
    Set<Character> second = ImmutableSet.of('b', 'c', 'd');

    Set<Character> union = Sets.union(first, second);
    assertThat(union, containsInAnyOrder('a', 'b', 'c', 'd'));
}

3. Cartesian Product of Sets

We can also get the product of two sets using Sets.cartesianProduct() as in the following example:

@Test
public void whenCalculatingCartesianProductOfSets_thenCorrect() {
    Set<Character> first = ImmutableSet.of('a', 'b');
    Set<Character> second = ImmutableSet.of('c', 'd');
    Set<List<Character>> result =
      Sets.cartesianProduct(ImmutableList.of(first, second));

    Function<List<Character>, String> func =
      new Function<List<Character>, String>() {
        public String apply(List<Character> input) {
            return Joiner.on(" ").join(input);
        }
    };
    Iterable<String> joined = Iterables.transform(result, func);
    assertThat(joined, containsInAnyOrder("a c", "a d", "b c", "b d"));
}

Note that – to be able to test out the result easily, we are using a Function and a Joiner to convert the complex Set<List<Character>> structure into a more manageable Iterable<String>.

4. Sets Intersection

Next – let’s see how to get the intersection between two sets – using the Sets.intersection() API:

@Test
public void whenCalculatingSetIntersection_thenCorrect() {
    Set<Character> first = ImmutableSet.of('a', 'b', 'c');
    Set<Character> second = ImmutableSet.of('b', 'c', 'd');

    Set<Character> intersection = Sets.intersection(first, second);
    assertThat(intersection, containsInAnyOrder('b', 'c'));
}

5. Symmetric Difference of Sets

Now, let’s have a look at the symmetric difference of two sets – all elements that are contained in either set 1 or set 2 but not in both:

@Test
public void whenCalculatingSetSymmetricDifference_thenCorrect() {
    Set<Character> first = ImmutableSet.of('a', 'b', 'c');
    Set<Character> second = ImmutableSet.of('b', 'c', 'd');

    Set<Character> intersection = Sets.symmetricDifference(first, second);
    assertThat(intersection, containsInAnyOrder('a', 'd'));
}

6. Power Set

Now – Let’s see how to calculate the power set – the set of all possible subsets of that set.

In the following example – we use Sets.powerSet() to calculate the power set of a given set of characters:

@Test
public void whenCalculatingPowerSet_thenCorrect() {
    Set<Character> chars = ImmutableSet.of('a', 'b');

    Set<Set<Character>> result = Sets.powerSet(chars);

    Set<Character> empty =  ImmutableSet.<Character> builder().build();
    Set<Character> a = ImmutableSet.of('a');
    Set<Character> b = ImmutableSet.of('b');
    Set<Character> aB = ImmutableSet.of('a', 'b');

    assertThat(result, contains(empty, a, b, aB));
}

7. ContiguousSet

Next – Let’s take a look at a sorted set of contiguous values – the ContiguousSet.

In the following example – we get a set of integers [10, 11, …, 30] into a ContiguousSet:

@Test
public void whenCreatingRangeOfIntegersSet_thenCreated() {
    int start = 10;
    int end = 30;
    ContiguousSet<Integer> set = ContiguousSet.create(
      Range.closed(start, end), DiscreteDomain.integers());

    assertEquals(21, set.size());
    assertEquals(10, set.first().intValue());
    assertEquals(30, set.last().intValue());
}

This type of data structure is of course something you can do in plain Java with a TreeSet – but the semantics of this specialized type of set are just much more nicer to work with if you need your data represented this way.

8. RangeSet

Now – let’s take a look at RangeSet. We can use RangeSet to hold disconnected and nonempty ranges.

In the following example – when start with 2 disconnected ranges and then we connect them into a single, large range:

@Test
public void whenUsingRangeSet_thenCorrect() {
    RangeSet<Integer> rangeSet = TreeRangeSet.create();
    rangeSet.add(Range.closed(1, 10));
    rangeSet.add(Range.closed(12, 15));

    assertEquals(2, rangeSet.asRanges().size());

    rangeSet.add(Range.closed(10, 12));
    assertTrue(rangeSet.encloses(Range.closed(1, 15)));
    assertEquals(1, rangeSet.asRanges().size());
}

Let’s go over this example in detail:

  • First – we insert the 2 disconnected ranges: [1, 10] and [12, 15]
  • Next – we add a third range to connect the existing 2: [10, 12]
  • Finally – we verify that the RangeSet was smart enough to see that the 3 ranges are now one large range, and merge them together into: [1, 15]

9. MultiSet

Next – let’s discuss how to use Multiset. As opposed to normal sets, a Multiset does support adding duplicate elements – which it counts as occurrences.

In the following example – we go through some simple multi-set logic:

@Test
public void whenInsertDuplicatesInMultiSet_thenInserted() {
    Multiset<String> names = HashMultiset.create();
    names.add("John");
    names.add("Adam", 3);
    names.add("John");

    assertEquals(2, names.count("John"));
    names.remove("John");
    assertEquals(1, names.count("John"));

    assertEquals(3, names.count("Adam"));
    names.remove("Adam", 2);
    assertEquals(1, names.count("Adam"));
}

10. Get Top N Elements in a MultiSet

Now – let’s see a more complex and useful example of using a MultiSet. We’ll get the Top N occurring elements in the set – basically, the most common ones.

In the following example – we sort the elements in the Multiset using Multisets.copyHighCountFirst():

@Test
public void whenGetTopOcurringElementsWithMultiSet_thenCorrect() {
    Multiset<String> names = HashMultiset.create();
    names.add("John");
    names.add("Adam", 5);
    names.add("Jane");
    names.add("Tom", 2);

    Set<String> sorted = Multisets.copyHighestCountFirst(names).elementSet();
    List<String> sortedAsList = Lists.newArrayList(sorted);
    assertEquals("Adam", sortedAsList.get(0));
    assertEquals("Tom", sortedAsList.get(1));
}

11. Conclusion

In this quick tutorial we discussed the most common and useful usecases of working with Sets using the Guava library.

The implementation of all these examples and code snippets can be found in my Guava github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS

newest oldest most voted
Notify of
youmoo
Guest

There is also a useful `com.google.common.collect.Sets#symmetricDifference` method which is used to find uncommon elements.

Eugen Paraschiv
Guest

That’s cool – thanks for letting me know. I updated the article with the new operation. Cheers,
Eugen.

Harihar Das
Guest
Harihar Das

Most of the recent articles are pretty standard stuff. These are already available in multiple places over the internet. Why write them again?

Eugen Paraschiv
Guest

Hey Harihar – that’s an interesting question. There are a few reasons I publish foundational topics sometimes – here’s just a few. First – it’s because I believe they’re done better on Baeldung. And second, because these are usually the start of a series – and I don’t want to jump straight into an advanced topic without having written about the basics of that topic first. Cheers,
Eugen.

Cássio Paixão
Guest
Cássio Paixão

I’m from Brazil and follow your articles, very good!
congratulations

Eugen Paraschiv
Guest

Glad you’re enjoying the site Cassio.
Cheers,
Eugen.