title: Problems with Collections.sort in Java 8
body: <pre class="lang-java prettyprint-override"><code> @Entity
   @NamedQueries({
     @NamedQuery(
       name = "FolderNode.findByName",
       query = "SELECT f FROM FolderNode f WHERE f.name = :name AND f.parentNode = :parentNode"),
     @NamedQuery(
       name = "FolderNode.findRootNodeByName",
       query = "SELECT f FROM FolderNode f WHERE f.name = :name AND f.parentNode is null")
   })
   public class FolderNode extends InstructorTreeNode {
     public FolderNode() {
       super();
     }
  
     public FolderNode(String name) {
       this();
       setName(name);
     }
  
     public FolderNode(int sortOrder, String name) {
       this(name);
       this.sortOrder = sortOrder;
     }
  
     public FolderNode(int sortOrder, String name, EmployeeState status) {
       this(sortOrder, name);
       this.status = status;
     }
  
     public static FolderNode addWaitingListNode(String name) {
       EntityManager em = getDao().getEntityManager();
       em.getTransaction().begin();
       FolderNode waitingListNode = getWaitingListFolder();
       FolderNode folderNode = new FolderNode(0, name);
       waitingListNode.addChild(folderNode);
       em.merge(waitingListNode);
       em.getTransaction().commit();
       em.close();
       return folderNode;
     }
  
     public static void addWaitingListStudent(String waitingList, Student s) {
       EntityManager em = FolderNode.getDao().getEntityManager();
       em.getTransaction().begin();
       FolderNode waitingListsNode = getWaitingListFolder();
       FolderNode waitingListNode = getDao().findFolderNodeByName(waitingListsNode, waitingList);
       waitingListNode.addChild(new EmployeeLeaf(s.getInmate()));
       em.merge(waitingListNode);
       em.getTransaction().commit();
       em.close();
     }
  
     public static FolderNode getAMClassFolder() {
       return getDao().findFolderNodeByName(getStudentsFolder(), "AM Class");
     }
  
     public static FolderNode getAttendanceFolder() {
       return getDao().findFolderNodeByName(getRootFolder(), "Employee Attendance");
     }
  
     public static FolderNode getFormerParaprosFolder() {
       return getDao().findFolderNodeByName(getParaprosFolder(), "Former");
     }
  
     public static FolderNode getFormerStudentsFolder() {
       return getDao().findFolderNodeByName(getStudentsFolder(), "Former");
     }
  
     public static FolderNode getPMClassFolder() {
       return getDao().findFolderNodeByName(getStudentsFolder(), "PM Class");
     }
  
     public static FolderNode getParaprosFolder() {
       return getDao().findFolderNodeByName(getRootFolder(), "Parapros");
     }
  
     public static FolderNode getPendingStudentsFolder() {
       return getDao().findFolderNodeByName(getRootFolder(), "Pending Students");
     }
  
     public static FolderNode getRootFolder() {
       return getDao().findFolderNodeByName(null, EducationPreferences.getInstructor().getInstructorName());
     }
  
     public static FolderNode getStudentsFolder() {
       return getDao().findFolderNodeByName(getRootFolder(), "Students");
     }
  
     public static FolderNode getWaitingListFolder(String name) {
       FolderNode waitingListsNode = getWaitingListFolder();
       return getDao().findFolderNodeByName(waitingListsNode, name);
     }
  
     public static FolderNode getWaitingListFolder() {
       return getDao().findFolderNodeByName(getRootFolder(), "Waiting List");
     }
  
     public static void setClassFolder(Student aStudent, EntityManager entityManager) {
       EntityManager em = entityManager;
       if (entityManager == null) {
         em = FolderNode.getDao().getEntityManager();
         em.getTransaction().begin();
       }
  
       EmployeeLeaf leaf = EmployeeLeaf.findActiveStudentLeaf(aStudent);
       FolderNode node = aStudent.getShift() == Shift.AM ? getAMClassFolder() : getPMClassFolder();
       leaf.setParentNode(node);
       em.merge(leaf);
       GlobalEntityMethods.updateHistory(leaf);
       if (entityManager == null) {
         em.getTransaction().commit();
         em.close();
       }
     }
  
     public static void transferWaitingListStudent(String currentFolder, String toFolder, Student student) {
       EntityManager em = FolderNode.getDao().getEntityManager();
       em.getTransaction().begin();
       FolderNode waitingListsNode = getWaitingListFolder();
       FolderNode currentWaitingListNode = getDao().findFolderNodeByName(waitingListsNode, currentFolder);
       EmployeeLeaf employeeLeaf = EmployeeLeaf.getDao().findWaitingListLeafByInmate(student.getInmate());
       currentWaitingListNode.removeChild(employeeLeaf);
       FolderNode toWaitingListNode = getDao().findFolderNodeByName(waitingListsNode, toFolder);
       toWaitingListNode.addChild(employeeLeaf);
       em.merge(currentWaitingListNode);
       em.merge(toWaitingListNode);
       em.getTransaction().commit();
       em.close();
     }
  
     public void addChild(InstructorTreeNode node) {
       childNodes.add(node);
       node.setParentNode(this);
     }
  
     public List&lt;InstructorTreeNode&gt; getChildNodes() {
       Collections.sort(childNodes);
       return childNodes;
     }
  
     @Override
     public Set&lt;Inmate&gt; getInmates() {
       Set&lt;Inmate&gt; inmateSet = new HashSet&lt;&gt; (50);
       for (InstructorTreeNode node: getChildNodes()) {
         inmateSet.addAll(node.getInmates());
       }
       return inmateSet;
     }
  
     public int getSortOrder() {
       return sortOrder;
     }
  
     public EmployeeState getStatus() {
       return status;
     }
  
     @Override
     public List&lt;InstructorTreeNode&gt; getTree() {
       List &lt;InstructorTreeNode&gt; result = new ArrayList&lt;&gt; (25);
       for (InstructorTreeNode childNode: getChildNodes()) {
         if (childNode instanceof FolderNode) {
           result.add(childNode);
         }
         result.addAll(childNode.getTree());
       }
       return result;
     }
  
     @Override
     public JPanel getView(EmployeeViewController controller) {
       if ("Employee Attendance".equals(getName())) {
         return new AttendanceView();
       } else if ("Waiting List".equals(getName())) {
         return new AllWaitingListsPanel(controller);
       } else if (getParentNode().getName().equals("Waiting List")) {
         return new WaitingListPanel(controller);
       } else if ("Pending Students".equals(getName())) {
         return new PendingStudentsPanel(controller);
       } else if ("Students".equals(getName())) {
         return new AllStudentsPanel(controller);
       } else if ("AM Class".equals(getName())) {
         return new AllStudentsPanel(controller, Shift.AM);
       } else if ("PM Class".equals(getName())) {
         return new AllStudentsPanel(controller, Shift.PM);
       } else if (getParentNode().getName().equals("Students") &amp;&amp; "Former".equals(getName())) {
         return new FormerStudentsPanel(controller);
       } else if ("Parapros".equals(getName())) {
         return new AllParaprosPanel(controller);
       } else if (getParentNode().getName().equals("Parapros") &amp;&amp; "Former".equals(getName())) {
         return new FormerParaprosPanel(controller);
       }
       throw new UnsupportedOperationException("unknown folder");
     }
  
     public void removeChild(InstructorTreeNode node) {
       childNodes.remove(node);
       node.setParentNode(null);
     }
  
     public void removeEmployeeLeaf(Inmate inmate) {
       for (InstructorTreeNode node: childNodes) {
         if (node instanceof EmployeeLeaf) {
           EmployeeLeaf employeeLeaf = (EmployeeLeaf) node;
           if (employeeLeaf.getInmate().equals(inmate)) {
             childNodes.remove(employeeLeaf);
             break;
           }
         }
       }
     }
  
     public void setChildNodes(List&lt;InstructorTreeNode&gt; childNodes) {
       this.childNodes = childNodes;
     }
  
     public void setSortOrder(int sortOrder) {
       this.sortOrder = sortOrder;
     }
  
     public void setStatus(EmployeeState status) {
       this.status = status;
     }
  
     @OneToMany(mappedBy = "parentNode", cascade = CascadeType.ALL, orphanRemoval = true)
     private List&lt;InstructorTreeNode&gt; childNodes;
  
     private int sortOrder;
  
     @Enumerated(EnumType.STRING)
     private EmployeeState status;
   }
  
  
   @Entity
   @Table(catalog = "education", name = "instructortreenode", uniqueConstraints = @UniqueConstraint(columnNames = {
     "PARENTNODE_ID", "NAME"
   }))
   @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
   public abstract class InstructorTreeNode implements Comparable&lt;InstructorTreeNode&gt; {
     public InstructorTreeNode() {
       super();
     }
  
     public static InstructorTreeNodeDAO getDao() {
       return dao;
     }
  
     @Override
     public int compareTo(InstructorTreeNode o) {
       if (o instanceof FolderNode &amp;&amp; this instanceof FolderNode) {
         FolderNode thisFolder = (FolderNode) this;
         FolderNode otherFolder = (FolderNode) o;
         if (thisFolder.getSortOrder() != otherFolder.getSortOrder()) {
           return thisFolder.getSortOrder() - otherFolder.getSortOrder();
         } else {
           return thisFolder.getName().compareToIgnoreCase(otherFolder.getName());
         }
       } else if (o instanceof EmployeeLeaf &amp;&amp; this instanceof EmployeeLeaf) {
         return getName().compareToIgnoreCase(((InstructorTreeNode) o).getName());
       }
       return (o instanceof FolderNode) ? -1 : +1;
     }
  
     public int getCount() {
       return getTree().size();
     }
  
     public abstract Set&lt;Inmate&gt; getInmates();
  
     public String getName() {
       return name;
     }
  
     public FolderNode getParentNode() {
       return parentNode;
     }
  
     public abstract List&lt;InstructorTreeNode&gt; getTree();
  
     public abstract JPanel getView(EmployeeViewController theController);
  
     public void setName(String name) {
       this.name = name;
     }
  
     public void setParentNode(FolderNode parentNode) {
       this.parentNode = parentNode;
     }
  
     @Override
     public String toString() {
       return name;
     }
  
     private static final InstructorTreeNodeDAO dao = new InstructorTreeNodeDAO();
     private String name;
  
     @ManyToOne
     private FolderNode parentNode;
   }
  </code></pre>
  
  <p>Here is my problem:
  The Collections.sort line works just fine in Java 8u5 and before, but
  in Java 8u20 they seem to have changed the code for Collections.sort
  and it no longer uses anything but the natural order, even if you specify
  a Comparator.</p>
  
  <p>Should I be using another method to sort my list, or is there an error in 
  Collections.sort.</p>
  
  <p>Any help would be much appreciated, as this is driving me crazy.</p>
  
  <p>I forgot to say that this code does not use a specified comparator, but according to the documentation it is supposed to use the CompareTo, if your class implements Comparable, which is what I am using.
  I tried also specifying a comparator, but it did not work either.</p>