bugfix> java > 投稿

ストリームと比較して、共通の要素が1つ以上あるかどうかを確認したいと思います(1つを見つけるだけで、それ以上の要素を探すのをやめることができます)。これを、カスタム作成されたクラスを含むStreamsに適用できるようにしたいと思います。

説明のために、次のようなクラスがあるとします。

public class Point {
    public final int row;
    public final int col;
    public Point(int row, int col) {
        this.row = row;
        this.col = col;
    }    
    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (obj.getClass() != this.getClass()) return false;
        final Point other = (Point) obj;
        return this.row == other.row && this.col == other.col;
    }
    @Override
    public int hashCode() {
        return Objects.hash(row, col); 
    }
}

そして、次のような2つの素敵なストリームがあります。

Stream<Point> streamA = Stream.of(new Point(2, 5), new Point(3, 1));
Stream<Point> streamB = Stream.of(new Point(7, 3), new Point(3, 1));

これらのストリームに共通のポイントが1つあるとすると(つまり、 Point(3, 1) )、私は最終結果が真であることを望みます。

必要な機能は次のように表すことができます。

public static boolean haveSomethingInCommon(Stream<Point> a, Stream<Point> b){
    //Code that compares a and b and returns true if they have at least 1 element in common
}

回答 3 件
  • まず、有名なエラーが発生しないように、ストリームをセットまたはリストに変換する必要があります。

    java.lang.IllegalStateException: stream has already been operated upon or closed
    
    

    そして、あなたは使用することができます anyMatch このように:

    public static boolean haveSomethingInCommon(Stream<Coord> a, Stream<Coord> b) {
        Set<Coord> setA = a.collect(Collectors.toSet());
        Set<Coord> setB = b.collect(Collectors.toSet());
        return setA.stream().anyMatch(setB::contains);
    }
    
    

    または、 b セットにストリーミングして使用する:

    public static boolean haveSomethingInCommon(Stream<Coord> a, Stream<Coord> b) {
        Set<Coord> setB = b.collect(Collectors.toSet());
        return a.anyMatch(setB::contains);
    }
    
    

    私はお勧めします Set<Coord> の代わりに Stream<Coord> メソッドのparamとして。

    public static boolean haveSomethingInCommon(Set<Coord> a, Set<Coord> b) {
        return a.stream().anyMatch(b::contains);
    }
    
    

  • 2つのストリームを個別に収集しなくても、複数の値が任意のキーにマップされているかどうかをグループ化して識別することができます。

    public static boolean haveSomethingInCommon(Stream<Coord> a, Stream<Coord> b) {
        return Stream.concat(a, b)
                .collect(Collectors.groupingBy(Function.identity()))
                .values().stream()
                .anyMatch(l -> l.size() > 1);
    }
    
    

    同じストリームに同じ要素を2回以上含めることができる場合は、使用するコードを変更できます-

    Stream.concat(a.distinct(), b.distinct())
    
    

  • 機能があります disjoint Collections

    public static boolean haveSomethingInCommon( Stream<Coord> a, Stream<Coord> b ) {
      return( ! Collections.disjoint( a.collect( toList() ), b.collect( toList() ) ) );
    }
    
    

あなたの答え