두 스트림이 분리되어 있는지 확인하는 방법은 무엇입니까?

Nov 23 2020

스트림과 비교하여 공통 요소가 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
}

답변

1 YCF_L Nov 23 2020 at 14:37

먼저 유명한 오류가 발생하지 않도록 스트림을 세트 또는 목록으로 변환해야합니다.

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>.

public static boolean haveSomethingInCommon(Set<Coord> a, Set<Coord> b) {
    return a.stream().anyMatch(b::contains);
}
2 Naman Nov 23 2020 at 16:17

두 스트림을 독립적으로 수집하지 않고 여러 값이 키에 매핑되는지 그룹화하고 식별 할 수 있습니다.

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())
Kaplan Nov 23 2020 at 18:19

에 기능 disjoint 이 있습니다 Collections .

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