I would like to compare to streams, and check if they have 1 or more elements in common (finding 1 is sufficient to stop looking for more). I want to be able to apply this to Streams containing a custom-created class.
For illustration, let’s say I have a class that looks like:
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); } }
And then I have two lovely streams that look like:
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));
Given that these Streams have 1 Point in common (namely, Point(3, 1)
), I would want the final result to be true.
The desired functionality can be pictured as:
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 }
Advertisement
Answer
First of all you have to convert your Streams to a Set or List to not get the famous error:
java.lang.IllegalStateException: stream has already been operated upon or closed
And then you can use anyMatch
as this:
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); }
Or you can convert only the b
Stream to a Set and use:
public static boolean haveSomethingInCommon(Stream<Coord> a, Stream<Coord> b) { Set<Coord> setB = b.collect(Collectors.toSet()); return a.anyMatch(setB::contains); }
I would recommend to Set<Coord>
instead of Stream<Coord>
as param in your method.
public static boolean haveSomethingInCommon(Set<Coord> a, Set<Coord> b) { return a.stream().anyMatch(b::contains); }