1. 概述

在这个简短教程中,我们将讲解如何在Java中检查一个集合(Set)是否包含特定元素。

首先,我们将通过探索核心JDK的解决方案来启动。然后,我们将解释如何使用Apache Commons等外部库来实现相同的结果。

2. 使用核心JDK

Java提供了多种方便的方法来检查Set中是否包含给定的元素。让我们深入了解并看看如何在实践中使用它们。

2.1. Set#contains() 方法

顾名思义,这个方法检查Set是否包含给定的元素。 这是回答我们核心问题的最简单解决方案:

@Test
void givenASet_whenUsingContainsMethod_thenCheck() {
    assertThat(CITIES.contains("London")).isTrue();
    assertThat(CITIES.contains("Madrid")).isFalse();
}

通常情况下,contains()方法如果Set中存在给定元素会返回true,否则返回false

根据官方文档,只有当且仅当以下条件成立时,它才会返回true

object==null ? element==null : object.equals(element);

因此,在属于Set对象的类中实现equals()方法非常重要,这样可以自定义相等逻辑,考虑类字段的全部或部分。

总之,与其它方法相比,contains()方法提供了检查给定Set中是否存在元素的最简洁和直接的方式。

2.2. Collections#disjoint() 方法

Collections工具类提供了一个名为disjoint()的方法,我们可以用来检查Set是否包含给定元素。

此方法接受两个集合作为参数,如果它们没有共同的元素,则返回true

@Test
public void givenASet_whenUsingCollectionsDisjointMethod_thenCheck() {
    boolean isPresent = !Collections.disjoint(CITIES, Collections.singleton("Paris"));

    assertThat(isPresent).isTrue();
}

总的来说,我们创建了一个只包含给定字符串“Paris”的不可变Set。此外,我们使用了disjoint()方法和否定运算符来检查两个集合是否有共同的元素。

2.3. Stream#anyMatch() 方法

Stream API提供了anyMatch()方法,我们可以使用它来验证给定集合中的任何元素是否满足提供的 谓词

现在来看看它的用法:

class CheckIfPresentInSetUnitTest {
    private static final Set<String> CITIES = new HashSet<>();

    @BeforeAll
    static void setup() {
        CITIES.add("Paris");
        CITIES.add("London");
        CITIES.add("Tokyo");
        CITIES.add("Tamassint");
        CITIES.add("New york");
    }

    @Test
    void givenASet_whenUsingStreamAnyMatchMethod_thenCheck() {
        boolean isPresent = CITIES.stream()
          .anyMatch(city -> city.equals("London"));

        assertThat(isPresent).isTrue();
    }
}

如上所示,我们使用谓词city.equals("London")来检查流中是否存在等于“London”的城市。

2.4. Stream#filter() 方法

另一种解决方案是使用filter()方法。它返回一个新的流,其中包含满足指定条件的元素。

换句话说,它根据指定的条件过滤流:

@Test
void givenASet_whenUsingStreamFilterMethod_thenCheck() {
    long resultCount = CITIES.stream()
      .filter(city -> city.equals("Tamassint"))
      .count();

    assertThat(resultCount).isPositive();
}

如上所述,我们过滤Set,只保留等于“Tamassint”的元素,然后使用终止操作count()返回过滤后的元素数量。

3. 使用Apache Commons Collections

如果我们想检查给定元素是否存在于Set中,Apache Commons Collections库是另一个值得考虑的选项。首先,我们需要将其依赖项添加到pom.xml文件中:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version>
</dependency>

3.1. CollectionUtils#containsAny() 方法

CollectionUtils提供了一系列对集合进行常用操作的实用方法。这些方法之一是containsAny(Collection<?> coll1, Collection<?> coll2)这个方法如果第二个集合中的至少一个元素也存在于第一个集合中,则返回true

让我们来看看它的用法:

@Test
void givenASet_whenUsingCollectionUtilsContainsAnyMethod_thenCheck() {
    boolean isPresent = CollectionUtils.containsAny(CITIES, Collections.singleton("Paris"));

    assertThat(isPresent).isTrue();
}

同样地,我们创建了一个只包含一个元素“Paris”的单例Set。然后,我们使用containsAny()方法检查集合CITIES是否包含给定值“Paris”。

3.2. SetUtils#intersection() 方法

另一种选择是使用SetUtils工具类来解决这个问题。这个类提供了intersection(Set<? extends E> a, Set<? extends E> b)方法,它返回一个新的Set,包含指定两个Set中都存在的元素:

@Test
void givenASet_whenUsingSetUtilsIntersectionMethod_thenCheck() {
    Set<String> result = SetUtils.intersection(CITIES, Collections.singleton("Tamassint"));

    assertThat(result).isNotEmpty();
}

简而言之,这里的思路是通过检查CITIES与给定单例Set的交集是否不为空,来验证城市“Tamassint”是否在CITIES中。

4. 总结

在这篇短文中,我们深入探讨了如何在Java中检查Set中是否包含给定元素的细节。

首先,我们展示了使用现成的JDK方法。接着,我们演示了如何使用Apache Commons Collections库来达成同样的目标。

如往常一样,本文中使用的代码可以在GitHub上找到。