How to avoid a circular reference in Java - java

I'm trying to create two different classes that represent different options of exercises the user can choose to sort by. After one class is chosen, the other is no longer an option, because of this I create an ArrayList in both classes of classes which are not allowed to follow it.
The problem is that since they are not able to follow each other, when these classes are constructed it results in an infinite loop, is there any way I can avoid this?
PushPullLegs Class
public class PushPullLegs extends SortingGroup implements Serializable{
public PushPullLegs(){
this.setName("Push,Pull,Legs");
this.addCantFollow(new MuscleGroup());
SortingCategory push = new SortingCategory("Push","PPL","Push");
this.addOption(push);
SortingCategory pull = new SortingCategory("Pull","PPL","Pull");
this.addOption(pull);
SortingCategory legs = new SortingCategory("Legs","PPL","Legs");
this.addOption(legs);
}
}
MuscleGroup Class
public class MuscleGroup extends SortingGroup implements Serializable {
public MuscleGroup(){
this.addCantFollow(new PushPullLegs());
SortingCategory chest = new SortingCategory("Chest","Primary","Chest");
chest.addNewOptions(new ChestMovementPatterns());
this.addOption(chest);
SortingCategory triceps = new SortingCategory("Triceps","Primary","Triceps");
triceps.addNewOptions(new TricepMovementPatterns());
this.addOption(triceps);
SortingCategory lats = new SortingCategory("Lats","Primary","Lats");
this.addOption(lats);
SortingCategory quads = new SortingCategory("Quads","Primary","Quads");
this.addOption(quads);
SortingCategory hamstrings = new SortingCategory("Hamstrings","Primary","Hamstrings");
this.addOption(hamstrings);
}
}

You would use code like this:
private Set<Class<? extends SortingGroup>> cantFollowClass = new HashSet<>();
public void addCantFollow(Class<? extends SortingGroup> clazz) {
this.cantFollowClass = clazz;
}
public boolean canFollow(SortingGroup group) {
return ! this.cantFollowClass.contains(group.getClass());
}

Related

How to create a method with an object wildcard (parameter) in Java?

Problem<NQueensBoard, QueenAction> problem = new GeneralProblem<>(createBoard(),
TailoredNQF::getIFActions, TailoredNQF::getResult, TailoredNQF::testGoal);
SearchForActions<NQueensBoard, QueenAction> search = new BreadthFirstSearch<>(new GraphSearch<>());
Optional<List<QueenAction>> actions = search.findActions(problem);
actions.ifPresent(qActions -> qActions.forEach(System.out::println));
System.out.println(search.getMetrics());
I want "BreadthFirstSearch" to be some kind of a wildcard(*) (or parameter in a method structure) here, so that I can run this entire piece of code just as;
runCode(BreadthFirstSearch);
runCode(DepthFirstSearch);
...
without repeating.
How can I do it?
You will need to use an interface or an abstract class and dependency injection, to inject the type of object search you want to do. The code will look something like this:
public interface SearchForAction<N, Q> {
Optional<List<Q>> findActions(Problem<N, Q> problem);
}
public class BreadthFirstSearch implements SearchForAction<N, Q> {
Optional<List<Q>> findActions(Problem<N, Q> problem) {
// Do your action
}
}
public class SearchEngine<N, Q> {
private SearchForAction<N, Q> searchForAction;
public Optional<List<Q>> runCode(SearchForAction<N, Q> searchForAction, Problem<N, Q> problem) {
this.searchForAction = searchForAction;
return this.searchForAction.findActions(problem);
}
}
public class Program {
private SearchEngine<NQueensBoard, QueenAction> searchEngine = new SearchEngine<>();
private SearchForActions<NQueensBoard, QueenAction> breadthFirstSearch = new BreadthFirstSearch<>();
private SearchForActions<NQueensBoard, QueenAction> depthFirstSearch = new DepthFirstSearch<>();
// In your program call your method and you inject your dependency
searchEngine.runCode(breadthFirstSearch);
searchEngine.runCode(depthFirstSearch);
}

Instantiate all children of a given abstract parent class dynamically

Is there a way to instantiate all children of an abstract class dynamically?
What I have currently is similar to this:
public class CommandHandler {
private Command info = new Info();
private Command prefix = new Prefix();
private Command roll = new Roll();
private Command coin = new Coin();
private Command invite = new Invite();
private Command quit = new Quit();
private Command restart = new Restart();
}
With the abstract parent class being something like this:
public abstract class Command {
protected String name;
protected String arguments;
protected abstract void execute();
}
But what if I want to instantiate all classes that extend Command without typing them all out individually and adding to the list every time I add a command?
And if I can instantiate them dynamically, can I also manipulate them dynamically? i.e. add each class to a list once it has been instantiated.
Or is there a better design to use that accomplishes what I want in a simpler way?
EDIT: #Ash's solution works perfectly in an IDE, but not when using a jar. All you have to do to make it work in both is change
classPathList.addAll(ClasspathHelper.forClassLoader());
to
classPathList.addAll(ClasspathHelper.forJavaClassPath());
Hope it helps someone!
If you use maven (if not, you should :p), add the following dependency :
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
Then you can list the class you want with the following code (assuming you have a constructor with no parameters) :
public class Loader {
public static void main(String[] args) {
try {
Set<URL> classPathList = new HashSet<URL>();
classPathList.addAll(ClasspathHelper.forClassLoader());
Set<Class<? extends Command>> result = new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner()).setUrls(classPathList)).getSubTypesOf(Command.class);
List<Command> commands = new ArrayList<Command>();
for (Class<? extends Command> c : result) {
System.out.println(c.getSimpleName());
commands.add(c.newInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Using a fluent builder pattern without inner static classes for workflow

This is a continuation from what I was working in Passing 1 to many parameters of same object type
I've gotten good feedback on that , I believe i have the improved the design . The whole code is at https://github.com/spakai/flow_input_builder
The requirement is simple : -
I need to build a set of input for different workflows using 1 or more outputs from previous workflows
I have a set of interfaces
public interface SwfInput {
}
public interface SwfOutput {
}
public interface Workflow<I extends SwfInput, O extends SwfOutput> {
public O execute(I input);
}
public interface Builder<I extends SwfInput> {
public I build();
}
Now , Say I have 3 flows which gets executed in sequence FlowA->FlowB->FlowC
FlowC needs mandatory output from FlowB but only optionally from FlowA
so I have a implementation for FlowCBuilder
public class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowBOutput mandatoryflowBOutput;
private FlowAOutput optionalflowAOutput;
public FlowAOutput getOptionalflowAOutput() {
return optionalflowAOutput;
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
this.optionalflowAOutput = optionalflowAOutput;
return this;
}
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
this.mandatoryflowBOutput = mandatoryflowBOutput;
}
#Override
public FlowCInput build() {
FlowCInput input = new FlowCInput();
input.setMandatoryFromFlowB(mandatoryflowBOutput.getOutput1FromB());
if (optionalflowAOutput != null) {
input.setOptionalFromFlowA(optionalflowAOutput.getOutput2FromA());
}
return input;
}
}
one test i have written shows an example usage
FlowBOutput mandatoryflowBOutput = new FlowBOutput();
mandatoryflowBOutput.setOutput1FromB("iNeedThis");
FlowAOutput optionalflowAOutput = new FlowAOutput();
FlowCInput input = new FlowCInputBuilder(mandatoryflowBOutput)
.setOptionalflowAOutput(optionalflowAOutput)
.build();
I have not used static inner class for the Builder pattern.
Any suggestions are welcomed.
You should use static inner class. The key point of using this approach is that, the inner can directly access private properties of the object being constructed. This helps eliminating duplicated code since the builder does not need to maintain a long list of temporary state for the constructing. So, your code can be rewritten like this:
public class FlowCInput {
private int output1FromB; // suppose that it is int
private String output2FromA; // suppose that it is String
private FlowCInput() { }
//...
public static class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowCInput result;
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
result = new FlowCInput();
// output1FromB is private but still accessed from here
result.output1FromB = mandatoryflowBOutput.getOutput1FromB();
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
// same for output2FromA
result.output2FromA = optionalflowAOutput.getOutput2FromA();
return this;
}
#Override
public FlowCInput build() {
return result;
}
}
}
As you see, the builder now holds only a FlowCInput object, it does not unnecessarily hold mandatoryflowBOutput and optionalflowAOutput as before.

Java - Set capable of referencing instances of a different class

Can anyone help me with this java code?
I have two classes and need to create a set that can store instances of the other class. here is the sample I managed to "commit" :)
Class A
public Class Rabbit {
private String age;
//constructor for instance of Rabbit <br>
public Rabbit(String rabAge) {
super();
this.age = rabAge;
}
now class B:
public class ManyRabbits {
private Set <String> setOfRabbits;
now this method should create a new instance of the Rabbit and add it to the set represented by variable setOfRabbits
public void addRabbit (String age)` {
//and I don't know what should go next...something like: `
Rabbit r1 = new Rabbit("10");` <br>
setOfRabbits.add(r1);
}
You need to change your set declatation :
private Set<Rabbit> setOfRabbits;
And you also need to ovweride those two method in order to never insert twice the same object in the set.
#Override
public int hashCode() {
// Your own implementation
return ...;
}
#Override
public boolean equals(Object o) {
// Your own implementation
return ...;
}
your ManyRabbits calss should be like this
public class ManyRabbits
{
private Set<Rabbit> setOfRabbits = new HashSet<Rabbit>();
public void addRabbit (String age)
{
Rabbit r1 = new Rabbit(age);
setOfRabbits.add(r1);
}
}
public class Rabbit {
private String age;
//constructor for instance of Rabbit
public Rabbit(String rabAge) {
super();
this.age = rabAge;
}
// more methods if necessary
}
In ManyRabbits:
public class ManyRabbits {
private Set <Rabbit> setOfRabbits = new HashSet<>();
public void addRabbit (String age) {
Rabbit r1 = new Rabbit(age);
setOfRabbits.add(r1);
}
// more methods if necessary
}
Use it by calling something like
ManyRabbits manyRabbits = new ManyRabbits();
manyRabbits.addRabbit("10");
manyRabbits.addRabbit("20");
manyRabbits.addRabbit("30");
Say:
Set<Rabbit> setOfRabbits = new HashSet<>();
setOfRabbits.add(new Rabbit());
When the Set will be keeping track of an unknown quantity of an object, I typically try to instantiate with an unnamed instance. This would work great for adding to a listener so that you could, say, add a new Rabbit every time the user clicks.
In this way, you could add however many Rabbit object you want. Try:
for(i = 0; i < 10; i++) {
setOfRabbits.add(new Rabbit());
}
You may see this in older versions of Java:
Set<Rabbit> setOfRabbits = new HashSet<Rabbit>();
but it is no longer necessary

Better way to call common method on randomly selected object in java

Nice day to everybody.
I have an abstract class with the method runRandomExercise(), and several classes that extends it to add different kind of exercise.
I now want to chose a random type exercise, so I need to randomly choose one of the classes, and call runRandomExercise() on that.
For now I am manually coding this, which is not the very best solution I think. However, I can’t store just the classes in the array since the class type is different, and if I use object[] I can’t call the runRandomExercise() method. Any smart way to handle this?
Here is my code till now. It works, but it’s gonna be a pain to add other classes...
/*Specific classes that extend abstract class TrainingClass with the runRandomExercise() method*/
private MatheMagic mMathMag;
private Mnemonics mMnemonics;
private String[] mTrainingClasses;
/*Initialize classes*/
mMathMag = new MatheMagic();
mMnemonics = new Mnemonics();
/*Manually store classe names*/
mTrainingClasses = new String[2];
mTrainingClasses[0] = "mMathMag";
mTrainingClasses[1] = "mMnemonics";
/*Return random exercise*/
public String[] RandomExercise() {
Random aGenerator = new Random();
/*Get random class name*/
int rnd = aGenerator.nextInt(mTrainingClasses.length);
String aChosen = mTrainingClasses[rnd];
String[] aRes = new String[2];
if (aChosen == "mMathMag") {
aRes = mMathMag.runRandomExercise();
} else if (aChosen == "mMnemonics") {
aRes = mMnemonics.runRandomExercise();
}
return aRes;
}
EDIT
Here is how TrainingClass is defined:
/** Common interface for all exercises */
public interface Exercise {
public String[] run();
}
/** Common interface for all training classes */
public abstract class TrainingClass {
private Random mRandGen = new Random();
public ArrayList<Exercise> mExerciseTypes = new ArrayList<Exercise>();
/** Run a random exercise */
public String[] runRandomExercise() {
int i = mRandGen.nextInt(mExerciseTypes.size());
return mExerciseTypes.get(i).run();
}
}
/*Specific training class*/
public class MatheMagic extends TrainingClass {
public MatheMagic() {
class SomeExercise implements Exercise {
public String[] run() {
String[] mRes = new String[2];
mRes[0] = "Question type 1";
mRes[1] = "Answer type 1";
return mRes;
}
}
class SomeOtherExercise implements Exercise {
public String[] run() {
String[] mRes = new String[2];
mRes[0] = "Question type 2";
mRes[1] = "Answer type 2";
return mRes;
}
}
SomeExercise mN = new SomeExercise();
SomeOtherExercise mS = new SomeOtherExercise();
mExerciseTypes.add(mN);
mExerciseTypes.add(mS);
}
}
Easy solution is to create an interface with the common method and have all your classes extend it.
Create a collection or array of that type instead of Object; you can simply iterate through or randomly select and call the method you want.
It feels like a Command pattern from GoF to me.
public interface Exercise {
void execute();
}
Now your classes do this:
public class MatheMagic implements Execise {
public void execute() {
// special logic here.
}
}
Then you can do this:
int numExercises = 1;
Exercise [] exercises = new Exercise[numExercises];
exercises[0] = new MatheMagic();
for (Exercise exercise : exercises) {
exercise.execute();
}
Yes, yes you can store all those Classes in an array and then call them at random. How? Create an interface and in all your classes derive from that interface. That way you can invoke based on interface, and not on implementation.

Categories