先日、Python での 2つのリストに存在する要素を抽出したリストを求める - Oboe吹きプログラマの黙示録
を書いたので、
Java の方を整理して書き留めておく。
Java では、List と Set を意識して使いたいので、求める結果は Streamになるメソッドを
用意するのが明示的で使いやすいであろう。
Apache Commons – Apache Commons の CollectionUtils を使えば済むことではあるが、
外部ライブラリに頼りたくない場合以下のように整理したメソッドを用意すると便利である。
サンプルの List
List<Integer> l1 = List.of(1, 2, 4, 5, 7, 9, 1); List<Integer> l2 = List.of(2, 3, 4, 6, 8)
和集合:CollectionUtils.union(a, b) に相当
public static <T> Stream<T> unionStream(List<T> a, List<T> b){ Set<T> sa = a.stream().collect(Collectors.toSet()); Set<T> sb = b.stream().collect(Collectors.toSet()); sa.addAll(sb); return sa.stream(); }
和集合計算
List<Integer> lt = unionStream(l1, l2).collect(Collectors.toList()); System.out.println(lt);
[1, 2, 3, 4, 5, 6, 7, 8, 9]
差分:CollectionUtils.subtract(a, b) に相当
public static <T> Stream<T> differenceStream(List<T> a, List<T> b){ Set<T> sa = a.stream().collect(Collectors.toSet()); Set<T> sb = b.stream().collect(Collectors.toSet()); sa.removeAll(sb); return sa.stream(); }
差分計算
List<Integer> lt = differenceStream(l1, l2).collect(Collectors.toList()); System.out.println(lt);
[1, 5, 7, 9]
積:CollectionUtils.disjunction(a, b) に相当
public static <T> Stream<T> intersectStream(List<T> a, List<T> b){ Set<T> t = a.stream().collect(Collectors.toSet()); Set<T> sb = b.stream().collect(Collectors.toSet()); t.retainAll(sb); return t.stream(); }
積集合計算
List<Integer> lt = intersectStream(l1, l2).collect(Collectors.toList()); System.out.println(lt);
[2, 4]
対象差(排他的論理和):CollectionUtils.disjunction(a, b) に相当
public static <T> Stream<T> symmetricDifferenceStream(List<T> a, List<T> b){ Set<T> sa = a.stream().collect(Collectors.toSet()); Set<T> sb = b.stream().collect(Collectors.toSet()); Set<T> sc = a.stream().collect(Collectors.toSet()); sc.addAll(sb); sa.retainAll(sb); sc.removeAll(sa); return sc.stream(); }
排他的論理和計算
List<Integer> lt = symmetricDifferenceStream(l1, l2).collect(Collectors.toList()); System.out.println(lt);
[1, 3, 5, 6, 7, 8, 9]