This implementation of GuestList is called strict (as opposed to the lazy implementation) because it enforces uniqueness eagerly: add calls isComing first and returns immediately if the guest is already present.
This implementation maintains the following data invariant: all non-null entries in data from 0 to count-1 are distinct.
Because we are in the same package as GuestArrayList, we have access to its package-private fields and know about how its methods work.
We also know that enforcing uniqueness changes nothing about the externally expected behaviour of the class.
As such, we can make our new class a subtype of GuestArrayList, and use inheritance to reuse existing code, changing only what needs to be changed:
public class GuestArrayUniqueList extends GuestArrayList {
// Invariant: all non-null values in data[0..count-1] are unique
@Override
public void add(String name) {
if(isComing(name)) {
return;
}
super.add(name);
}
public void remove(String name) {
int i = 0;
while(i<count) {
if(data[i] != null && data[i].equals(name)) {
data[i]=null;
return;
}
i = i +1;
}
}
}
The add method is overridden to the isComing check first. However, after this check, the code of the method is the same as before, and we can just call the superclass' implementation of that method instead of copying it into here.
Because the invariant guarantees at most one copy exists, remove can stop after finding the first match. Contrast with the lazy implementation, where remove must scan the entire array to null out all copies.
However, because this change to the code of remove is deep within the code of that method, we have to rewrite it fully, rather than calling the superclass' implementation.