Содержит ли AllAll () и retainAll () в интерфейсе адреса коллекции Collection?

StackOverflow https://stackoverflow.com/questions/816379

  •  03-07-2019
  •  | 
  •  

Вопрос

В JavaвеcтвыеВсе и retainAll в классе AbstractCollection прямо заявляют, что количество элементов не учитывается, поэтому, другими словами, не имеет значения, сколько экземпляров значения находится на каждой стороне. Поскольку все коллекции Java в стандартной библиотеке расширяют AbstractCollection, предполагается, что все они работают одинаково.

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

Например, Bag в apache-collection явно заявляет, что уважает количество элементов, и заявляет, что нарушает контракт версии из Collection (хотя на самом деле это не так).

Итак, какова семантика этих операций в Collection, а не в AbstractCollection?

Редактировать: То, кто интересуется, почему мне было бы все равно, это потому, что как часть моей докторской диссертации. В своей работе я продемонстрировал, что разработчики не ожидают нарушения соответствия в Apache, но я пытаюсь понять, почему интерфейс Collection остался таким неоднозначным.

Это было полезно?

Решение

Javadocs для содержит все (в коллекции) говорят:

  

Возвращает: true, если эта коллекция   содержит все элементы в   указанная коллекция

и для retainAll (в коллекции):

  

Сохраняет только элементы в этом   Коллекция, которая содержится в   указанная коллекция (необязательно   операция). Другими словами, удаляет   из этой коллекции все его   элементы, которые не содержатся в   указанная коллекция.

Я прочитал контракт containsAll, чтобы означать, что вызов a.containsAll (b) вернет true, если и только если, вызов a.contains (bElem) для каждого элемента bElem в b вернет true. Я также взял бы это, чтобы подразумевать, что a.containsAll (someEmptyCollection) также вернул бы true. Когда вы заявляете, что javadocs для AbstractCollection более явно заявляют это:

  

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

Я согласен, что контакт для Collection for содержит все должно быть более явным, чтобы избежать путаницы. (И что чтение javadocs для AbstractCollection НЕ должно было быть необходимым для подтверждения понимания Коллекции)

Я бы не сделал предположение относительно количества дублирующихся элементов после вызова retainAll. Указанный контракт в Коллекции (по моим сведениям) никоим образом не подразумевает, как будут обрабатываться дубликаты в любой коллекции. Основываясь на моем чтении retainAll в коллекции, все возможные результаты a.retainAll (b) являются разумными:

<Ол>
  • результат содержит 1 каждого элемента, который имеет хотя бы одну копию в a и b
  • результат содержит каждый элемент (включая дубликаты), который был в a, кроме тех, которые не находятся в b
  • или даже, результат содержит где-то между 1 и количеством копий, найденных в a каждого элемента в a, кроме тех, которые не в b. Я ожидал, что № 1 или № 2, но я бы предположил, что любой из трех будет законным на основе контракта.
  • Javadocs для AbstractCollection подтверждают, что он использует # 2:

      

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

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

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

    Что касается «почему интерфейс Collection остался таким неоднозначным» - я серьезно сомневаюсь, что это было сделано намеренно - вероятно, просто тем, что не было уделено должное внимание при написании этой части API.

    Другие советы

    Я не думаю, что Collection определяет это так или иначе, но это просто стало своего рода соглашением следовать поведению AbstractCollection, например google-collection do: смотрите их документация по Multiset (Multiset - это то, что они называют Bag)

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top