Get vs. Find
Get vs. Find is a simple code naming convention for increasing code readability while decreasing code
complexity, the amount of code written and potential defects. When fetching data, from something such as a
list, map, set, or even permanent storage, the developer will know when the data being fetch should
always be found (i.e.gets
) or not (i.e. finds
).
Get
methods raise an exception if the data is not found, these methods will never return null.
Find
methods will return null if the data is not found, these methods will not raise an
exception.
When calling a get
method, there is no need to handle a null condition, reducing the need for
extra logic.
Data Sorting Example
Let's take the following example where a list of addresses need to be sorted by the owner's name.
// Address data class to be sorted
class Address
{
PersonID personID;
String street;
String city;
StateID stateID;
}
// Person data class to aide in sorting
class Person
{
PersonID personID;
String firstName;
String lastName;
}
We can assume Person.personID
is a unique key and will always exist. And
Address.personID
will always refer to a valid Person.personID
.
To help with the sorting, we create a helper PersonMap
class with our get
and find
methods, named getByID
and findByID
:
class PersonMap extends HashMap<PersonID, Person>
{
// never returns null, raises an exception
public Person getByID(PersonID personID)
{
Person person = super.get(personID);
if (person != null)
return person;
throw new IllegalArgumentException("Bad PersonID(" + personID + ")");
}
// may return null
public Person findByID(PersonID personID)
{
return super.get(personID);
}
}
This class helps with creating the sorting (Comparator
) class we need:
class AddressSorter implements Comparator<Address>
{
PersonMap personMap;
public AddressSorter(PersonMap personMap)
{
this.personMap = personMap;
}
@Override
public int compare(Address o1, Address o2)
{
Person person1 = personMap.getByID(o1.personID);
Person person2 = personMap.getByID(o2.personID);
int compare = person1.lastName.compareTo(person2.lastName);
if (compare != 0)
return compare;
compare = person1.firstName.compareTo(person2.firstName);
if (compare != 0)
return compare;
return person1.personID.compareTo(person2.personID);
}
}
The resulting code is cleaner and removes the need to check for null when calling getByID()
,
knowing that null will never be returned (i.e. in practice of course unless there is a defect elsewhere).
The Alternative
If we did not take this approach, our code would need to confirm person1
and
person2
are not null. We would need code such as:
if ((person1 == null) || (person2 == null))
throw new IllegalArgumentException("Bad o1.personID or o2.personID");
We would need these null pointer checks in other similar code, whenever Person
look-ups are
performed. Having our PersonMap
with its get
and find
methods removes
a lot of similar, repetitive code.
Other Benefits
There are more benefits to get
methods. Let's say there is a defect elsewhere and
getByID()
does not find it's personID
parameter as expected. Our
getByID()
raises an intelligent exception, noting the bad personID
value (as well
as providing a consistent error message, regardless of the calling code). If the standard Java Map.get()
were used, the code would just result in a null pointer.
Get or Find
Get
methods should only be used when the criteria is known to always exist. Having a unique key
is a good indicator that get
methods can be used.
But be careful, the situation matters. There often are cases where provided values are expected to be unique
keys but may not have been validated. Take for example code that validates user inputted data. Email
addresses are unique keys, once they are validated. Consider an email address entered by a user. In this
situation, a find
method should be used to validate the email address. Using a get
method on an invalid email address would raise an exception. Instead, a find
method should be
used and a null result handled.
Conclusion
The Get vs. Find approach will go a long way towards helping to build better, more stable code. And will result in less, better tested code.