Когда использовать Сопоставимый и Компаратор

У меня есть список объектов, которые я должен отсортировать на поле, сказать Счет. Не много думая я записал новый класс, который реализует Компаратор, который делает задачу, и это работает.

Теперь оглядываясь назад на это, я задаюсь вопросом, должен ли я иметь, вместо этого имеют мою реализацию класса, Сопоставимую вместо того, чтобы создать новый класс, который реализует Компаратор. Счет является единственным полем, на котором будут заказаны объекты.

  1. Что я сделал приемлемый как практика?

  2. Правильный подход, "Сначала имеют Сопоставимую реализацию класса (для естественного упорядочивания) и если альтернативное полевое сравнение требуется, то создайте новый класс, который реализует Компаратор"?

  3. Если (2) выше верно, то это означает, что нужно реализовать Компаратор только после того, как у них есть Сопоставимая реализация класса? (Принятие я владею исходным классом).

106
задан Alex.K. 9 December 2014 в 12:48
поделиться

6 ответов

Я бы сказал, что объект должен реализовать Comparable, если это очевидный естественный способ сортировки класса, и любой, кому понадобится сортировать класс, обычно захочет сделать это таким образом.

Если же сортировка является необычным использованием класса, или сортировка имеет смысл только для конкретного случая использования, то лучшим вариантом будет Comparator.

Другими словами, учитывая название класса, ясно ли, как будет сортировать компаратор, или вам придется прибегнуть к чтению javadoc? Если это последнее, то, скорее всего, каждый будущий случай сортировки потребует использования компаратора, и тогда реализация comparable может замедлить работу пользователей класса, а не ускорить ее.

78
ответ дан 24 November 2019 в 03:45
поделиться

Используйте Сопоставимый :

  • , если объект находится под вашим контролем.
  • , если поведение сравнения является основным поведением сравнения.

Используйте Компаратор :

  • , если объект находится вне вашего контроля, и вы не можете заставить их реализовать Сопоставимый .
  • , если вы хотите сравнить поведение, отличное от поведения по умолчанию (которое указано в Comparable ) поведения.
57
ответ дан 24 November 2019 в 03:45
поделиться

Я бы сказал:

  • если сравнение интуитивно понятно, тогда обязательно реализуйте Comparable
  • , если неясно, интуитивно ли ваше сравнение, используйте компаратор, поскольку он более ясен и, следовательно, более понятен для бедняжек, которым приходится поддерживать код
  • , если возможно более одного интуитивного сравнения, я бы предпочел компаратор, возможно построить фабричным методом в сравниваемом классе.
  • если сравнение является специальным, используйте Comparator
8
ответ дан 24 November 2019 в 03:45
поделиться

Как сказал Матье в другом ответе, библиотека Boost.MultiIndex кажется правильным выбором для того, что вы хотите. Однако эту библиотеку может быть немного трудно использовать в начале, особенно если у вас нет большого опыта работы с C++. Вот как вы могли бы использовать библиотеку для решения точной проблемы в коде вашего вопроса:

struct person {
    std::string name;
    int id;
    person(std::string const & name, int id) 
    : name(name), id(id) { 
    }
};

int main() {

    using namespace::boost::multi_index;
    using namespace std;

    // define a multi_index_container with a list-like index and an ordered index
    typedef multi_index_container<
      person,        // The type of the elements stored
      indexed_by<    // The indices that our container will support
        sequenced<>,                           // list-like index
        ordered_unique<member<person, string, 
                              &person::name> > // map-like index (sorted by name)
      >
    > person_container;

    // Create our container and add some people
    person_container persons;
    persons.push_back(person("B", 123));
    persons.push_back(person("C", 224));
    persons.push_back(person("A", 321));

    // Typedefs for the sequence index and the ordered index
    enum { Seq, Ord };
    typedef person_container::nth_index<Seq>::type persons_seq_index;
    typedef person_container::nth_index<Ord>::type persons_ord_index;

    // Let's test the sequence index
    persons_seq_index & seq_index = persons.get<Seq>();
    for(persons_seq_index::iterator it = seq_index.begin(), 
                                    e = seq_index.end(); it != e; ++it)
        cout << it->name << ":"<< it->id << endl;
    cout << "\n";

    // And now the ordered index
    persons_ord_index & ord_index = persons.get<Ord>();
    for(persons_ord_index::iterator it = ord_index.begin(), 
                                    e = ord_index.end(); it != e; ++it)
        cout << it->name << ":"<< it->id << endl;
    cout << "\n";

    // Thanks to the ordered index we have fast lookup by name:
    std::cout << "The id of B is: " << ord_index.find("B")->id << "\n";
}

Что приводит к следующим выводам:

B:123
C:224
A:321

A:321
B:123
C:224

The id of B is: 123
-121--1547481-

Я бы использовал столбец IDENTITY, а если нет, то использовать System.Guid.NewGuid () для создания GUID для вас.

-121--3430372-
  • Если в момент написания класса у вас есть только один пример использования сортировки Использовать Сопоставимо.
  • Только при наличии нескольких стратегия сортировки реализовать Компаратор.
4
ответ дан 24 November 2019 в 03:45
поделиться

Здесь был аналогичный вопрос: Когда класс должен быть Comparable и / или Comparator?

Я бы сказал следующее: Реализуйте Comparable для чего-то вроде естественного упорядочения, например на основе внутреннего идентификатора

. Реализуйте компаратор, если у вас есть более сложный алгоритм сравнения, например несколько полей и так далее.

3
ответ дан 24 November 2019 в 03:45
поделиться

Используйте Comparable , если вы хотите определить стандартное (естественное) поведение упорядочивания рассматриваемого объекта, распространенной практикой является использование для этого технического или естественного (база данных?) идентификатора объекта.

Используйте Компаратор , если вы хотите определить внешнее управляемое поведение упорядочивания, это может переопределить поведение упорядочивания по умолчанию.

124
ответ дан 24 November 2019 в 03:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: