Let’s say I have a class which, internally, stores a List of data:
import java.util.List;
public class Wrapper
{
private List<Integer> list;
public Wrapper(List<Integer> list)
{
this.list = list;
}
public Integer get(int index) { return list.get(index); }
}
For the sake of this example, pretend it’s a useful and necessary abstraction. Now, here’s my concern: As a programmer who knows the underlying implementation of this class, should I be specific about which type of List I ask for in the constructor? To demonstrate, I’ve made this test:
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
public class Main
{
public static void main(String[] args)
{
long start;
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new LinkedList<Integer>();
Wrapper wrapper1, wrapper2;
for(int i = 0; i < 1000000; i++)
{
list1.add(i);
list2.add(i);
}
wrapper1 = new Wrapper(list1);
wrapper2 = new Wrapper(list2);
start = System.currentTimeMillis();
wrapper1.get(500000);
System.out.println(System.currentTimeMillis() - start);
start = System.currentTimeMillis();
wrapper2.get(500000);
System.out.println(System.currentTimeMillis() - start);
}
}
As you most likely know, randomly accessing an element takes a bit more time with a linked list as opposed to an array. So, going back to the Wrapper constructor, should I be general and allow for any type of List, or should I specify that the user pass an ArrayList to ensure the best possible performance? While in this example, it may be easy for the user to guess as to what the underlying implementation of the method get is, you could imagine that this was something more complex. Thanks in advance!
The whole point of interfaces is to allow for agnosticism about the underlying implementation. The very use of the List type as opposed to LinkedList or ArrayList is to allow general operations without having to worry about this kind of problem. As long as your code can be written without having to rely upon methods not exposed by List you don’t need to worry.
It is likely a user of this class is writing code that has other requirements on the type of list they use, they might be appending lots into the middle of the list for instance where a LinkedList excels. As such you should accept the most generic type possible and assume the user has a good reason for using that type.
This isn’t however to stop you perhaps including a javadoc comment that the use of an ArrayList might be better if there is no difference in any other use of the application.