У меня ошибка в логике реализации или неверна сама реализация? Пробовал заменить примитивы на Double и возвращать результат метода .compareTo - валидатор не согласен по тому же пункту. Пробовал сравнивать имена с учетом регистра. Проверял каждый этап сортировки, комментируя предыдущие - результаты верные для каждого случая. Пробовал переносить все сравнения в конец метода. Решено путем сравнения имен с учетом регистра. Логично же.
public static void sort(List<Stock> list) {
    Collections.sort(list, new Comparator<Stock>() {
        public int compare(Stock stock1, Stock stock2) {
            String name1 = (String) stock1.get("name");
            String name2 = (String) stock2.get("name");

            if (name1.compareToIgnoreCase(name2) != 0) return name1.compareToIgnoreCase(name2);


            Date date1 = (Date) stock1.get("date");
            date1.setSeconds(0);
            date1.setMinutes(0);
            date1.setHours(0);

            Date date2 = (Date) stock2.get("date");
            date2.setSeconds(0);
            date2.setMinutes(0);
            date2.setHours(0);

            if (date2.compareTo(date1) != 0) return date2.compareTo(date1);


            double profit1;
            double profit2;
            if (stock1.containsKey("change"))
                profit1 = (double) stock1.get("change");
            else
                profit1 = (double) stock1.get("last") - (double) stock1.get("open");

            if (stock2.containsKey("change"))
                profit2 = (double) stock2.get("change");
            else
                profit2 = (double) stock2.get("last") - (double) stock2.get("open");

            return Double.compare(profit2, profit1);
        }
    });
}