I have a set of points with different possibilities. For that I created a class Point. It's importan to say that a point MUST ALWAYS HAVE AT LEAST ONE POSSIBILITY (For this example we assume this statement is true).
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Point {
private final HashSet<Integer> possibilities;
public Point(int n) {
this.possibilities = (HashSet<Integer>) IntStream.rangeClosed(1, n)
.boxed()
.collect(Collectors.toSet());
}
/**
* Serves to verify if this point has only one
* possibility
* @return true if there's only one element in the
* hashset possibilities, false otherwise
*/
public boolean uniquePossibility() {
return this.possibilities.size() == 1;
}
/**
* @return the number of possibilities for this point
*/
public int getCurrentPossibilities() {
return this.possibilities.size();
}
/**
* @return possibilities
*/
public HashSet<Integer> getPossibilities() {
return possibilities;
}
/* Lots of methods here */
}
And then I want to create a method that works with the points with 2 or 3 possibilities.
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class AwesomeClass {
private final List<Point> points;
public AwesomeClass() {
points = new ArrayList(10_00_000);
for (int i = 0; i < 10_00_000; i++) {
Random random = new Random();
points.add(new Point(random.nextInt(9) + 1));
}
spotTriplets();
}
private boolean spotTriplets() {
AtomicBoolean changes = new AtomicBoolean(false);
List<Point> triplets = points.stream()
.filter(point -> point.getCurrentPossibilities() <= 3)
.filter(point -> !point.uniquePossibility())
.collect(Collectors.toList());
triplets.forEach(point -> {
System.out.println(point.uniquePossibility());
List<Integer> number = new ArrayList<>(point.getPossibilities());
int x = number.get(0);
int y = number.get(1);
AtomicInteger z = new AtomicInteger(0);
/* Lots of beautiful code*/
});
return changes.get();
}
}
When I run my code, this error happens
false
false
...
false
false
true
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at AwesomeClass.lambda$spotTriplets$69(AwesomeClass.java:400)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at AwesomeClass.spotTriplets(AwesomeClass.java:396)
at AwesomeClass.solveProblem(AwesomeClass.java:71)
at Main.main(Main.java:59)
Process finished with exit code 1
This error is on the line int y = number.get(1);. But the error actually is from the filter, please notice the filter .filter(point -> !point.uniquePossibility()) and the STDOUT: System.out.println(point.uniquePossibility());.
Is contradictory that if I have a filter dropping point.uniquePossibility(), I got a point with point.uniquePossibility() -> true.
What can I do?
Using the filter before the foreach solves the problem, but I would like to fix this on the List
triplets.stream()
.filter(point -> !point.uniquePossibility())
.forEach(point -> {/*code here*/});
Thanks in advance