Содержит ли AllAll () и retainAll () в интерфейсе адреса коллекции Collection?
-
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) являются разумными:
<Ол>Javadocs для AbstractCollection подтверждают, что он использует # 2:
Эта реализация повторяет это сбор, проверка каждого элемента возвращается итератором в свою очередь посмотреть, если он содержится в указанном коллекция. Если это не так сдержано, он удален из этой коллекции с метод удаления итератора
Несмотря на то, что этого нет в моем чтении контракта с оригинальным интерфейсом Collection, я не обязательно буду считать, что поведение Collection в целом такое.
Возможно, вам следует подумать о том, чтобы отправить предлагаемые обновления в JavaDoc, как только вы закончите.
Что касается «почему интерфейс Collection остался таким неоднозначным» - я серьезно сомневаюсь, что это было сделано намеренно - вероятно, просто тем, что не было уделено должное внимание при написании этой части API.
Другие советы
Я не думаю, что Collection определяет это так или иначе, но это просто стало своего рода соглашением следовать поведению AbstractCollection, например google-collection do: смотрите их документация по Multiset (Multiset - это то, что они называют Bag)