The algorithm follows exactly the hint given in the problem, so no explanation is needed.

```
public class Solution {
public boolean isReflected(int[][] points) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int[] point : points) {
min = Math.min(min, point[0]);
max = Math.max(max, point[0]);
}
double reflectiveLine = (min + max) / 2.0;
Set<Point> set = new HashSet<>();
for (int[] point : points) {
set.add(new Point(point[0], point[1]));
}
for (int[] point : points) {
if (!set.contains(new Point((int)Math.round(2 * reflectiveLine - point[0]), point[1]))) {
return false;
}
}
return true;
}
}
class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
if (!(o instanceof Point)) {
return false;
}
Point other = (Point) o;
return x == other.x && y == other.y;
}
public int hashCode() {
return x * 31 + y;
}
}
```