Avoid unnecessary restrictions
You should always try to declare your variables with the least unnecessary restriction; often that means to an interface like Queue or Collection. This allows you to more easily change your implementation. I will use two classes from the collections framework as my example but the principle is general.
Imagine the following objective:
I need 2 collections that can have objects added to it. And I also need to be able to find which objects are in both collections. So in other words I need the following methods
Collection#add
Collection#retainAll
These are both within Collection so any collection will do. Collection is an interface so I need to choose a concrete implementation. I choose ArrayList, on a whim. My code is the following:
public static void main(String[] args){
Collection<Integer> a=new ArrayList<>();
Collection<Integer> b=new ArrayList<>();
initialise(a);
initialise(b);
testRetain(a,b);
}
public static void initialise(Collection<Integer> collection){
Random rnd=new Random();
for(int i=0;i<1000;i++){
collection.add(rnd.nextInt());
}
}
public static void testRetain(Collection<Integer> collection1, Collection<Integer> collection2){
collection1.removeAll(collection2);
}
This code works fine and does exactly what I asked it to do. However; in profiling I find that it is a bottleneck. So I test out different implentations of the Collection class and profile the results.
As you can see, for the retainAll operation the HashSet turned out to be much better. So I can change my implementation by changing just new ArrayList<>();
to new HashSet<>();
in one place. No need to change every other method I've used to HashSet
as well because they don't care, as long as they get some sort of Collection
they are happy
public static void main(String[] args){
Collection<Integer> a=new HashSet<>();
Collection<Integer> b=new HashSet<>();
initialise(a); //<--no need to alter this method
initialise(b);
testRetain(a,b); //<--no need to alter this method
}
Well that was easy. Now imagine a much larger application with dozens of methods; all of which could be hardcoded to use ArrayList
even though they didn't need to, all of which you would now need to manually alter.