Collection-подобный интерфейс, наследующий от Collection - PullRequest
1 голос
/ 17 июня 2019

У меня есть интерфейс, похожий на коллекцию, который содержит большинство методов интерфейса Collection, но есть проблема, связанная с методами add и contains, которые я просто хочу унаследовать от Collection.

Элементы типа T в Collection реализуют метод copy и метод установки, который иногда требуется следующим образом:

  • Измените элемент перед тем, как вставить его через предоставленный сеттер
  • Создайте копию элемента, измените один или оба элемента с помощью предоставленного установщика и только затем вставьте их

Можно визуализировать это, думая о коллекции, которая принимает строковые аргументы, но если добавлена ​​конкретная строка foo, добавляется усеченная версия fo или fo плюс еще одна строка bar.

// Examples of the add() method internals
collection.add("foo"); // internally add("fo");
collection.add("foo"); // internally add("fo"); add("bar");

Проблема в том, что иногда вставляется более одного элемента, что само по себе хорошо для контракта метода из add, но изменение элемента перед вставкой несколько грязно. Если используется метод copy и элемент вставлен, он больше не будет contain оригинальным элементом.

Вопрос: Правильно ли будет расширить Collection, тем не менее, или большинство методов сбора данных переопределяется здесь?

Ответы [ 2 ]

2 голосов
/ 17 июня 2019

Ваш интерфейс не должен расширяться Collection, если он ведет себя так, как вы описали, поскольку он нарушает договор Collection add, который гласит:

Гарантирует, что эта коллекциясодержит указанный элемент

и

Если коллекция отказывается добавить определенный элемент по любой причине, кроме того, что она уже содержит элемент, она должна вызвать исключение (а не возвращать ложь).Это сохраняет инвариант, что коллекция всегда содержит указанный элемент после возврата этого вызова.

Если collection.add("foo"); фактически добавляет «fo», то контракт нарушается.

Если вашИнтерфейс расширяет Collection, пользователь вашего интерфейса может назначить экземпляр вашего интерфейса переменной Collection и ожидать, что он будет вести себя так, как описано в интерфейсе Collection.

1 голос
/ 17 июня 2019

Добавление к ответу @ Eran.

Из документов

If a collection refuses to add a particular element for any reason
other than that it already contains the element, it must throw
an exception (rather than returning false)

Не используйте метод add.Вместо этого вы можете расширить коллекцию и добавить новый метод, соответствующий вашему контракту.Что-то в строках

boolean addOrSplit(E e) {
    if(contains(e)) {
         //split e
         //addOrSplit(e - Part1);
         //addOrSplit(e - Part2);
    } else {
         add(e);
    }
}

Убедитесь, что вы обрабатываете условие окончания рекурсии и избегаете бесконечных циклов в этой реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...