Apache Commons Collections SetUtils – Apache Commons Collections SetUtils

最后修改: 2017年 6月 28日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this article, we’ll be exploring the SetUtils API of Apache Commons Collections library. Simply put, these utilities can be used to execute certain operations on Set data structures in Java.

在这篇文章中,我们将探讨Apache Commons集合库的SetUtils API。简单地说,这些工具可以用来在Java中对Set数据结构执行某些操作。

2. Dependency Installation

2.依赖性安装

In order for us to use the SetUtils library in our project, we need to add the following dependency to our project’s pom.xml file:

为了让我们在项目中使用SetUtils库,我们需要在项目的pom.xml文件中添加以下依赖。

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

Alternatively, if our project is Gradle-based, we should add the dependency to our project’s build.gradle file. Also, we need to add mavenCentral() to the repositories section of the build.gradle file:

或者,如果我们的项目是基于Gradle的,我们应该将该依赖性添加到项目的build.gradle文件中。此外,我们还需要在build.gradle文件的资源库部分添加mavenCentral()

compile 'org.apache.commons:commons-collections4:4.1'

3. Predicated Set

3.预设集

The predicatedSet() method of the SetUtils library permits defining conditions that should be met by all elements that are to be inserted into a set. It accepts a source Set object and a predicate.

SetUtils库的predicatedSet()方法允许定义所有要插入集合的元素应该满足的条件。它接受一个源Set对象和一个谓词。

We can use this to easily validate that all elements of a Set satisfy a certain condition, which can be handy when developing a third-party library/API.

我们可以用它来轻松验证Set中的所有元素是否满足某个条件,这在开发第三方库/API时非常方便。

If the validation fails for any element, an IllegalArgumentException will be thrown. The snippet below prevents the addition of strings that do not start with ‘L’ into the sourceSet or the returned validatingSet:

如果任何元素的验证失败,将抛出一个IllegalArgumentException。下面的代码段防止在sourceSet或返回的validatingSet中添加非’L’开头的字符串。

Set<String> validatingSet
  = SetUtils.predicatedSet(sourceSet, s -> s.startsWith("L"));

The library also has predicatedSortedSet() and predicatedNavigableSet() for working with SortedSet and NavigableSet respectively.

该库还有predicatedSortedSet()predicatedNavigableSet()分别用于处理SortedSetNavigableSet

4. Union, Difference, and Intersection of a Set

4.集合的并集、差集和交集

The library has methods that can compute union, difference, and the intersection of Set elements.

该库有一些方法可以计算Set元素的联合、差异和相交。

The difference() method takes two Set objects and returns an immutable SetUtils.SetView object. The returned SetUtils.SetView contains the elements that are in set a but not in set b:

difference() 方法接收两个Set对象,并返回一个不可变的SetUtils.SetView对象。返回的SetUtils.SetView包含在集合a中但不在集合b的元素。

Set<Integer> a = new HashSet<>(Arrays.asList(1, 2, 5));
Set<Integer> b = new HashSet<>(Arrays.asList(1, 2));
SetUtils.SetView<Integer> result = SetUtils.difference(a, b);
 
assertTrue(result.size() == 1 && result.contains(5));

Note that, trying to perform write operations, like add() or addAll(), on the returned SetUtils.SetView will throw an UnsupportedOperationException.

请注意,在返回的SetUtils.SetView上执行写操作,如add()addAll(),将抛出UnsupportedOperationException

To modify the returned result, we need to call the toSet() method of the returned SetUtils.SetView to obtain a writable Set object:

要修改返回的结果,我们需要调用返回的SetUtils.SetViewtoSet()方法,以获得一个可写的Set对象。

Set<Integer> mutableSet = result.toSet();

The union method of the SetUtils library does exactly what it sounds like – it returns all the elements of set a and b. The union method also returns a SetUtil.SetView object that is immutable:

SetUtils库的union方法所做的和它听起来一样 – 它返回集合ab的所有元素。union方法还返回一个SetUtil.SetView对象,它是不可改变的。

Set<Integer> expected = new HashSet<>(Arrays.asList(1, 2, 5));
SetUtils.SetView<Integer> union = SetUtils.union(a, b);
 
assertTrue(SetUtils.isEqualSet(expected, union));

Take note of the isEqualSet() method used in the assert statement. It is a convenient static method of SetUtils library that effectively checks if two sets are equal.

注意assert语句中使用的isEqualSet()方法。它是SetUtils library的一个方便的静态方法,可以有效地检查两个集合是否相等。

To get the intersection of a set, i.e. elements that are both present in set a and set b, we’ll use the SetUtils.intersection() method. This method also returns a SetUtil.SetView object:

为了得到一个集合的交集,即同时存在于集合a和集合b中的元素,我们将使用SetUtils.intersection()方法。这个方法也会返回一个SetUtil.SetView对象。

Set<Integer> expected = new HashSet<>(Arrays.asList(1, 2));
SetUtils.SetView<Integer> intersect = SetUtils.intersection(a, b);
 
assertTrue(SetUtils.isEqualSet(expected, intersect));

5. Transforming Set Elements

5.转化集合元素

Let’s take a look at another exciting method – SetUtils.transformedSet(). This method accepts a Set object and a Transformer interface. Backed by the source set, it uses the transform() method of the Transformer interface to transform every element of a set.

让我们来看看另一个令人兴奋的方法–SetUtils.transformedSet()。这个方法接受一个Set对象和一个Transformer接口。在源集合的支持下,它使用Transformer接口的transform()方法来转换一个集合的每个元素。

The transforming logic is defined in the transform() method of the Transformer interface, which is applied to every element added to the set. The code snippet below multiplies every element added to the set by 2:

转换逻辑在Transformer接口的transform()方法中定义,它被应用于添加到集合的每个元素。下面的代码片段将添加到集合中的每个元素乘以2。

Set<Integer> a = SetUtils.transformedSet(new HashSet<>(), e -> e * 2  );
a.add(2);
 
assertEquals(a.toArray()[0], 4);

The transformedSet() method is pretty handy – they can even be used to cast elements of a set – say from String to Integer. Just make sure that the type of the output is a subtype of the input.

transformedSet()方法是非常方便的–它们甚至可以用来铸造一个集合的元素–比如从String到Integer。只要确保输出的类型是输入的一个子类型。

Let’s say we are working with SortedSet or NavigableSet instead of HashSet, we can use the transformedSortedSet() or transformedNavigableSet() respectively.

假设我们正在使用SortedSetNavigableSet而不是HashSet,我们可以分别使用transformedSortedSet()transformedNavigableSet()

Note that a new HashSet instance is passed to the transformedSet() method. In situations where an existing, non-empty Set is passed to the method, the pre-existing elements will not be transformed.

请注意,一个新的HashSet实例被传递给transformedSet()方法。在现有的、非空的Set被传递给该方法的情况下,预先存在的元素将不会被转换。

If we want to transform pre-existing elements (and those added thereafter), we need to use the transformedSet() method of org.apache.commons.collections4.set.TransformedSet:

如果我们想转换预先存在的元素(以及之后添加的元素),我们需要使用org.apache.commons.collection4.set.TransformedSettransformedSet()方法。

Set<Integer> source = new HashSet<>(Arrays.asList(1));
Set<Integer> newSet = TransformedSet.transformedSet(source, e -> e * 2);
 
assertEquals(newSet.toArray()[0], 2);
assertEquals(source.toArray()[0], 2);

Note that elements from the source set are transformed and the result is copied to the returned newSet.

注意,源集合中的元素被转换,结果被复制到返回的newSet.中。

6. Set Disjunction

6.集合离合

The SetUtils library provides a static method that can be used to find set disjunctions. The disjunction of set a and set b are all the elements that are unique to set a and set b.

SetUtils库提供了一个静态方法,可以用来寻找集合的不连接。集合a和集合b的二择一是指集合a和集合b所特有的所有元素。

Let’s see how to use the disjunction() method of the SetUtils library:

我们来看看如何使用SetUtils库的disjunction()方法。

Set<Integer> a = new HashSet<>(Arrays.asList(1, 2, 5));
Set<Integer> b = new HashSet<>(Arrays.asList(1, 2, 3));
SetUtils.SetView<Integer> result = SetUtils.disjunction(a, b);
 
assertTrue(
  result.toSet().contains(5) && result.toSet().contains(3));

7. Other Methods in SetUtils Library

7、SetUtils库中的其他方法

There are other methods in the SetUtils library that make processing of set data a breeze:

SetUtils库中还有其他方法,使处理集合数据变得轻而易举。

  • We can use the synchronizedSet() or synchronizedSortedSet() to get a thread-safe Set. However, as stated in the docs, we must manually synchronize the returned set’s iterator to avoid non-deterministic behavior
  • We can use the SetUtils.unmodifiableSet() to get a read-only set. Note that an attempt to add elements to the returned Set Object will throw an UnsupportedOperationException
  • There is also the SetUtils.emptySet() method that returns a type-safe, immutable empty set
  • The SetUtils.emptyIfNull() method accepts a nullable Set object. It returns an empty, read-only, Set if the supplied Set is null; otherwise, it returns the supplied Set
  • SetUtils.orderedSet() will return a Set object that maintains the order in which elements are added
  • SetUtils.hashCodeForSet() can generate a hashcode for a set – in such a way that two sets of the same elements will have the same hashcode
  • SetUtils.newIdentityHashSet() will return a HashSet that uses == to match an element instead of the equals() method. Please read about its caveats here

8. Conclusion

8.结语

In this article, we’ve explored the nitty-gritty of the SetUtils library. The utility class offers static methods that make working with a set data structure easy and exciting. It also boosts productivity.

在这篇文章中,我们已经探讨了SetUtils库的细枝末节。这个实用类提供了静态方法,使使用集合数据结构的工作变得简单而令人兴奋。它也提高了生产力。

As always, code snippets are available over on GitHub. The official doc for the SetUtils API can be found here.

像往常一样,代码片段可在GitHub上找到。SetUtilsAPI的官方文档可以在这里找到

Next »

Apache Commons Collections OrderedMap

« Previous

Apache Commons Collections Bag