Гуава - Наборы

Гуава - Наборы

1. обзор

В этом руководстве мы проиллюстрируем наиболее полезные способыleverage Guava to work with Java Sets.

Давайте начнем очень просто иcreate a HashSet без оператора new, используя Guava:

Set aNewSet = Sets.newHashSet();

2. Союз Сетов

Во-первых, давайте посмотрим, как мы можемdo a union operation over Sets - используя простой APISets.union():

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

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

3. Декартово произведение множеств

Мы также можем получитьthe product of two sets, используяSets.cartesianProduct(), как в следующем примере:

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

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

Обратите внимание: чтобы легко проверить результат, мы используемFunction иJoiner, чтобы преобразовать сложную структуруSet<List<Character>> в более управляемуюIterable<String>.

4. Sets Пересечение

Далее - давайте посмотрим, как получитьthe intersection between two sets - используя APISets.intersection():

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

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

5. Симметричная разность множеств

Теперь давайте посмотрим на симметричное различие двух наборов - всех элементов, которые содержатся в наборе 1 или наборе 2, но не в обоих:

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

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

6. Набор питания

Теперь - давайте посмотрим, как вычислитьthe power set – the set of all possible subsets этого набора.

В следующем примере - мы используемSets.powerSet() для вычисления набора мощности данного набора символов:

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

    Set> result = Sets.powerSet(chars);

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

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

7. ContiguousSetс

Далее - давайте посмотрим на отсортированный набор смежных значений -ContiguousSet.

В следующем примере - мы получаем набор целых чисел [10, 11,…, 30] вContiguousSet:

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

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

Этот тип структуры данных, конечно, можно сделать в простой Java сTreeSet, но сthe semantics of this specialized type of set are just much more nicer можно работать, если вам нужно, чтобы ваши данные были представлены таким образом.

8. RangeSetс

А теперь давайте посмотрим наRangeSet. Мы можем использоватьRangeSet для хранения отключенных и непустых диапазонов.

В следующем примере - когда начинаем с 2 отключенных диапазонов, а затем соединяем их в один большой диапазон:

@Test
public void whenUsingRangeSet_thenCorrect() {
    RangeSet 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());
}

Давайте подробно рассмотрим этот пример: **

  • Сначала - вставляем 2 отключенных диапазона:[1, 10] и[12, 15]

  • Далее - добавляем третий диапазон для подключения существующих 2:[10, 12]

  • Наконец, мы проверяем, чтоRangeSet был достаточно умен, чтобы увидеть, что 3 диапазона теперь являются одним большим диапазоном, и объединяем их вместе в:[1, 15]

9. MultiSetс

Далее - давайте обсудим, как использоватьMultiset. В отличие от обычных наборовa Multiset does support adding duplicate elements – which it counts as occurrences.

В следующем примере мы рассмотрим простую многосетевую логику:

@Test
public void whenInsertDuplicatesInMultiSet_thenInserted() {
    Multiset 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. Получить N лучших элементов заMultiSet

А теперь давайте посмотрим более сложный и полезный пример использованияMultiSet. Мы получим N самых встречающихся элементов в наборе - в основном, самые распространенные.

В следующем примере мы сортируем элементы вMultiset, используяMultisets.copyHighCountFirst():

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

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

11. Заключение

В этом кратком руководстве мы обсудили наиболее распространенные и полезные варианты использованияworking with Sets using the Guava library.

Реализация всех этих примеров и фрагментов кодаcan be found in my Guava github project - это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.