I would like to know what is the best pattern for precondition checks on a list from which I will need to pick the first item.
In words, I suppose the list should not be null and its size should be > 1.
I find Guava’s checkPositionIndex not helpful in this respect. On the contrary, I find it counter-intuitive, see the example below which bombs on an empty list because I use checkPositionIndex rather than checkArgument, as outlined after the guard which does not trigger.
It seems like checking position 0 is not sufficient to validate the argument even if I .get(0) from it?
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndex;
import java.util.List;
import com.google.common.collect.Lists;
public class HowShouldIUseCheckPositionIndex {
private static class ThingAMajig {
private String description;
private ThingAMajig(String description) {
this.description = description;
}
@Override
public String toString() {
return description;
}
}
private static void goByFirstItemOfTheseAMajigs(List<ThingAMajig> things) {
checkNotNull(things);
// Check whether getting the first item is fine
checkPositionIndex(0, things.size()); // Looks intuitive but...
System.out.println(things.get(0)); // Finally, help the economy!
checkArgument(things.size() > 0); // This would have worked :(
}
public static void main(String[] args) {
List<ThingAMajig> fullList =
Lists.newArrayList(new ThingAMajig(
"that thingy for the furnace I have been holding off buying"));
List<ThingAMajig> emptyList = Lists.newLinkedList();
goByFirstItemOfTheseAMajigs(fullList);
// goByFirstItemOfTheseAMajigs(emptyList); // This *bombs*
}
}
You should use
checkElementIndex()instead.checkPositionIndex()ensures that the given position is a valid position to insert new element to (i.e. you can doadd(0, obj)on empty list), not a valid index to get an element from.