1. 概要

この記事では、ApacheCommonsCollectionsライブラリのSetUtilsAPIについて説明します。 簡単に言うと、これらのユーティリティを使用して、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. 述語セット

SetUtilsライブラリのpredicatedSet()メソッドを使用すると、セットに挿入されるすべての要素が満たす必要のある条件を定義できます。 ソースSetオブジェクトと述語を受け入れます。

これを使用して、 Set のすべての要素が特定の条件を満たすことを簡単に検証できます。これは、サードパーティのライブラリ/APIを開発するときに便利です。

いずれかの要素の検証が失敗した場合、IllegalArgumentExceptionがスローされます。 の下のスニペットは、で始まらない文字列がsourceSetまたは返されたvalidatingSetに追加されるのを防ぎます。

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

ライブラリには、 SortedSetおよびNavigableSetをそれぞれ操作するためのpredicatedSortedSet()および predicatedNavigableSet()もあります。

4. セットの和集合、差、および共通部分

ライブラリには、 Set 要素の和集合、差、および共通部分を計算できるメソッドがあります。

Difference()メソッドは2つの 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.SetViewでadd()やaddAll()などの書き込み操作を実行しようとすると、UnsupportedOperationExceptionがスローされます。

返された結果を変更するには、返されたSetUtils。 SetViewtoSet()メソッドを呼び出して、書き込み可能なSetを取得する必要があります。物体:

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

SetUtilsライブラリのunionメソッドは、まさにそのように聞こえます。セットaおよびbのすべての要素を返します。 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 ライブラリの便利な静的メソッドであり、2つのセットが等しいかどうかを効果的にチェックします。

セットの共通部分を取得するには、つまり セット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. セット要素の変換

別のエキサイティングなメソッドであるSetUtils。transformedSet()を見てみましょう。 このメソッドは、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);

transformedSet()メソッドは非常に便利です。たとえば、文字列から整数へのセットの要素のキャストにも使用できます。 出力のタイプが入力のサブタイプであることを確認してください。

HashSetの代わりにSortedSetまたはNavigableSetを使用しているとしましょう。 )それぞれ。

新しい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 ライブラリには、セットデータの処理を簡単にする他のメソッドがあります。

  • synchronizedSet()または synchronizedSortedSet()を使用して、スレッドセーフなSetを取得できます。 ただし、ドキュメントに記載されているように、非決定的な動作を回避するために、返されたセットのイテレータを手動で同期する必要があります
  • SetUtils.unmodizableSet()を使用して、読み取り専用セットを取得できます。 返されたSet Objectに要素を追加しようとすると、UnsupportedOperationExceptionがスローされることに注意してください。
  • タイプセーフで不変の空のセットを返すSetUtils.emptySet()メソッドもあります
  • SetUtils.emptyIfNull()メソッドは、null許容のSetオブジェクトを受け入れます。 指定されたSetがnullの場合、空の読み取り専用のS etを返します。 それ以外の場合は、指定されたSetを返します。
  • SetUtils.orderedSet()は、要素が追加される順序を維持するSetオブジェクトを返します
  • SetUtils.hashCodeForSet()は、同じ要素の2つのセットが同じハッシュコードを持つように、セットのハッシュコードを生成できます。
  • SetUtils.newIdentityHashSet()は、 equals()メソッドの代わりに==を使用して要素を照合するHashSetを返します。 その警告について読んでくださいここ

8. 結論

この記事では、SetUtilsライブラリの要点を探りました。 ユーティリティクラスは、セットデータ構造を簡単かつエキサイティングに操作できるようにする静的メソッドを提供します。 また、生産性も向上します。

いつものように、コードスニペットはGitHub利用できます。 SetUtils APIの公式ドキュメントは、ここにあります。