You have quite a few object instantiations that seems redudandantredundant and could be removed. consider rewritting solveRules to something similar to:
private void solveRules() {
if (this.rules.isEmpty())
return;
FieldGroup<T> chosenGroup = this.rules.get(0).getSmallestFieldGroup();
if (chosenGroup == null) {
throw new IllegalStateException("Chosen group is null.");
}
int groupSize = chosenGroup.size();
if (groupSize == 0) {
throw new IllegalStateException("Chosen group is empty. " + chosenGroup);
}
GroupValues<T> mapCopy = new GroupValues<T>();
List<FieldRule<T>> rulesCopy = new ArrayList<FieldRule<T>>();
int rulesCount = this.rules.size();
for (FieldRule<T> rule : this.rules) {
rulesCopy.add(new FieldRule<T>(rule));
}
for (int i = 0; i <= groupSize; i++) {
mapCopy.copyFrom(this.knownValues);
mapCopy.put(chosenGroup, i);
for (int j = 0; j<rulesCount;j++) {
rulesCopy.get(j).copyFrom(this.rules.get(j));
}
this.solve(mapCopy, rulesCopy, this.callback);
}
}
every copyFromcopyFrom
is meant as a method that essentially does the same as your copy constructors but instead of allocating yet another object it reinitializes an existing one.
Since your GameAnalyzeGameAnalyze
is essentially a function with curried arguments you could skip the instantiation of all the analyzers and instead pass the constructor arguments to solvesolve
and let them drip down the call chain. I haven't checked all the proposed changedchanges through, they are meant to give you the general idea.