In an ongoing work project, we have a Java class that models a patient with type 1 diabetes. Since a lot of the risk models that operate on the simulated patient are affected by various medications (antihypertensives, antithrombotics, lipid modifying medications, etc.), we have an ArrayList
on the patient that holds instances of a Medication
class (or any of its many subclasses) to represent which of these the patient is currently taking:
private List<Medication> riskAdjustingMedications;
This allows us to write things like the fairly English-sounding:
patient.getRiskAdjustingMedications().add(new AntiHypertensiveMedication());
(We actually opted to use the getter for the riskAdjustingMedications
ArrayList and the .add() method directly for the very reason that the code is extremely readable when written as above.)
But how can we write something that allows us to establish whether or not the ArrayList
already contains an instance of Medication itself or one of its subclasses? For now, we’re using a private method in the Patient class that accomplishes this as generally as possible:
private static <T, E extends T> E returnFirstInstanceOfClassInCollection(Class<E> theClass, Collection<T> arrayList) { for (T o : arrayList) { if (o != null && o.getClass() == theClass) { return theClass.cast(o); } } return null; }
So that’s a generic method with the type parameters T
and E
(where E
extends T
) that takes the class of E
(in our specific example, Medication.class
or any subclass) and a Collection
of type T
as arguments. If an instance of type Class
is found in the Collection
, the method returns the first instance, otherwise it returns null
.
In the Patient
class, we’ve then implemented a public convenience method to support querying for Medication or any of its subclasses:
public <T extends Medication> boolean isTaking(Class<T> medication) { return Patient.returnFirstInstanceOfClassInCollection(medication, this.riskAdjustingMedications) == null ? false : true; }
For maximum readability in our classes that are evaluating complication risk and patient physiology, we can then declare statics for the specific Medication or subclass types we’re using and write code like the following:
static final Class<AntiHypertensiveMedication> ANTI_HYPERTENSIVES = AntiHypertensiveMedication.class; if (patient.isTaking(ANTI_HYPERTENSIVES)) { patient.adjustSystolicBloodPressureBy(-5.0); }
Eminently readable.