Removing Null Exercise
Start with code in this starter code project for IntelliJ.
Download the starter code and then using the Null Object pattern and Optional, remove as many mentions of null from the code as possible.
Use of Records
The sample code creates a couple classes using record instead of class. In Java, a record might look like:
public record Song(String title, String artist, int lengthInS) {
}
Notice how it looks like a class but has some variables declared in brackets after the name of the record. These are the private fields of the record.
A record is immutable and creates a number of things for you automatically:
- All fields are private final
- It creates well-named getters for each field.
- It overrides the
equals()andhashcode()functions.
Since all fields are final, there are no setters. Records cannot use inheritance. You can add any extra methods you like to the record to expand its behaviour if you need to; however, you cannot add any instance data inside the record, you must list all the instance data in the bracketed list after the record name.
The above record would include the functionality of the following class:
public class Song {
private final String title;
private final String artist;
private final int lengthInS;
public Song(String title, String artist, int lengthInS) {
this.title = title;
this.artist = artist;
this.lengthInS = lengthInS;
}
public String getTitle() {
return title;
}
public String getArtist() {
return artist;
}
public int getLengthInS() {
return lengthInS;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Song song = (Song) o;
return lengthInS == song.lengthInS
&& Objects.equals(title, song.title)
&& Objects.equals(artist, song.artist);
}
@Override
public int hashCode() {
return Objects.hash(title, artist, lengthInS);
}
}
Using record is a good idea when a class is going to store data and can be immutable.
Step 1: Refactor Election
Review the code in the election package. It tracks which political candidates are running in a specific riding during an election. It uses a lot of null checks to allow for:
getElectedCandidate()to not return a winner.- allow a
Candidateto not have anyParty.
Refactor the code to remove as many occurrences of null as you can. Consider both Optional and Null Object. Hint: which one is better for a function which might return an object, or return null?
As an extra (small) step, make a Party print its name using toString()
Step 2: Refactor SongPlayer
This package contains code that simulates part of a music player. The Song class stores information about an artist, title, and length. Player uses a PlaybackHardware object to simulate playing a Song. However, the Player must work without a Song or a PlaybackHardware object, and so at the moment there are a lot of null checks.
Change the code to use the Null Object pattern so that Player does not contain any null checks.
Submission
This exercise is not for marks: nothing need be submitted.