Apache Commons集合SetUtils

1.概述

在本文中,我們將探索Apache Commons Collections庫的SetUtils API。簡而言之,這些實用程序可用於在Java中對Set數據結構執行某些操作。

2.依賴安裝

為了使我們在項目中使用SetUtils庫,我們需要在項目的pom.xml文件中添加以下依賴項:

<dependency>

 <groupId>org.apache.commons</groupId>

 <artifactId>commons-collections4</artifactId>

 <version>4.1</version>

 </dependency>

或者,如果我們的項目基於Gradle,則應將依賴項添加到項目的build.gradle文件中。另外,我們需要將mavenCentral()添加到build.gradle文件的存儲庫部分:

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

3. Predicated Set

SetUtils庫的predicatedSet()方法允許定義要插入到集合中的所有元素應滿足的條件。它接受源Set對象和predicate。

我們可以使用它輕鬆地驗證Set的所有元素是否滿足特定條件,這在開發第三方庫/ API時很方便。

如果對任何元素的驗證失敗,則將拋出IllegalArgumentException 。下面的代碼段防止將**不是以'L'開頭**的**字符串**添加sourceSet或返回的validatingSet中

Set<String> validatingSet

 = SetUtils.predicatedSet(sourceSet, s -> s.startsWith("L"));

該庫還具有predicatedSortedSet()predicatedNavigableSet() ,分別用於SortedSetNavigableSet

4.集合的並集,差集和交集

該庫具有可以計算並集,差和Set元素的交集的方法。

different()方法接受兩個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));

請注意,嘗試對返回的SetUtils執行寫操作,如add()addAll() SetView將拋出UnsupportedOperationException

要修改返回的結果,我們需要調用返回的SetUtilstoSet()方法 SetView獲取一個可寫的Set對象:

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

SetUtils庫的union方法完全像聽起來那樣–返回set 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));

注意assert語句中使用isEqualSet()方法。這是SetUtils庫的一種方便的靜態方法,可以有效地檢查兩個集合是否相等。

為了獲得集合的交集,即集合a和集合b中都存在的元素,我們將使用SetUtils。**交集()方法。此方法還返回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.轉換集合元素

讓我們看一下另一個令人興奮的方法-SetUtils。 transformSet() 。此方法接受Set對象和Transformer接口。在源集的支持下,它使用Transformer接口的transform()方法來轉換集的每個元素。

轉換邏輯在Transformer接口的transform()方法中定義,該方法應用於添加到集合中的每個元素。下面的代碼片段將添加到集合中的每個元素乘以2:

Set<Integer> a = SetUtils.transformedSet(new HashSet<>(), e -> e * 2 );

 a.add(2);



 assertEquals(a.toArray()[0], 4);

transformSet()方法非常方便-它們甚至可以用於轉換集合的元素-例如從String到Integer。只要確保輸出的類型是輸入的子類型即可。

假設我們正在使用SortedSetNavigableSet而不是HashSet,我們可以分別使用transformedSortedSet()transformedNavigableSet()

請注意,新的HashSet實例將傳遞給transformedSet()方法。在將現有的非空Set傳遞給該方法的情況下,將不轉換先前存在的元素。

如果要轉換先前存在的元素(以及之後添加的元素),則需要使用org.apache.commons.collections4.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);

請注意,將轉換源集中的元素,並將結果復製到返回的newSet中。

6.設置析取

SetUtils庫提供了一種靜態方法,可用於查找集合析取。集a和集b的析取是集a和集b唯一的所有元素。

讓我們看看如何使用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. SetUtils庫中的其他方法

SetUtils庫中還有其他方法可以輕鬆處理集合數據:

  • 我們可以使用syncededSet()synchronizedSortedSet()來獲得線程安全的Set 。但是,正如文檔中所述,我們必須手動同步返回的集合的迭代器,以避免非確定性行為
  • 我們可以使用SetUtils.unmodifiableSet()獲得一個只讀集。請注意,嘗試將元素添加到返回的Set對像中將引發UnsupportedOperationException
  • 還有一個SetUtils.emptySet()方法可返回類型安全的不可變空集
  • SetUtils.emptyIfNull()方法接受可為空的Set對象。如果提供的Set為null,則返回一個空的只讀S et;否則為false。否則,返回提供的Set
  • SetUtils.orderedSet()將返回一個Set對象,該對象保持元素添加的順序
  • SetUtils.hashCodeForSet()可以為一個集合生成一個哈希碼-這樣,兩個相同元素的集合將具有相同的哈希碼
  • SetUtils.newIdentityHashSet()將返回一個HashSet ,該HashSet使用==匹配元素而不是equals()方法。請在此處閱讀有關其註意事項的信息

8.結論

在本文中,我們探討了SetUtils庫的精髓。實用程序類提供了靜態方法,這些方法使設置數據結構的使用變得輕鬆而令人興奮。它還可以提高生產率。

與往常一樣,代碼片段可以在GitHub上找到。可在此處找到SetUtils API的官方文檔。