簡體   English   中英

如何檢查兩個流是否不相交?

[英]How to check if two streams are disjoint?

我想與流進行比較,並檢查它們是否有 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); 
    }
}

然后我有兩個可愛的流,看起來像:

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
}

在不獨立收集兩個流的情況下,您可以對多個值是否映射到任何鍵進行分組和識別。

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);
}

如果同一個流可以有兩次或更多次相同的元素,您可以更改代碼以使用 -

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

首先,您必須將 Streams 轉換為 Set 或 List 才能避免出現著名的錯誤:

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 Stream 轉換為 Set 並使用:

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>作為參數。

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

有一個功能disjointCollections

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM