1概要


Eclipseコレクション

は、Java用のもう1つの改良されたコレクションフレームワークです。

簡単に言うと、最適化された実装と、コアJavaには見られない追加のデータ構造および機能を提供します。

このライブラリは、すべてのデータ構造の変更可能な実装と不変の実装の両方を提供します。


2 Mavenの依存関係

まず、

pom.xml

に次のMaven依存関係を追加します。

<dependency
    <groupId>org.eclipse.collections</groupId>
    <artifactId>eclipse-collections</artifactId>
    <version>8.2.0</version>
</dependency>

このライブラリの最新版はhttps://mvnrepository.com/artifact/org.eclipse.collections/eclipse-collections[Maven Central Repository]にあります。


3大きな絵


3.1. 基本コレクション型

Eclipseコレクションの基本的なコレクション型は以下のとおりです。



  • ListIterable


    – 挿入を維持する順序付きコレクション

重複した要素を並べ替えます。サブインターフェイスは次のとおりです。


MutableList



FixedSizeList

、および

ImmutableList

。最も一般的な

ListIterableの実装はFastListです。これはのサブクラスです。
MutableList




SetIterable

** – 重複した要素を許可しないコレクション。それ

ソートすることもソートしないこともできます。サブインターフェースは次のとおりです。

SortedSetIterable

最も一般的なソートされていない

SetIterable

実装は

UnifiedSet

です



MapIterable

** – キーと値のペアのコレクション。サブインターフェース


MutableMap



FixedSizeMap

、および

ImmutableMap

を含めます。 2つの一般的な
実装は

UnifiedMap



MutableSortedMap

です。しながら

UnifiedMap

は順序を維持しない、

MutableSortedMap

は維持する
要素の自然順序



BiMap

** – 繰り返し可能なキー/値ペアのコレクション

どちらの方向にも通過できます。

BiMap



MapIterable

インターフェースを拡張します



Bag

** – 重複を許可する番号なしコレクション。

サブインタフェースには

MutableBagと


FixedSizeBag

があります。最も一般的な
実装は

HashBag

です



StackIterable

** – 「後入れ先出し」を維持するコレクション

順番は逆の挿入順で要素を繰り返し

サブインターフェースには、

MutableStack



ImmutableStack

があります。



MultiMap

** – 複数を許可するキー/値ペアのコレクション

各キーの値


3.2. プリミティブコレクション

  • このフレームワークは膨大な数のプリミティブコレクション** も提供します。それらの実装はそれらが持つ型にちなんで名付けられています。それらのそれぞれのタイプには、可変、不変、同期、および変更不可能な形式があります。

  • プリミティブ

    リスト

  • プリミティブ

    Sets

  • プリミティブ

    スタック

  • プリミティブ

    Bags

  • プリミティブ

    マップ


  • InntInterval

プリミティブまたはオブジェクトキーとプリミティブまたはオブジェクト値のすべての可能な組み合わせを網羅する膨大な数のプリミティブマップ形式があります。

簡単なメモ –

InntInterval

は、step値を使用して反復できる整数の範囲です。


4コレクションのインスタンス化


ArrayList

または

HashSet

に要素を追加するには、引数なしのコンストラクターを呼び出して各要素を1つずつ追加して、コレクションをインスタンス化します。

Eclipseコレクションでもそれを実行できますが、** コレクションをインスタンス化して、すべての初期要素を同時に1行で提供することもできます。


FastList

をインスタンス化する方法を見てみましょう。

MutableList<String> list = FastList.newListWith(
  "Porsche", "Volkswagen", "Toyota", "Mercedes", "Toyota");

同様に、

UnifiedSet

をインスタンス化し、

newSetWith()

staticメソッドに要素を渡すことでそれに要素を追加できます。

Set<String> comparison = UnifiedSet.newSetWith(
  "Porsche", "Volkswagen", "Toyota", "Mercedes");

これが

HashBag

をインスタンス化する方法です。

MutableBag<String> bag = HashBag.newBagWith(
  "Porsche", "Volkswagen", "Toyota", "Porsche", "Mercedes");

マップをインスタンス化し、それらにキーと値のペアを追加することも同様です。

唯一の違いは、

Pair

インターフェースの実装としてキーと値のペアを

newMapWith()

メソッドに渡すことです。

例として

UnifiedMap

を取りましょう。

Pair<Integer, String> pair1 = Tuples.pair(1, "One");
Pair<Integer, String> pair2 = Tuples.pair(2, "Two");
Pair<Integer, String> pair3 = Tuples.pair(3, "Three");

UnifiedMap<Integer, String> map = new UnifiedMap<>(pair1, pair2, pair3);

私たちはまだJava Collections APIアプローチを使うことができます:

UnifiedMap<Integer, String> map = new UnifiedMap<>();

map.put(1, "one");
map.put(2, "two");
map.put(3, "three");

不変コレクションは変更できないため、

add()



remove()

などのコレクションを変更するメソッドの実装はありません。

ただし、変更不可能なコレクションではこれらのメソッドを呼び出すことができますが、呼び出すと

UnsupportedOperationException

がスローされます。


5コレクションから要素を取得する

標準的な

Lists

を使うのと同じように、Eclipse Collections

Lists

の要素はそれらのインデックスによって取得することができます。

list.get(0);

そしてEclipseコレクションマップの値はそれらのキーを使って取得することができます。

map.get(0);


getFirst()

メソッドと

getLast()

メソッドは、それぞれリストの最初と最後の要素を取得するために使用できます。他のコレクションの場合、それらはイテレータによって返される最初と最後の要素を返します。

map.getFirst();
map.getLast();

メソッド

max()

および

min()

を使用して、自然順序付けに基づいてコレクションの最大値と最小値を取得できます。

map.max();
map.min();


6. コレクションを反復する

Eclipseコレクションは、コレクションを反復処理するためのさまざまな方法を提供します。

彼らが何であるか、そして実際にどのように機能するかを見てみましょう。


6.1. コレクションフィルタリング

選択パターンは、論理条件を満たすコレクションの要素を含む新しいコレクションを返します。これは本質的にはフィルタリング操作です。

例を示しましょう。

@Test
public void givenListwhenSelect__thenCorrect() {
    MutableList<Integer> greaterThanThirty = list
      .select(Predicates.greaterThan(30))
      .sortThis();

    Assertions.assertThat(greaterThanThirty)
      .containsExactly(31, 38, 41);
}

単純なラムダ式を使用して同じことを実行できます。

return list.select(i -> i > 30)
  .sortThis();

棄却パターンは反対です。論理条件を満たさないすべての要素のコレクションを返します。

例を見てみましょう。

@Test
public void whenReject__thenCorrect() {
    MutableList<Integer> notGreaterThanThirty = list
      .reject(Predicates.greaterThan(30))
      .sortThis();

    Assertions.assertThat(notGreaterThanThirty)
      .containsExactlyElementsOf(this.expectedList);
}

ここでは、30より大きい要素をすべて拒否します。


6.2.

collect()

メソッド


collect

メソッドは、提供されたラムダ式によって返される結果を要素とする新しいコレクションを返します。基本的にはStream APIの

map()



collect()

の組み合わせです。

実際に見てみましょう。

@Test
public void whenCollect__thenCorrect() {
    Student student1 = new Student("John", "Hopkins");
    Student student2 = new Student("George", "Adams");

    MutableList<Student> students = FastList
      .newListWith(student1, student2);

    MutableList<String> lastNames = students
      .collect(Student::getLastName);

    Assertions.assertThat(lastNames)
      .containsExactly("Hopkins", "Adams");
}

作成されたコレクション

lastNames

には、生徒リストから収集された姓が含まれています。

しかし、

返されたコレクションがコレクションのコレクションで、ネストした構造を維持したくない場合はどうしますか?

たとえば、各生徒に複数の住所があり、その住所をコレクションのコレクションではなく

Strings

として含むコレクションが必要な場合は、

flatCollect()

メソッドを使用できます。

例を示しましょう。

@Test
public void whenFlatCollect__thenCorrect() {
    MutableList<String> addresses = students
      .flatCollect(Student::getAddresses);

    Assertions.assertThat(addresses)
      .containsExactlyElementsOf(this.expectedAddresses);
}


6.3. 元素検出


  • detect

    メソッドは、論理条件を満たす最初の要素を見つけて返します。

簡単な例を見てみましょう。

@Test
public void whenDetect__thenCorrect() {
    Integer result = list.detect(Predicates.greaterThan(30));

    Assertions.assertThat(result)
      .isEqualTo(41);
}


  • anySatisfy

    メソッドは、コレクションのいずれかの要素が論理条件を満たすかどうかを判断します。

例を示しましょう。

@Test
public void whenAnySatisfiesCondition__thenCorrect() {
    boolean result = list.anySatisfy(Predicates.greaterThan(30));

    assertTrue(result);
}

  • 同様に、

    allSatisfy

    メソッドは、コレクションのすべての要素が論理条件を満たすかどうかを判断します。

簡単な例を見てみましょう。

@Test
public void whenAnySatisfiesCondition__thenCorrect() {
    boolean result = list.allSatisfy(Predicates.greaterThan(0));

    assertTrue(result);
}


6.4.

partition()

メソッド


partition

メソッドは、要素が論理条件を満たすかどうかに応じて、コレクションの各要素を2つのコレクションのいずれかに割り当てます。

例を見てみましょう。

@Test
public void whenAnySatisfiesCondition__thenCorrect() {
    MutableList<Integer> numbers = list;
    PartitionMutableList<Integer> partitionedFolks = numbers
      .partition(i -> i > 30);

    MutableList<Integer> greaterThanThirty = partitionedFolks
      .getSelected()
      .sortThis();
    MutableList<Integer> smallerThanThirty = partitionedFolks
      .getRejected()
      .sortThis();

    Assertions.assertThat(smallerThanThirty)
      .containsExactly(1, 5, 8, 17, 23);
    Assertions.assertThat(greaterThanThirty)
      .containsExactly(31, 38, 41);
}


6.5. 遅延反復

遅延反復は、反復メソッドが呼び出される最適化パターンですが、その実際の実行は、そのアクションまたは戻り値が別の後続のメソッドで必要になるまで延期されます。

@Test
public void whenLazyIteration__thenCorrect() {
    Student student1 = new Student("John", "Hopkins");
    Student student2 = new Student("George", "Adams");
    Student student3 = new Student("Jennifer", "Rodriguez");

    MutableList<Student> students = Lists.mutable
      .with(student1, student2, student3);
    LazyIterable<Student> lazyStudents = students.asLazy();
    LazyIterable<String> lastNames = lazyStudents
      .collect(Student::getLastName);

    Assertions.assertThat(lastNames)
      .containsAll(Lists.mutable.with("Hopkins", "Adams", "Rodriguez"));
}

ここで、

lazyStudents

オブジェクトは、

collect()メソッドが呼び出されるまで、

students__リストの要素を取得しません。


7. コレクション要素の組み合わせ

メソッド

zip()

は、2つのコレクションの要素を組み合わせて新しいコレクションを返します。 2つのコレクションのいずれかが長い場合、残りの要素は切り捨てられます。

使用方法を見てみましょう。

@Test
public void whenZip__thenCorrect() {
    MutableList<String> numbers = Lists.mutable
      .with("1", "2", "3", "Ignored");
    MutableList<String> cars = Lists.mutable
      .with("Porsche", "Volvo", "Toyota");
    MutableList<Pair<String, String>> pairs = numbers.zip(cars);

    Assertions.assertThat(pairs)
      .containsExactlyElementsOf(this.expectedPairs);
}


zipWithIndex()

メソッドを使用して、コレクションの要素をそれらのインデックスとペアにすることもできます。

@Test
public void whenZip__thenCorrect() {
    MutableList<String> cars = FastList
      .newListWith("Porsche", "Volvo", "Toyota");
    MutableList<Pair<String, Integer>> pairs = cars.zipWithIndex();

    Assertions.assertThat(pairs)
      .containsExactlyElementsOf(this.expectedPairs);
}


8コレクションを変換する

Eclipseコレクションは、コンテナー・タイプを別のタイプに変換するための簡単な方法を提供します。これらのメソッドは、

toList()



toSet()



toBag()

、および__toMap()です。

使い方を見てみましょう。

public static List convertToList() {
    UnifiedSet<String> cars = new UnifiedSet<>();

    cars.add("Toyota");
    cars.add("Mercedes");
    cars.add("Volkswagen");

    return cars.toList();
}

テストを実行しましょう。

@Test
public void whenConvertContainerToAnother__thenCorrect() {
    MutableList<String> cars = (MutableList) ConvertContainerToAnother
      .convertToList();

    Assertions.assertThat(cars)
      .containsExactlyElementsOf(
      FastList.newListWith("Volkswagen", "Toyota", "Mercedes"));
}


9結論

このチュートリアルでは、Eclipseコレクションとそれらが提供する機能の概要を簡単に説明しました。

このチュートリアルの完全な実装はhttps://github.com/eugenp/tutorials/tree/master/libraries[over GitHub]で利用可能です。