Note: This question is a very specific case of "Why does the Collections class contain standalone (static) methods, instead of them being added to the List interface?" - one could even consider is as a duplicate. Beyond that, arguing about the reasoning behind the decision for each individual method is reading tea leaves, and nobody can tell "the reason" for the design decision for the particular case of the reverse
method (until, maybe Josh Bloch posts an answer here). Interestingly, this is a point that is not covered in the Java Collections API Design FAQ...
Some of the other answers seem convincing at the first glance, but raise other questions. Particularly, some of them don't give a reason for the design decision at all. Even if there are other ways to emulate the behavior of a certain method, or when a method is not used "99.9% of all time", it can still make sense to include it in the interface.
Looking at the List
interface, you will notice that you can basically implement all methods based on two others:
T get(int index)
int size()
(For a mutable list, you also need set
). These are exactly the ones that are still abstract in AbstractList
. So all other methods are rather "convenience" methods that can be implemented canonically, based on these two methods. In this regard, I think that the answer Sam Estep contains an important point: One could argue to implement dozens of other methods. And there would certainly be good reasons to do so. Having a look at the actual implementation of Collections#reverse(List)
:
public static void reverse(List<?> list) {
int size = list.size();
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
ListIterator fwd = list.listIterator();
ListIterator rev = list.listIterator(size);
for (int i=0, mid=list.size()>>1; i<mid; i++) {
Object tmp = fwd.next();
fwd.set(rev.previous());
rev.set(tmp);
}
}
}
What is this REVERSE_THRESHOLD
and RandomAccess
thing there? Seriously, if I felt the necessity to introduce a tagging interface like RandomAccess
, I would strongly question my design. Whenever you have a method like
void doSomethingWith(Type x) {
if (x instanceof Special) doSomethingSpecial((Special)x);
else doSomethingNormal(x);
}
then this is a strong sign that this should actually be a polymorphic method, which should be implemented accordingly for the Special
type.
So yes, it have been justified to pull the reverse
method into the interface, to allow a polymorphic implementation. The same applies to fill
rotate
, shuffle
, swap
, sort
and others. Similarly, one could have introduced a static method like
Collections.containsAll(containing, others);
that offers what is now done with the Collection#containsAll
method. But in general: The designers chose a particular set of methods that they found suitable. One of the reasonings behind leaving out certain methods may be given by one of the bottom lines of the talk about "How to Design a Good API & Why it Matters" by Joshua Bloch, one of the core designers of the Java Collections API:
When in doubt, leave it out
Interestingly, of all the methods for which a polymorphic implementation (via a method in the List
interface) could have been reasonable, one actually found its way into the interface, using a Java 8 default
method:List#sort()
. Maybe others, like reverse
, will be added later...
Collection.reverse
was introduced at the same time thanList
itself (JDK 1.2) it was most likely intention of the designers to not include it in theList
interface but rather provide a helper method only. – Nosedivefill
,shuffle
and other static methods...) – Magill