Question: Is there a way to write one function that would account for the different data types? Would generics work and if so how do you do that in AnyLogic?
Background: I have three different agent types that inherit from a parent class.
"agentB", "agentC", & "agentD" that inherit / extend from "agentA". They all have the same variables "condition1" and "condition2".
Additionally, I created populations of the above agents (in main) using database tables for initialization.
"popB", "popC", and "popD"
I am using the findFirst() function to find the first object that meets the required conditions. In order to account for the different types I wrote 3 separate functions that are the same except for the types.
Code Examples:
Function for AgentB Type:
AgentB curAgent = null;
curAgent = findFirst(main.popB, p->p.condition1 == true && p.condition2 == true);
return curAgent;
Function for AgentC Type:
AgentC curAgent = null;
curAgent = findFirst(main.popC, p->p.condition1 == true && p.condition2 == true);
return curAgent;
Function for AgentD Type:
AgentD curAgent = null;
curAgent = findFirst(main.popD, p->p.condition1 == true && p.condition2 == true);
return curAgent;
CodePudding user response:
You said that They all have the same variables "condition1" and "condition2".
If that is true, then your solution is very simple.
import java.util.Collection;
import java.util.List;
public class SOQ_20220430
{
class AgentA
{
public final boolean condition1;
public final boolean condition2;
/** Potentially other fields. */
public AgentA(boolean condition1, boolean condition2)
{
this.condition1 = condition1;
this.condition2 = condition2;
}
public boolean bothTrue()
{
return condition1 && condition2;
}
public String toString()
{
return
this.getClass().getName()
"{ condition1 = " this.condition1
", condition2 = " this.condition2 "}";
}
/** Potentially other methods. */
}
class AgentB extends AgentA {
public AgentB(boolean c1, boolean c2) { super(c1, c2); }
}
class AgentC extends AgentA {
public AgentC(boolean c1, boolean c2) { super(c1, c2); }
}
class AgentD extends AgentA {
public AgentD(boolean c1, boolean c2) { super(c1, c2); }
}
public SOQ_20220430()
{
final List<AgentB> popB = List.of(new AgentB(false, false), new AgentB(true, true));
final List<AgentC> popC = List.of(new AgentC(false, false), new AgentC(true, true));
final List<AgentD> popD = List.of(new AgentD(false, false), new AgentD(true, true));
System.out.println(findFirst(popB));
System.out.println(findFirst(popC));
System.out.println(findFirst(popD));
}
public <T extends AgentA> T findFirst(Collection<T> popT)
{
for (T each : popT)
{
if (each.bothTrue())
{
return each;
}
}
throw new IllegalStateException("Couldn't find one!");
}
public static void main(String[] args)
{
new SOQ_20220430();
}
}
Since they all extend AgentA
, then any fields or functions in AgentA
become theirs to use as well. As a result, we can perform the check for them being true as long as we call the super constructor, as you can see in each of the child classes.
Then, all we need to do is accept as a parameter to findFirst any collection of elements that are all the same type and extend AgentA
.