Сортировка потока Java с неполными критериями упорядочения.

Я пытаюсь создать метод, который сортирует список, делая:

private List<Processor> getByPriority(){                        
    return processors.stream().sorted( new ProcessorComparator() ).collect( Collectors.toList() );
}

Но я прочитал в Comprator javadoc, что сравнивает to должно быть отношением тотального упорядочивания. То есть никакие два компаратора не могут иметь одинаковый приоритет, если только они не равны. Это может быть не так.

Я пробовал этот простой компаратор:

public class ProcessorComparator implements Comparator<TTYMessageProcessor<?>>{

    @Override
    public int compare( Processor processor1 , Processor processor2 ) {         
        return processor1.getPriority() - processor2.getPriority();
    }       
} 

Конечно, я мог бы сделать процессор сопоставимым, но я хотел бы избежать модификаций всех процессоров. Нет ли способа отсортировать их потоками? В качестве альтернативы я мог бы написать свой собственный метод или создать более сложный компаратор, но я удивлен отсутствием более элегантного решения.


person borjab    schedule 20.04.2016    source источник
comment
если вас не волнует порядок процессоров с одинаковым приоритетом, это отличный компаратор, поскольку равенство в этом случае определяется как равенство приоритета процессора, а не самих процессоров   -  person BeyelerStudios    schedule 20.04.2016
comment
Согласно javadoc, это несовместимо с методом equals. Но я не совсем уверен в последствиях. Я просто хочу убедиться, что поток не считает его уже существующим и не удаляет. С другой стороны, я совсем не возражаю, если процессоры с одинаковым порядком сортируются случайным образом. Однажды Pc(p=2) появляется раньше Pb(p=2) и наоборот. Ваша фраза о равенстве приоритетов процессов и равенстве объектов была поучительной.   -  person borjab    schedule 20.04.2016
comment
Я бы хотел, чтобы вы использовали Java 8, это намного сложнее, чем нужно: используйте Comparator.comparingInt(Processor::getPriority).   -  person Louis Wasserman    schedule 20.04.2016


Ответы (1)


Чтение ссылки элементы исходного потока сохраняются:

Возвращает поток, состоящий из элементов этого потока, отсортированных в соответствии с предоставленным Компаратором.

Никакие элементы не будут вытеснены, удалены или дублированы. Одни и те же элементы выходят не в том виде, в каком они входят, только в другом порядке.

Изменить: документы также указывают для Comparator .сравнить

Как правило, но не обязательно, что (compare(x, y)==0) == (x.equals(y)). Вообще говоря, любой компаратор, нарушающий это условие, должен явно указывать на этот факт. Рекомендуемый язык: «Примечание: этот компаратор накладывает порядок, несовместимый с равными».

Это может привести к путанице в отношении equals при использовании в картах или наборах:

Следует проявлять осторожность при использовании компаратора, способного навязывать порядок, несовместимый с равными, для упорядочения отсортированного набора (или отсортированной карты). Предположим, что отсортированный набор (или отсортированная карта) с явным компаратором c используется с элементами (или ключами), взятыми из набора S. Если порядок, налагаемый c на S, несовместим с равными, отсортированный набор (или отсортированная карта) будет вести себя «странно». В частности, отсортированный набор (или отсортированная карта) будет нарушать общий контракт для набора (или карты), который определен в терминах равенства.

Путаница снимается, если вы думаете о Comparator как об абстракции пары ключ-значение: вы не ожидаете, что две пары будут равны, если их ключи равны. Это просто означает, что некоторые свойства этих значений (то есть их ключей) считаются одинаковыми. Если вы хотите, чтобы объект был Comparable в соответствии с equals, лучше всего реализовать интерфейс с одинаковым именем Сопоставимо.

person BeyelerStudios    schedule 20.04.2016
comment
@borjab то, что вы добавили, вообще не относится к сортировке списка. Для наборов и карт посмотрите на это так: компаратор абстрагирует концепцию наличия пары ключ-значение, где вы сортируете пары по их ключу, никогда не существует предположения, что пара равна другой, если их ключи сравниваются равными. На самом деле, в этом смысле я категорически не согласен с фактическим выбором формулировки документации Обычно это так..., это обычно не так, иначе вы бы реализовали Comparable.compareTo не внешний Comparator... - person BeyelerStudios; 20.04.2016