1概要

このクイックチュートリアルでは、2つのInteger配列間の共通部分を計算する方法を見ていきましょう。

重複エントリの処理方法にも焦点を当てます。

実装には

Streams.

を使用します。


2配列のメンバーシップ述語

2つの集合の共通部分は、定義上、1からのすべての値を持つ集合です。これも2番目の集合の一部です。

したがって、2番目の配列のメンバシップを決定するには、

Function

または

Predicate

が必要です。

List

はそのままでこのようなメソッドを提供するので、これを

List

に変換します。

Predicate isContainedInB = Arrays.asList(b)::contains;


3交差点を構築する

結果の配列を構築するために、最初のセットの要素を順番に検討し、それらが2番目の配列にも含まれるかどうかを確認します。


__Stream


APIは必要なメソッドを提供します。

まず、


Stream

を作成し、次に

Predicate__のメンバーシップでフィルタリングし、最後に新しい配列を作成します。

public static Integer[]intersectionSimple(Integer[]a, Integer[]b){
    return Stream.of(a)
      .filter(Arrays.asList(b)::contains)
      .toArray(Integer[]::new);
}


4重複エントリ

Javaの配列は

Set

の実装ではないので、入力とそれに続く結果に重複したエントリがあるという問題があります。結果の出現回数は、最初のパラメーターの出現回数によって異なります。

しかし集合の場合、要素は複数回出現してはいけません。 **

distinct()

メソッドを使用してこれをアーカイブすることができます。

public static Integer[]intersectionSet(Integer[]a, Integer[]b){
    return Stream.of(a)
      .filter(Arrays.asList(b)::contain)
      .distinct()
      .toArray(Integer[]::new);
}

そのため、交差の長さはパラメータの順序に依存しなくなりました。

しかし、ダブルエントリを削除しているため、配列とそれ自体の交差部分が再び配列になることはありません。


5多集合交差点

より一般的な概念は、複数の等しいエントリを許可するもので、マルチセットです。それらの場合、交差は最小数の入力オカレンスによって定義されます。したがって、私たちのメンバーシップ

Predicate

は、結果に要素を追加する頻度をスコア付けしなければなりません。

これには

remove()

メソッドを使用できます。これにより、メンバーシップが返され、要素が消費されます。したがって、

‘b’

のすべての等しい要素が消費された後は、結果に同じ要素が追加されることはありません。

public static Integer[]intersectionSet(Integer[]a, Integer[]b){
    return Stream.of(a)
      .filter(new LinkedList<>(Arrays.asList(b))::remove)
      .toArray(Integer[]::new);
}


__Arrays


APIは不変の

Listだけを返すので、__私たちは専用の可変のものを生成する必要があります。

6.まとめ

この記事では、

contains

メソッドと____removeメソッドを使用して、Javaで2つの配列の共通部分を実装する方法を説明しました。

すべての実装、コードスニペット、テストはhttps://github.com/eugenp/tutorials/tree/master/core-java-arrays[Githubリポジトリ]にあります – これはMavenベースのプロジェクトなので、インポートしてそのまま実行するのは簡単なはずです。