Java8 Collections.sort (sometimes) does not sort JPA returned lists

Well, this is a perfect didactic play telling you why programmers shouldn’t extend classes not designed for being subclassed. Books like “Effective Java” tell you why: the attempt to intercept every method to alter its behavior will fail when the superclass evolves.

Here, IndirectList extends Vector and overrides almost all methods to modify its behavior, a clear anti-pattern. Now, with Java 8 the base class has evolved.

Since Java 8, interfaces can have default methods and so methods like sort were added which have the advantage that, unlike Collections.sort, implementations can override the method and provide an implementation more suitable to the particular interface implementation. Vector does this, for two reasons: now the contract that all methods are synchronized expands to sorting as well and the optimized implementation can pass its internal array to the Arrays.sort method skipping the copying operation known from previous implementations (ArrayList does the same).

To get this benefit immediately even for existing code, Collections.sort has been retrofitted. It delegates to List.sort which will by default delegate to another method implementing the old behavior of copying via toArray and using TimSort. But if a List implementation overrides List.sort it will affect the behavior of Collections.sort as well.

                  interface method              using internal
                  List.sort                     array w/o copying
Collections.sort ─────────────────> Vector.sort ─────────────────> Arrays.sort

Leave a Comment